create auth check helper function
This commit is contained in:
parent
e3a0554823
commit
b5c770b349
|
@ -8,7 +8,7 @@ use axum::response::{IntoResponse, Response};
|
||||||
use tokio_util::io::ReaderStream;
|
use tokio_util::io::ReaderStream;
|
||||||
|
|
||||||
use crate::app_state::AppState;
|
use crate::app_state::AppState;
|
||||||
use crate::auth_storage::{does_user_have_permission, get_unauthenticated_response};
|
use crate::auth_storage::{does_user_have_permission, get_unauthenticated_response, does_user_have_repository_permission};
|
||||||
use crate::database::Database;
|
use crate::database::Database;
|
||||||
use crate::dto::RepositoryVisibility;
|
use crate::dto::RepositoryVisibility;
|
||||||
use crate::dto::user::{Permission, RegistryUserType, UserAuth};
|
use crate::dto::user::{Permission, RegistryUserType, UserAuth};
|
||||||
|
@ -16,11 +16,14 @@ use crate::dto::user::{Permission, RegistryUserType, UserAuth};
|
||||||
pub async fn digest_exists_head(Path((name, layer_digest)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Response {
|
pub async fn digest_exists_head(Path((name, layer_digest)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Response {
|
||||||
// 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 database = &state.database;
|
let database = &state.database;
|
||||||
if !does_user_have_permission(database, auth.user.username, name.clone(), Permission::PULL).await.unwrap()
|
/* if !does_user_have_permission(database, auth.user.username, name.clone(), Permission::PULL).await.unwrap()
|
||||||
&& !database.get_repository_visibility(&name).await.unwrap()
|
&& !database.get_repository_visibility(&name).await.unwrap()
|
||||||
.and_then(|v| Some(v == RepositoryVisibility::Public))
|
.and_then(|v| Some(v == RepositoryVisibility::Public))
|
||||||
.unwrap_or_else(|| false) {
|
.unwrap_or_else(|| false) {
|
||||||
|
|
||||||
|
return get_unauthenticated_response(&state.config);
|
||||||
|
} */
|
||||||
|
if !does_user_have_repository_permission(database, auth.user.username, name.clone(), Permission::PULL, Some(RepositoryVisibility::Public)).await.unwrap() {
|
||||||
return get_unauthenticated_response(&state.config);
|
return get_unauthenticated_response(&state.config);
|
||||||
}
|
}
|
||||||
drop(database);
|
drop(database);
|
||||||
|
@ -45,11 +48,7 @@ pub async fn digest_exists_head(Path((name, layer_digest)): Path<(String, String
|
||||||
pub async fn pull_digest_get(Path((name, layer_digest)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Response {
|
pub async fn pull_digest_get(Path((name, layer_digest)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Response {
|
||||||
// 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 database = &state.database;
|
let database = &state.database;
|
||||||
if !does_user_have_permission(database, auth.user.username, name.clone(), Permission::PULL).await.unwrap()
|
if !does_user_have_repository_permission(database, auth.user.username, name.clone(), Permission::PULL, Some(RepositoryVisibility::Public)).await.unwrap() {
|
||||||
&& !database.get_repository_visibility(&name).await.unwrap()
|
|
||||||
.and_then(|v| Some(v == RepositoryVisibility::Public))
|
|
||||||
.unwrap_or_else(|| false) {
|
|
||||||
|
|
||||||
return get_unauthenticated_response(&state.config);
|
return get_unauthenticated_response(&state.config);
|
||||||
}
|
}
|
||||||
drop(database);
|
drop(database);
|
||||||
|
|
|
@ -7,7 +7,7 @@ use axum::http::{StatusCode, HeaderMap, HeaderName, header};
|
||||||
use tracing::log::warn;
|
use tracing::log::warn;
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
|
|
||||||
use crate::auth_storage::{does_user_have_permission, get_unauthenticated_response};
|
use crate::auth_storage::{does_user_have_permission, get_unauthenticated_response, does_user_have_repository_permission};
|
||||||
use crate::app_state::AppState;
|
use crate::app_state::AppState;
|
||||||
use crate::database::Database;
|
use crate::database::Database;
|
||||||
use crate::dto::RepositoryVisibility;
|
use crate::dto::RepositoryVisibility;
|
||||||
|
@ -64,11 +64,7 @@ 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>) -> Response {
|
pub async fn pull_manifest_get(Path((name, reference)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Response {
|
||||||
// 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 database = &state.database;
|
let database = &state.database;
|
||||||
if !does_user_have_permission(database, auth.user.username, name.clone(), Permission::PULL).await.unwrap()
|
if !does_user_have_repository_permission(database, auth.user.username, name.clone(), Permission::PULL, Some(RepositoryVisibility::Public)).await.unwrap() {
|
||||||
&& !database.get_repository_visibility(&name).await.unwrap()
|
|
||||||
.and_then(|v| Some(v == RepositoryVisibility::Public))
|
|
||||||
.unwrap_or_else(|| false) {
|
|
||||||
|
|
||||||
return get_unauthenticated_response(&state.config);
|
return get_unauthenticated_response(&state.config);
|
||||||
}
|
}
|
||||||
drop(database);
|
drop(database);
|
||||||
|
@ -111,11 +107,7 @@ pub async fn pull_manifest_get(Path((name, reference)): Path<(String, String)>,
|
||||||
pub async fn manifest_exists_head(Path((name, reference)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Response {
|
pub async fn manifest_exists_head(Path((name, reference)): Path<(String, String)>, state: State<Arc<AppState>>, Extension(auth): Extension<UserAuth>) -> Response {
|
||||||
// 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 database = &state.database;
|
let database = &state.database;
|
||||||
if !does_user_have_permission(database, auth.user.username, name.clone(), Permission::PULL).await.unwrap()
|
if !does_user_have_repository_permission(database, auth.user.username, name.clone(), Permission::PULL, Some(RepositoryVisibility::Public)).await.unwrap() {
|
||||||
&& !database.get_repository_visibility(&name).await.unwrap()
|
|
||||||
.and_then(|v| Some(v == RepositoryVisibility::Public))
|
|
||||||
.unwrap_or_else(|| false) {
|
|
||||||
|
|
||||||
return get_unauthenticated_response(&state.config);
|
return get_unauthenticated_response(&state.config);
|
||||||
}
|
}
|
||||||
drop(database);
|
drop(database);
|
||||||
|
|
|
@ -4,7 +4,7 @@ use axum::{extract::{State, Path}, http::{StatusCode, HeaderMap, header, HeaderN
|
||||||
|
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::{app_state::AppState, dto::user::{Permission, RegistryUserType}, config::Config};
|
use crate::{app_state::AppState, dto::{user::{Permission, RegistryUserType}, RepositoryVisibility}, config::Config};
|
||||||
use crate::database::Database;
|
use crate::database::Database;
|
||||||
|
|
||||||
/// Temporary struct for storing auth information in memory.
|
/// Temporary struct for storing auth information in memory.
|
||||||
|
@ -73,14 +73,42 @@ pub async fn require_auth<B>(State(state): State<Arc<AppState>>, mut request: Re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn does_user_have_permission(database: &impl Database, username: String, repository: String, permission: Permission) -> sqlx::Result<bool> {
|
pub async fn does_user_have_permission(database: &impl Database, username: String, repository: String, permission: Permission) -> anyhow::Result<bool> {
|
||||||
|
does_user_have_repository_permission(database, username, repository, permission, None).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if a user has permission to do something in a repository.
|
||||||
|
///
|
||||||
|
/// * `database`: Database connection.
|
||||||
|
/// * `username`: Name of the user.
|
||||||
|
/// * `repository`: Name of the repository.
|
||||||
|
/// * `permissions`: Permission to check for.
|
||||||
|
/// * `required_visibility`: Specified if there is a specific visibility of the repository that will give the user permission.
|
||||||
|
pub async fn does_user_have_repository_permission(database: &impl Database, username: String, repository: String, permission: Permission, required_visibility: Option<RepositoryVisibility>) -> anyhow::Result<bool> {
|
||||||
let allowed_to = {
|
let allowed_to = {
|
||||||
match database.get_user_registry_type(username.clone()).await.unwrap() {
|
match database.get_user_registry_type(username.clone()).await? {
|
||||||
Some(RegistryUserType::Admin) => true,
|
Some(RegistryUserType::Admin) => true,
|
||||||
_ => match database.get_user_repo_permissions(username, repository).await.unwrap() {
|
_ => {
|
||||||
|
if let Some(perms) = database.get_user_repo_permissions(username, repository.clone()).await? {
|
||||||
|
if perms.has_permission(permission) {
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(vis) = required_visibility {
|
||||||
|
if let Some(repo_vis) = database.get_repository_visibility(&repository).await? {
|
||||||
|
if vis == repo_vis {
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
/* match database.get_user_repo_permissions(username, repository).await.unwrap() {
|
||||||
Some(perms) => if perms.has_permission(permission) { true } else { false },
|
Some(perms) => if perms.has_permission(permission) { true } else { false },
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue