Put some api calls behind admin access
This commit is contained in:
@@ -93,3 +93,86 @@ pub async fn validate_token(
|
||||
request.extensions_mut().insert(filter_user(&user));
|
||||
Ok(next.run(request).await)
|
||||
}
|
||||
|
||||
pub async fn validate_admin(
|
||||
cookies: CookieJar,
|
||||
State(data): State<Arc<AppState>>,
|
||||
mut request: Request<Body>,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
||||
let token = cookies
|
||||
.get("token")
|
||||
.map(|cookie| cookie.value().to_string())
|
||||
.or_else(|| {
|
||||
request
|
||||
.headers()
|
||||
.get(header::AUTHORIZATION)
|
||||
.and_then(|header| header.to_str().ok())
|
||||
.and_then(|value| {
|
||||
if value.starts_with("Bearer ") {
|
||||
Some(value[7..].to_owned())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
let token = token.ok_or_else(|| {
|
||||
let error = json!({
|
||||
"status": "error",
|
||||
"message": "Please provide a valid token"
|
||||
});
|
||||
(StatusCode::UNAUTHORIZED, Json(error))
|
||||
})?;
|
||||
|
||||
let claims = decode_token(
|
||||
token,
|
||||
&DecodingKey::from_secret(data.env.token_secret.as_ref()),
|
||||
)
|
||||
.map_err(|(status, json_err)| {
|
||||
let error = json!({
|
||||
"status": json_err.status,
|
||||
"message": json_err.message
|
||||
});
|
||||
(status, Json(error))
|
||||
})?;
|
||||
|
||||
let uuid = (&claims.sub).parse::<i16>().map_err(|_| {
|
||||
let error = json!({
|
||||
"status": "error",
|
||||
"message": "Invalid user id"
|
||||
});
|
||||
(StatusCode::UNAUTHORIZED, Json(error))
|
||||
})?;
|
||||
|
||||
let user = sqlx::query_as::<_, User>(r#"SELECT * FROM users WHERE id = $1"#)
|
||||
.bind(uuid)
|
||||
.fetch_optional(&data.db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
let error = json!({
|
||||
"status": "error",
|
||||
"message": format!("Database error: {}", e)
|
||||
});
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, Json(error))
|
||||
})?;
|
||||
|
||||
let user = user.ok_or_else(|| {
|
||||
let error = json!({
|
||||
"status": "error",
|
||||
"message": "Invalid user"
|
||||
});
|
||||
(StatusCode::UNAUTHORIZED, Json(error))
|
||||
})?;
|
||||
|
||||
if !user.is_admin {
|
||||
let error = json!({
|
||||
"status": "error",
|
||||
"message": "Admin access required"
|
||||
});
|
||||
return Err((StatusCode::FORBIDDEN, Json(error)));
|
||||
}
|
||||
|
||||
request.extensions_mut().insert(filter_user(&user));
|
||||
Ok(next.run(request).await)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user