basic docker login PoC
This commit is contained in:
parent
2cde7ec673
commit
478094abcf
2 changed files with 43 additions and 15 deletions
|
@ -28,6 +28,7 @@ planetwars-matchrunner = { path = "../planetwars-matchrunner" }
|
||||||
config = { version = "0.12", features = ["toml"] }
|
config = { version = "0.12", features = ["toml"] }
|
||||||
thiserror = "1.0.31"
|
thiserror = "1.0.31"
|
||||||
sha2 = "0.10"
|
sha2 = "0.10"
|
||||||
|
tokio-util = { version="0.7.3", features=["io"] }
|
||||||
|
|
||||||
# TODO: remove me
|
# TODO: remove me
|
||||||
shlex = "1.1"
|
shlex = "1.1"
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
use axum::body::{Body, StreamBody};
|
use axum::body::{Body, Bytes, StreamBody};
|
||||||
use axum::extract::{BodyStream, Path, Query};
|
use axum::extract::{BodyStream, FromRequest, Path, Query, RequestParts, TypedHeader};
|
||||||
use axum::handler::Handler;
|
use axum::handler::Handler;
|
||||||
|
use axum::headers::authorization::Basic;
|
||||||
|
use axum::headers::Authorization;
|
||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::{IntoResponse, Response};
|
||||||
use axum::routing::{get, head, post, put};
|
use axum::routing::{get, head, post, put};
|
||||||
use axum::Router;
|
use axum::{async_trait, Router};
|
||||||
use hyper::StatusCode;
|
use hyper::StatusCode;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
@ -16,7 +18,8 @@ use crate::util::gen_alphanumeric;
|
||||||
const REGISTRY_PATH: &'static str = "./data/registry";
|
const REGISTRY_PATH: &'static str = "./data/registry";
|
||||||
pub fn registry_service() -> Router {
|
pub fn registry_service() -> Router {
|
||||||
Router::new()
|
Router::new()
|
||||||
.nest("/v2", registry_api_v2())
|
// The docker API requires this trailing slash
|
||||||
|
.nest("/v2/", registry_api_v2())
|
||||||
.fallback(fallback.into_service())
|
.fallback(fallback.into_service())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +44,41 @@ async fn fallback(request: axum::http::Request<Body>) -> impl IntoResponse {
|
||||||
StatusCode::NOT_FOUND
|
StatusCode::NOT_FOUND
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AuthorizationHeader = TypedHeader<Authorization<Basic>>;
|
||||||
|
|
||||||
|
struct RegistryAuth;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<B> FromRequest<B> for RegistryAuth
|
||||||
|
where
|
||||||
|
B: Send,
|
||||||
|
{
|
||||||
|
type Rejection = Response<axum::body::Full<Bytes>>;
|
||||||
|
|
||||||
|
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
|
||||||
|
let TypedHeader(Authorization(_basic)) =
|
||||||
|
AuthorizationHeader::from_request(req).await.map_err(|_| {
|
||||||
|
let err = RegistryErrors {
|
||||||
|
errors: vec![RegistryError {
|
||||||
|
code: "UNAUTHORIZED".to_string(),
|
||||||
|
message: "please log in".to_string(),
|
||||||
|
detail: serde_json::Value::Null,
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
Response::builder()
|
||||||
|
.status(StatusCode::UNAUTHORIZED)
|
||||||
|
.header("Docker-Distribution-API-Version", "registry/2.0")
|
||||||
|
.header("WWW-Authenticate", "Basic")
|
||||||
|
.body(axum::body::Full::from(serde_json::to_vec(&err).unwrap()))
|
||||||
|
.unwrap()
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(RegistryAuth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn root_handler(_auth: RegistryAuth) -> impl IntoResponse {
|
||||||
// root should return 200 OK to confirm api compliance
|
// root should return 200 OK to confirm api compliance
|
||||||
async fn root_handler() -> Response<Body> {
|
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(StatusCode::OK)
|
.status(StatusCode::OK)
|
||||||
.header("Docker-Distribution-API-Version", "registry/2.0")
|
.header("Docker-Distribution-API-Version", "registry/2.0")
|
||||||
|
@ -89,15 +125,6 @@ async fn get_blob(
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn blob_upload(Path(repository_name): Path<String>) -> impl IntoResponse {
|
async fn blob_upload(Path(repository_name): Path<String>) -> impl IntoResponse {
|
||||||
// let value = json!({
|
|
||||||
// "errors": [
|
|
||||||
// {
|
|
||||||
// "code": "UNSUPPORTED",
|
|
||||||
// "message": "not implemented yet lol",
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// });
|
|
||||||
|
|
||||||
let uuid = gen_alphanumeric(16);
|
let uuid = gen_alphanumeric(16);
|
||||||
tokio::fs::File::create(PathBuf::from(REGISTRY_PATH).join("uploads").join(&uuid))
|
tokio::fs::File::create(PathBuf::from(REGISTRY_PATH).join("uploads").join(&uuid))
|
||||||
.await
|
.await
|
||||||
|
|
Loading…
Reference in a new issue