51 lines
1.3 KiB
Rust
51 lines
1.3 KiB
Rust
use axum::{
|
|
Json,
|
|
extract::{Extension, State},
|
|
http::StatusCode,
|
|
};
|
|
use base64::{Engine as _, engine::general_purpose};
|
|
use rand::RngCore;
|
|
use rand::rngs::OsRng;
|
|
|
|
use crate::dto::api::{CreateApiKeyRequest, CreateApiKeyResponse};
|
|
use crate::middlewares::auth::middleware::Auth;
|
|
use crate::state::app_state::AppState;
|
|
use crate::utils::crypto::hash_key;
|
|
|
|
fn generate_api_key() -> String {
|
|
let mut bytes = [0u8; 32];
|
|
OsRng.fill_bytes(&mut bytes);
|
|
general_purpose::URL_SAFE_NO_PAD.encode(bytes)
|
|
}
|
|
|
|
pub async fn create_api_key(
|
|
State(state): State<AppState>,
|
|
Extension(claims): Extension<Auth>,
|
|
Json(body): Json<CreateApiKeyRequest>,
|
|
) -> Result<Json<CreateApiKeyResponse>, StatusCode> {
|
|
if matches!(claims, Auth::ApiKey(_)) {
|
|
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)
|
|
VALUES ($1, $2, $3, $4)
|
|
"#,
|
|
key_hash,
|
|
body.name,
|
|
claims.user_id(),
|
|
&body.scopes
|
|
)
|
|
.execute(&state.postgres)
|
|
.await
|
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
|
|
|
Ok(Json(CreateApiKeyResponse { api_key: raw_key }))
|
|
}
|