fix pulling from public repositories when not logged in
This commit is contained in:
parent
603c0062ba
commit
0150a1a11e
|
@ -14,4 +14,4 @@
|
||||||
- [ ] fix repository list
|
- [ ] fix repository list
|
||||||
- [ ] its not responding with anything
|
- [ ] its not responding with anything
|
||||||
- [ ] make sure private repositories dont show up
|
- [ ] make sure private repositories dont show up
|
||||||
- [ ] fix pulling from public repositories when not logged in
|
- [x] fix pulling from public repositories when not logged in
|
|
@ -9,17 +9,24 @@ use tokio_util::io::ReaderStream;
|
||||||
|
|
||||||
use crate::app_state::AppState;
|
use crate::app_state::AppState;
|
||||||
use crate::auth::access_denied_response;
|
use crate::auth::access_denied_response;
|
||||||
|
use crate::database::Database;
|
||||||
use crate::dto::RepositoryVisibility;
|
use crate::dto::RepositoryVisibility;
|
||||||
use crate::dto::user::{Permission, UserAuth};
|
use crate::dto::user::{Permission, UserAuth};
|
||||||
use crate::error::AppError;
|
use crate::error::AppError;
|
||||||
|
|
||||||
pub async fn digest_exists_head(Path((name, layer_digest)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Result<Response, AppError> {
|
pub async fn digest_exists_head(Path((name, layer_digest)): Path<(String, String)>, state: State<Arc<AppState>>, auth: Option<UserAuth>) -> Result<Response, AppError> {
|
||||||
// Check if the user has permission to pull, or that the repository is public
|
// Check if the user has permission to pull, or that the repository is public
|
||||||
let mut auth_driver = state.auth_checker.lock().await;
|
if let Some(auth) = auth {
|
||||||
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PULL, Some(RepositoryVisibility::Public)).await? {
|
let mut auth_driver = state.auth_checker.lock().await;
|
||||||
return Ok(access_denied_response(&state.config));
|
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PULL, Some(RepositoryVisibility::Public)).await? {
|
||||||
|
return Ok(access_denied_response(&state.config));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let database = &state.database;
|
||||||
|
if database.get_repository_visibility(&name).await? != Some(RepositoryVisibility::Public) {
|
||||||
|
return Ok(access_denied_response(&state.config));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
drop(auth_driver);
|
|
||||||
|
|
||||||
let storage = state.storage.lock().await;
|
let storage = state.storage.lock().await;
|
||||||
|
|
||||||
|
@ -38,13 +45,19 @@ pub async fn digest_exists_head(Path((name, layer_digest)): Path<(String, String
|
||||||
Ok(StatusCode::NOT_FOUND.into_response())
|
Ok(StatusCode::NOT_FOUND.into_response())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn pull_digest_get(Path((name, layer_digest)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Result<Response, AppError> {
|
pub async fn pull_digest_get(Path((name, layer_digest)): Path<(String, String)>, state: State<Arc<AppState>>, auth: Option<UserAuth>) -> Result<Response, AppError> {
|
||||||
// Check if the user has permission to pull, or that the repository is public
|
// Check if the user has permission to pull, or that the repository is public
|
||||||
let mut auth_driver = state.auth_checker.lock().await;
|
if let Some(auth) = auth {
|
||||||
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PULL, Some(RepositoryVisibility::Public)).await? {
|
let mut auth_driver = state.auth_checker.lock().await;
|
||||||
return Ok(access_denied_response(&state.config));
|
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PULL, Some(RepositoryVisibility::Public)).await? {
|
||||||
|
return Ok(access_denied_response(&state.config));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let database = &state.database;
|
||||||
|
if database.get_repository_visibility(&name).await? != Some(RepositoryVisibility::Public) {
|
||||||
|
return Ok(access_denied_response(&state.config));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
drop(auth_driver);
|
|
||||||
|
|
||||||
let storage = state.storage.lock().await;
|
let storage = state.storage.lock().await;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ use crate::dto::manifest::Manifest;
|
||||||
use crate::dto::user::{UserAuth, Permission};
|
use crate::dto::user::{UserAuth, Permission};
|
||||||
use crate::error::AppError;
|
use crate::error::AppError;
|
||||||
|
|
||||||
pub async fn upload_manifest_put(Path((name, reference)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>, body: String) -> Result<Response, AppError> {
|
pub async fn upload_manifest_put(Path((name, reference)): Path<(String, String)>, state: State<Arc<AppState>>, auth: UserAuth, body: String) -> Result<Response, AppError> {
|
||||||
let mut auth_driver = state.auth_checker.lock().await;
|
let mut auth_driver = state.auth_checker.lock().await;
|
||||||
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
||||||
return Ok(access_denied_response(&state.config));
|
return Ok(access_denied_response(&state.config));
|
||||||
|
@ -64,13 +64,19 @@ pub async fn upload_manifest_put(Path((name, reference)): Path<(String, String)>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn pull_manifest_get(Path((name, reference)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Result<Response, AppError> {
|
pub async fn pull_manifest_get(Path((name, reference)): Path<(String, String)>, state: State<Arc<AppState>>, auth: Option<UserAuth>) -> Result<Response, AppError> {
|
||||||
// Check if the user has permission to pull, or that the repository is public
|
// Check if the user has permission to pull, or that the repository is public
|
||||||
let mut auth_driver = state.auth_checker.lock().await;
|
if let Some(auth) = auth {
|
||||||
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PULL, Some(RepositoryVisibility::Public)).await? {
|
let mut auth_driver = state.auth_checker.lock().await;
|
||||||
return Ok(access_denied_response(&state.config));
|
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PULL, Some(RepositoryVisibility::Public)).await? {
|
||||||
|
return Ok(access_denied_response(&state.config));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let database = &state.database;
|
||||||
|
if database.get_repository_visibility(&name).await? != Some(RepositoryVisibility::Public) {
|
||||||
|
return Ok(access_denied_response(&state.config));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
drop(auth_driver);
|
|
||||||
|
|
||||||
let database = &state.database;
|
let database = &state.database;
|
||||||
let digest = match Digest::is_digest(&reference) {
|
let digest = match Digest::is_digest(&reference) {
|
||||||
|
@ -107,13 +113,20 @@ pub async fn pull_manifest_get(Path((name, reference)): Path<(String, String)>,
|
||||||
).into_response())
|
).into_response())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn manifest_exists_head(Path((name, reference)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Result<Response, AppError> {
|
pub async fn manifest_exists_head(Path((name, reference)): Path<(String, String)>, state: State<Arc<AppState>>, auth: Option<UserAuth>) -> Result<Response, AppError> {
|
||||||
// Check if the user has permission to pull, or that the repository is public
|
// Check if the user has permission to pull, or that the repository is public
|
||||||
let mut auth_driver = state.auth_checker.lock().await;
|
if let Some(auth) = auth {
|
||||||
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PULL, Some(RepositoryVisibility::Public)).await? {
|
let mut auth_driver = state.auth_checker.lock().await;
|
||||||
return Ok(access_denied_response(&state.config));
|
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PULL, Some(RepositoryVisibility::Public)).await? {
|
||||||
|
return Ok(access_denied_response(&state.config));
|
||||||
|
}
|
||||||
|
drop(auth_driver);
|
||||||
|
} else {
|
||||||
|
let database = &state.database;
|
||||||
|
if database.get_repository_visibility(&name).await? != Some(RepositoryVisibility::Public) {
|
||||||
|
return Ok(access_denied_response(&state.config));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
drop(auth_driver);
|
|
||||||
|
|
||||||
// Get the digest from the reference path.
|
// Get the digest from the reference path.
|
||||||
let database = &state.database;
|
let database = &state.database;
|
||||||
|
@ -148,7 +161,7 @@ pub async fn manifest_exists_head(Path((name, reference)): Path<(String, String)
|
||||||
).into_response())
|
).into_response())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_manifest(Path((name, reference)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Result<Response, AppError> {
|
pub async fn delete_manifest(Path((name, reference)): Path<(String, String)>, state: State<Arc<AppState>>, auth: UserAuth) -> Result<Response, AppError> {
|
||||||
let mut auth_driver = state.auth_checker.lock().await;
|
let mut auth_driver = state.auth_checker.lock().await;
|
||||||
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
||||||
return Ok(access_denied_response(&state.config));
|
return Ok(access_denied_response(&state.config));
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use axum::Extension;
|
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::{IntoResponse, Response};
|
||||||
use axum::http::{StatusCode, HeaderName};
|
use axum::http::{StatusCode, HeaderName};
|
||||||
|
@ -18,7 +17,7 @@ use crate::dto::user::UserAuth;
|
||||||
|
|
||||||
/// https://docs.docker.com/registry/spec/api/#api-version-check
|
/// https://docs.docker.com/registry/spec/api/#api-version-check
|
||||||
/// full endpoint: `/v2/`
|
/// full endpoint: `/v2/`
|
||||||
pub async fn version_check(Extension(_auth): Extension<UserAuth>, _state: State<Arc<AppState>>) -> Response {
|
pub async fn version_check(_state: State<Arc<AppState>>) -> Response {
|
||||||
(
|
(
|
||||||
StatusCode::OK,
|
StatusCode::OK,
|
||||||
[( HeaderName::from_static("docker-distribution-api-version"), "registry/2.0" )]
|
[( HeaderName::from_static("docker-distribution-api-version"), "registry/2.0" )]
|
||||||
|
|
|
@ -18,7 +18,7 @@ use crate::dto::user::{UserAuth, Permission};
|
||||||
use crate::error::AppError;
|
use crate::error::AppError;
|
||||||
|
|
||||||
/// Starting an upload
|
/// Starting an upload
|
||||||
pub async fn start_upload_post(Path((name, )): Path<(String, )>, Extension(auth): Extension<UserAuth>, state: State<Arc<AppState>>) -> Result<Response, AppError> {
|
pub async fn start_upload_post(Path((name, )): Path<(String, )>, auth: UserAuth, state: State<Arc<AppState>>) -> Result<Response, AppError> {
|
||||||
let mut auth_driver = state.auth_checker.lock().await;
|
let mut auth_driver = state.auth_checker.lock().await;
|
||||||
if auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
if auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
||||||
debug!("Upload requested");
|
debug!("Upload requested");
|
||||||
|
@ -38,7 +38,7 @@ pub async fn start_upload_post(Path((name, )): Path<(String, )>, Extension(auth)
|
||||||
Ok(access_denied_response(&state.config))
|
Ok(access_denied_response(&state.config))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn chunked_upload_layer_patch(Path((name, layer_uuid)): Path<(String, String)>, Extension(auth): Extension<UserAuth>, state: State<Arc<AppState>>, mut body: BodyStream) -> Result<Response, AppError> {
|
pub async fn chunked_upload_layer_patch(Path((name, layer_uuid)): Path<(String, String)>, auth: UserAuth, state: State<Arc<AppState>>, mut body: BodyStream) -> Result<Response, AppError> {
|
||||||
let mut auth_driver = state.auth_checker.lock().await;
|
let mut auth_driver = state.auth_checker.lock().await;
|
||||||
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
||||||
return Ok(access_denied_response(&state.config));
|
return Ok(access_denied_response(&state.config));
|
||||||
|
@ -97,7 +97,7 @@ pub async fn chunked_upload_layer_patch(Path((name, layer_uuid)): Path<(String,
|
||||||
).into_response())
|
).into_response())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn finish_chunked_upload_put(Path((name, layer_uuid)): Path<(String, String)>, Query(query): Query<HashMap<String, String>>, Extension(auth): Extension<UserAuth>, state: State<Arc<AppState>>, body: Bytes) -> Result<Response, AppError> {
|
pub async fn finish_chunked_upload_put(Path((name, layer_uuid)): Path<(String, String)>, Query(query): Query<HashMap<String, String>>, auth: UserAuth, state: State<Arc<AppState>>, body: Bytes) -> Result<Response, AppError> {
|
||||||
let mut auth_driver = state.auth_checker.lock().await;
|
let mut auth_driver = state.auth_checker.lock().await;
|
||||||
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
||||||
return Ok(access_denied_response(&state.config));
|
return Ok(access_denied_response(&state.config));
|
||||||
|
@ -126,7 +126,7 @@ pub async fn finish_chunked_upload_put(Path((name, layer_uuid)): Path<(String, S
|
||||||
).into_response())
|
).into_response())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn cancel_upload_delete(Path((name, layer_uuid)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Result<Response, AppError> {
|
pub async fn cancel_upload_delete(Path((name, layer_uuid)): Path<(String, String)>, state: State<Arc<AppState>>, auth: UserAuth) -> Result<Response, AppError> {
|
||||||
let mut auth_driver = state.auth_checker.lock().await;
|
let mut auth_driver = state.auth_checker.lock().await;
|
||||||
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
||||||
return Ok(access_denied_response(&state.config));
|
return Ok(access_denied_response(&state.config));
|
||||||
|
@ -140,7 +140,7 @@ pub async fn cancel_upload_delete(Path((name, layer_uuid)): Path<(String, String
|
||||||
Ok(StatusCode::OK.into_response())
|
Ok(StatusCode::OK.into_response())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn check_upload_status_get(Path((name, layer_uuid)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Result<Response, AppError> {
|
pub async fn check_upload_status_get(Path((name, layer_uuid)): Path<(String, String)>, state: State<Arc<AppState>>, auth: UserAuth) -> Result<Response, AppError> {
|
||||||
let mut auth_driver = state.auth_checker.lock().await;
|
let mut auth_driver = state.auth_checker.lock().await;
|
||||||
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
if !auth_driver.user_has_permission(auth.user.username, name.clone(), Permission::PUSH, None).await? {
|
||||||
return Ok(access_denied_response(&state.config));
|
return Ok(access_denied_response(&state.config));
|
||||||
|
|
|
@ -410,9 +410,20 @@ impl Database for Pool<Sqlite> {
|
||||||
|
|
||||||
async fn verify_user_login(&self, email: String, password: String) -> anyhow::Result<bool> {
|
async fn verify_user_login(&self, email: String, password: String) -> anyhow::Result<bool> {
|
||||||
let email = email.to_lowercase();
|
let email = email.to_lowercase();
|
||||||
let row: (String, ) = sqlx::query_as("SELECT password_hash FROM user_logins WHERE email = ?")
|
|
||||||
|
let row: (String,) = match sqlx::query_as("SELECT password_hash FROM user_logins WHERE email = ?")
|
||||||
.bind(email)
|
.bind(email)
|
||||||
.fetch_one(self).await?;
|
.fetch_one(self).await {
|
||||||
|
Ok(row) => row,
|
||||||
|
Err(e) => match e {
|
||||||
|
sqlx::Error::RowNotFound => {
|
||||||
|
return Ok(false)
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
return Err(anyhow::Error::new(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Ok(bcrypt::verify(password, &row.0)?)
|
Ok(bcrypt::verify(password, &row.0)?)
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ CREATE TABLE IF NOT EXISTS user_tokens (
|
||||||
created_at BIGINT NOT NULL
|
created_at BIGINT NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
-- create admin user
|
-- create admin user (password is 'admin')
|
||||||
INSERT OR IGNORE INTO users (username, email, login_source) VALUES ('admin', 'admin@example.com', 0);
|
INSERT OR IGNORE INTO users (username, email, login_source) VALUES ('admin', 'admin@example.com', 0);
|
||||||
INSERT OR IGNORE INTO user_logins (email, password_hash, password_salt) VALUES ('admin@example.com', '$2y$05$ZBnzGzctboHkUDMr4W02jOaUuPwmRC2OgWKKBxqiQsYv53OkUrfO6', 'x5ECk0jUmOSfBWxW52wsyO');
|
INSERT OR IGNORE INTO user_logins (email, password_hash, password_salt) VALUES ('admin@example.com', '$2y$05$v9ND7dQKvfkOtY4XpnKVaOpvV0F5RDnW1Ec.nfkZ0vmEjLX5D5S8e', 'x5ECk0jUmOSfBWxW52wsyO');
|
||||||
INSERT OR IGNORE INTO user_registry_permissions (email, user_type) VALUES ('admin@example.com', 1);
|
INSERT OR IGNORE INTO user_registry_permissions (email, user_type) VALUES ('admin@example.com', 1);
|
|
@ -1,7 +1,12 @@
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use axum::{http::{StatusCode, header, HeaderName, HeaderMap, Request, request::Parts}, extract::{FromRequest, FromRequestParts}};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
|
use crate::{app_state::AppState, database::Database};
|
||||||
|
|
||||||
use super::RepositoryVisibility;
|
use super::RepositoryVisibility;
|
||||||
|
|
||||||
|
@ -72,6 +77,51 @@ impl UserAuth {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl FromRequestParts<Arc<AppState>> for UserAuth {
|
||||||
|
type Rejection = (StatusCode, HeaderMap);
|
||||||
|
|
||||||
|
async fn from_request_parts(parts: &mut Parts, state: &Arc<AppState>) -> Result<Self, Self::Rejection> {
|
||||||
|
let bearer = format!("Bearer realm=\"{}/auth\"", state.config.url());
|
||||||
|
let mut failure_headers = HeaderMap::new();
|
||||||
|
failure_headers.append(header::WWW_AUTHENTICATE, bearer.parse().unwrap());
|
||||||
|
failure_headers.append(HeaderName::from_static("docker-distribution-api-version"), "registry/2.0".parse().unwrap());
|
||||||
|
|
||||||
|
let auth = String::from(
|
||||||
|
parts.headers
|
||||||
|
.get(header::AUTHORIZATION)
|
||||||
|
.ok_or((StatusCode::UNAUTHORIZED, failure_headers.clone()))?
|
||||||
|
.to_str()
|
||||||
|
.map_err(|_| (StatusCode::UNAUTHORIZED, failure_headers.clone()))?
|
||||||
|
);
|
||||||
|
|
||||||
|
let token = match auth.split_once(' ') {
|
||||||
|
Some((auth, token)) if auth == "Bearer" => token,
|
||||||
|
// This line would allow empty tokens
|
||||||
|
//_ if auth == "Bearer" => Ok(AuthToken(None)),
|
||||||
|
_ => return Err( (StatusCode::UNAUTHORIZED, failure_headers) ),
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the token is not valid, return an unauthorized response
|
||||||
|
let database = &state.database;
|
||||||
|
if let Ok(Some(user)) = database.verify_user_token(token.to_string()).await {
|
||||||
|
debug!("Authenticated user through middleware: {}", user.user.username);
|
||||||
|
|
||||||
|
Ok(user)
|
||||||
|
} else {
|
||||||
|
let bearer = format!("Bearer realm=\"{}/auth\"", state.config.url());
|
||||||
|
let mut headers = HeaderMap::new();
|
||||||
|
headers.insert(header::WWW_AUTHENTICATE, bearer.parse().unwrap());
|
||||||
|
headers.insert(HeaderName::from_static("docker-distribution-api-version"), "registry/2.0".to_string().parse().unwrap());
|
||||||
|
|
||||||
|
Err((
|
||||||
|
StatusCode::UNAUTHORIZED,
|
||||||
|
headers
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct Permission: u32 {
|
pub struct Permission: u32 {
|
||||||
|
|
|
@ -102,7 +102,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
let state = Arc::new(AppState::new(pool, storage_driver, config, auth_driver));
|
let state = Arc::new(AppState::new(pool, storage_driver, config, auth_driver));
|
||||||
|
|
||||||
let auth_middleware = axum::middleware::from_fn_with_state(state.clone(), auth::require_auth);
|
//let auth_middleware = axum::middleware::from_fn_with_state(state.clone(), auth::require_auth);
|
||||||
let path_middleware = axum::middleware::from_fn(change_request_paths);
|
let path_middleware = axum::middleware::from_fn(change_request_paths);
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
|
@ -129,7 +129,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
.put(api::manifests::upload_manifest_put)
|
.put(api::manifests::upload_manifest_put)
|
||||||
.head(api::manifests::manifest_exists_head)
|
.head(api::manifests::manifest_exists_head)
|
||||||
.delete(api::manifests::delete_manifest))
|
.delete(api::manifests::delete_manifest))
|
||||||
.layer(auth_middleware) // require auth for ALL v2 routes
|
//.layer(auth_middleware) // require auth for ALL v2 routes
|
||||||
)
|
)
|
||||||
.with_state(state)
|
.with_state(state)
|
||||||
.layer(TraceLayer::new_for_http());
|
.layer(TraceLayer::new_for_http());
|
||||||
|
|
Loading…
Reference in New Issue