|
1 | 1 | use anyhow::anyhow; |
2 | 2 | use axum::{ |
3 | 3 | body::Body, |
4 | | - extract::{Request, State}, |
| 4 | + extract::{Path, Request, State}, |
5 | 5 | http::Response, |
6 | 6 | middleware::Next, |
7 | 7 | Extension, |
@@ -44,3 +44,49 @@ pub async fn can_list_users( |
44 | 44 |
|
45 | 45 | Err(errors::ServerError::Unauthorized) |
46 | 46 | } |
| 47 | + |
| 48 | +pub async fn can_get_user( |
| 49 | + State(state): State<AppState>, |
| 50 | + Extension(claims): Extension<Claims>, |
| 51 | + Path(user_id): Path<String>, |
| 52 | + req: Request, |
| 53 | + next: Next, |
| 54 | +) -> Result<Response<Body>, errors::ServerError> { |
| 55 | + let conn = &*state.conn.clone(); |
| 56 | + let authorization = state.authorization.clone(); |
| 57 | + |
| 58 | + let user_actor = User::find() |
| 59 | + .filter(models::user::Column::Auth0Id.eq(claims.sub.to_owned())) |
| 60 | + .one(conn) |
| 61 | + .await |
| 62 | + .map_err(|err| errors::ServerError::Internal(anyhow!(err)))? |
| 63 | + .ok_or(errors::ServerError::Unauthorized)?; |
| 64 | + |
| 65 | + let user_resource: models::user::Model = (|| -> Result<_, errors::ServerError> { |
| 66 | + if user_id == "me" { |
| 67 | + return Ok(User::find() |
| 68 | + .filter(models::user::Column::Auth0Id.eq(claims.sub.to_owned())) |
| 69 | + .one(conn)); |
| 70 | + } |
| 71 | + let user_id_uuid = uuid::Uuid::parse_str(user_id.as_str()) |
| 72 | + .map_err(|err| errors::ServerError::InvalidUUID(anyhow!(err)))?; |
| 73 | + Ok(User::find_by_id(user_id_uuid).one(conn)) |
| 74 | + })()? |
| 75 | + .await |
| 76 | + .map_err(|err| errors::ServerError::Internal(anyhow!(err)))? |
| 77 | + .ok_or(errors::ServerError::NotFound)?; |
| 78 | + |
| 79 | + let is_authorized = authorization.can_get_user( |
| 80 | + AuthzUser { |
| 81 | + user_id: user_actor.user_id.to_owned(), |
| 82 | + role: user_actor.role.to_owned(), |
| 83 | + }, |
| 84 | + user_resource.user_id.to_owned(), |
| 85 | + ); |
| 86 | + |
| 87 | + if is_authorized { |
| 88 | + return Ok(next.run(req).await); |
| 89 | + } |
| 90 | + |
| 91 | + Err(errors::ServerError::Unauthorized) |
| 92 | +} |
0 commit comments