Skip to content

Commit 460ae76

Browse files
committed
adding can_get_user middleware
1 parent 80c332b commit 460ae76

3 files changed

Lines changed: 56 additions & 2 deletions

File tree

src/handlers/authorization.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anyhow::anyhow;
22
use axum::{
33
body::Body,
4-
extract::{Request, State},
4+
extract::{Path, Request, State},
55
http::Response,
66
middleware::Next,
77
Extension,
@@ -44,3 +44,49 @@ pub async fn can_list_users(
4444

4545
Err(errors::ServerError::Unauthorized)
4646
}
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+
}

src/handlers/routes.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ pub fn router(app_state: AppState) -> Router {
3535
authorization_middleware::can_list_users,
3636
)),
3737
)
38-
.route("/users/{user_id}", get(users::get_user))
38+
.route(
39+
"/users/{user_id}",
40+
get(users::get_user).layer(middleware::from_fn_with_state(
41+
app_state.clone(),
42+
authorization_middleware::can_get_user,
43+
)),
44+
)
3945
.route("/users", post(users::create_user))
4046
.route("/users/{user_id}", put(users::modify_user))
4147
.route("/users/{user_id}", delete(users::delete_user))

src/handlers/users_test.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ mod tests {
3333
};
3434

3535
let conn = MockDatabase::new(DatabaseBackend::Postgres)
36+
.append_query_results(vec![vec![user_db.clone()]])
37+
.append_query_results(vec![vec![user_db.clone()]])
3638
.append_query_results(vec![vec![user_db.clone()]])
3739
.into_connection();
3840

0 commit comments

Comments
 (0)