diff options
author | Santo Cariotti <santo@dcariotti.me> | 2024-09-03 12:44:45 +0200 |
---|---|---|
committer | Santo Cariotti <santo@dcariotti.me> | 2024-09-03 12:44:45 +0200 |
commit | 4082fc6ea1d3976f76a0190112d99c73dd1419fb (patch) | |
tree | c9d2c84187896e50032b1c6aefae60ee6f344c86 /src | |
parent | 739cd1ba90bc0411c7d4d48943f84f19db6aced2 (diff) |
Add user query used to find an user by id
Diffstat (limited to 'src')
-rw-r--r-- | src/graphql/query.rs | 19 | ||||
-rw-r--r-- | src/graphql/types/user.rs | 56 |
2 files changed, 74 insertions, 1 deletions
diff --git a/src/graphql/query.rs b/src/graphql/query.rs index d2b7968..c122220 100644 --- a/src/graphql/query.rs +++ b/src/graphql/query.rs @@ -11,7 +11,7 @@ impl Query { "1.0" } - /// Returns all the users + /// Returns all the users. It is restricted to admins only. /// /// Request example: /// ```text @@ -29,6 +29,23 @@ impl Query { user::get_users(ctx, limit, offset).await } + /// Returns an user by ID. Admins can check everyone. + /// + /// Request example: + /// ```text + /// curl http://localhost:8000/graphql + /// -H 'authorization: Bearer ***' + /// -H 'content-type: application/json' + /// -d '{"query":"{user(id: 1) { id, email, password, name, address, isAdmin }}"}' + /// ``` + async fn user<'ctx>( + &self, + ctx: &Context<'ctx>, + #[graphql(desc = "User to find")] id: i32, + ) -> Result<user::User, String> { + user::get_user_by_id(ctx, id).await + } + /// Returns all the positions /// /// Request example: diff --git a/src/graphql/types/user.rs b/src/graphql/types/user.rs index 69ffc38..b185a16 100644 --- a/src/graphql/types/user.rs +++ b/src/graphql/types/user.rs @@ -91,6 +91,62 @@ pub async fn get_users<'ctx>( } } +/// Get users from the database +pub async fn get_user_by_id<'ctx>(ctx: &Context<'ctx>, id: i32) -> Result<User, String> { + let state = ctx.data::<AppState>().expect("Can't connect to db"); + let client = &*state.client; + let auth: &Authentication = ctx.data().unwrap(); + match auth { + Authentication::NotLogged => Err("Unauthorized".to_string()), + Authentication::Logged(claims) => { + let claim_user = find_user(client, claims.user_id) + .await + .expect("Should not be here"); + + let rows; + if claim_user.is_admin { + rows = client + .query( + "SELECT id, email, password, name, address, is_admin FROM users + WHERE id = $1", + &[&id], + ) + .await + .unwrap(); + } else if claims.user_id != id { + return Err("Unauthorized".to_string()); + } else { + rows = client + .query( + "SELECT id, email, password, name, address, is_admin FROM users + WHERE id = $1", + &[&claims.user_id], + ) + .await + .unwrap(); + } + + let users: Vec<User> = rows + .iter() + .map(|row| User { + id: row.get("id"), + email: row.get("email"), + password: row.get("password"), + name: row.get("name"), + address: row.get("address"), + is_admin: row.get("is_admin"), + }) + .collect(); + + if users.len() == 0 { + return Err("Not found".to_string()); + } + + Ok(users[0].clone()) + } + } +} + /// Find an user with id = `id` using the PostgreSQL `client` pub async fn find_user(client: &Client, id: i32) -> Result<User, AppError> { let rows = client |