feat: get roles associted to api key
This commit is contained in:
+34
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT u.id AS user_id, ak.id as key_id, ak.scopes as roles\n FROM auth.api_key ak\n JOIN auth.app_user u ON u.id = ak.created_by\n WHERE ak.key_hash = $1\n AND ak.revoked_at IS NULL\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "user_id",
|
||||
"type_info": "Uuid"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "key_id",
|
||||
"type_info": "Uuid"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "roles",
|
||||
"type_info": "TextArray"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "931f64701ca90a159a54dab717b9cb4004548fc2efc7cbcb056e11e2534eb441"
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT u.id AS user_id, ak.id as key_id\n FROM auth.api_key ak\n JOIN auth.app_user u ON u.id = ak.created_by\n WHERE ak.key_hash = $1\n AND ak.revoked_at IS NULL\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "user_id",
|
||||
"type_info": "Uuid"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "key_id",
|
||||
"type_info": "Uuid"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "c0816078de6c25d441752500b9307900ff3d6c7781ebd9c0d8b47031539d8bdf"
|
||||
}
|
||||
@@ -1,7 +1,15 @@
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub enum ApiKeyClaimsRoles {
|
||||
Admin,
|
||||
Read,
|
||||
Write,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ApiKeyClaims {
|
||||
pub sub: Uuid,
|
||||
pub api_key_id: Uuid,
|
||||
pub roles: Vec<ApiKeyClaimsRoles>,
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use axum::{
|
||||
use crate::databases::postgres::{
|
||||
api_key::update_last_access, user_repository::ensure_user_exists,
|
||||
};
|
||||
use crate::middlewares::auth::apikey::ApiKeyClaims;
|
||||
use crate::middlewares::auth::apikey::{ApiKeyClaims, ApiKeyClaimsRoles};
|
||||
use crate::middlewares::auth::keycloak::{KeycloakClaims, get_jwks, refresh_jwks, validate_token};
|
||||
use crate::state::app_state::AppState;
|
||||
use crate::utils::crypto::hash_key;
|
||||
@@ -127,7 +127,7 @@ async fn try_api_key(
|
||||
|
||||
let row = sqlx::query!(
|
||||
r#"
|
||||
SELECT u.id AS user_id, ak.id as key_id
|
||||
SELECT u.id AS user_id, ak.id as key_id, ak.scopes as roles
|
||||
FROM auth.api_key ak
|
||||
JOIN auth.app_user u ON u.id = ak.created_by
|
||||
WHERE ak.key_hash = $1
|
||||
@@ -145,6 +145,17 @@ async fn try_api_key(
|
||||
|
||||
tracing::debug!("API key valid, user_id={}", row.user_id);
|
||||
|
||||
let roles = row
|
||||
.roles
|
||||
.into_iter()
|
||||
.filter_map(|r| match r.as_str() {
|
||||
"admin" => Some(ApiKeyClaimsRoles::Admin),
|
||||
"read" => Some(ApiKeyClaimsRoles::Read),
|
||||
"write" => Some(ApiKeyClaimsRoles::Write),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
handle_auth(
|
||||
state,
|
||||
request,
|
||||
@@ -152,6 +163,7 @@ async fn try_api_key(
|
||||
Auth::ApiKey(ApiKeyClaims {
|
||||
sub: row.user_id,
|
||||
api_key_id: row.key_id,
|
||||
roles,
|
||||
}),
|
||||
)
|
||||
.await
|
||||
|
||||
@@ -8,6 +8,7 @@ use rand::RngCore;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use crate::dto::api::{CreateApiKeyRequest, CreateApiKeyResponse};
|
||||
use crate::middlewares::auth::apikey::ApiKeyClaimsRoles;
|
||||
use crate::middlewares::auth::middleware::Auth;
|
||||
use crate::state::app_state::AppState;
|
||||
use crate::utils::crypto::hash_key;
|
||||
@@ -23,15 +24,14 @@ pub async fn create_api_key(
|
||||
Extension(claims): Extension<Auth>,
|
||||
Json(body): Json<CreateApiKeyRequest>,
|
||||
) -> Result<Json<CreateApiKeyResponse>, StatusCode> {
|
||||
if matches!(claims, Auth::ApiKey(_)) {
|
||||
if matches!(&claims, Auth::ApiKey(api_key) if !api_key.roles.contains(&ApiKeyClaimsRoles::Admin))
|
||||
{
|
||||
return Err(StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
let raw_key = generate_api_key();
|
||||
let key_hash = hash_key(&raw_key);
|
||||
|
||||
dbg!(&claims);
|
||||
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO auth.api_key (key_hash, name, created_by, scopes)
|
||||
|
||||
Reference in New Issue
Block a user