From 0fd2a589eb297678e15d12400364594887a6fe98 Mon Sep 17 00:00:00 2001 From: filipriec Date: Fri, 11 Apr 2025 13:37:57 +0200 Subject: [PATCH] register with optional role in the post request --- common/proto/auth.proto | 1 + common/src/proto/descriptor.bin | Bin 21080 -> 21155 bytes common/src/proto/multieko2.auth.rs | 2 ++ server/src/auth/docs/role_added.txt | 37 +++++++++++++++++++++++++++ server/src/auth/handlers/register.rs | 14 ++++++++-- 5 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 server/src/auth/docs/role_added.txt diff --git a/common/proto/auth.proto b/common/proto/auth.proto index bcb30df..9c5221e 100644 --- a/common/proto/auth.proto +++ b/common/proto/auth.proto @@ -14,6 +14,7 @@ message RegisterRequest { string email = 2; string password = 3; string password_confirmation = 4; + string role = 5; } message AuthResponse { diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index edd4e4a718bd551e8735dbf8b1110e96421e9bdd..56166bc81dd70be68054b7e00b21e434d17978e8 100644 GIT binary patch delta 720 zcmX|8S%6ooxMi+1nui}^GG&B$)AxcVw1T;{k0ud=n8+eEj5{NR1 zgaidrUVws!px_B8sCWR*j3@4V=6-YTJ=gQ=l%1Th@5hGyweQR=_QifRA5yJJ9v-~e zFJ>*fxp?Bg&mU(0*y6LIOIosM%RVT6vJJ~O|GZEnWyGZxu}tYQ&77DyMHh-escRQX zKK&q~I8z|VM@dkAsN6FZiWj~k+ zcYa1C0cXHXmea1sxfYrIR^A!13Fp8w6$hLH&ytk3Jr0rES+(;hpKt*@51AMjjtH5! zmSxn8nVe~fOgCV|U8c$&R@?UX{rJ7{op6Y&Rk2BKi`?_dJ4qcJ`#+8#=iN9xh5pV!Z delta 675 zcmX|^WAM*2#vk{kV`Zaeic%E#en39D zgnB<6?uISS5D&$?!jf*9?XnO^X$7UiBk$%3YE zW>`S15Rn~(3eAcng~B#rsnnyaYRVQjvrD%!v$IQFdCTH>*Gm6n+fBu1oS!*C1;M{U z_bQ5EXmJ#^KFrsex^*`@*Frkn+_hFABo^nA_4Q+(<^2}Ne~I*gPp C%sb-% diff --git a/common/src/proto/multieko2.auth.rs b/common/src/proto/multieko2.auth.rs index ff60458..22bd8ff 100644 --- a/common/src/proto/multieko2.auth.rs +++ b/common/src/proto/multieko2.auth.rs @@ -9,6 +9,8 @@ pub struct RegisterRequest { pub password: ::prost::alloc::string::String, #[prost(string, tag = "4")] pub password_confirmation: ::prost::alloc::string::String, + #[prost(string, tag = "5")] + pub role: ::prost::alloc::string::String, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct AuthResponse { diff --git a/server/src/auth/docs/role_added.txt b/server/src/auth/docs/role_added.txt new file mode 100644 index 0000000..27072ff --- /dev/null +++ b/server/src/auth/docs/role_added.txt @@ -0,0 +1,37 @@ +❯ grpcurl -plaintext -d '{ + "username": "testuser_default_role", + "email": "default@example.com", + "password": "password", + "password_confirmation": "password" +}' localhost:50051 multieko2.auth.AuthService/Register +{ + "id": "73017288-af41-49d8-b4cb-2ac2109b38a1", + "username": "testuser_default_role", + "email": "default@example.com", + "role": "accountant" +} +❯ grpcurl -plaintext -d '{ + "username": "testuser_admin_role", + "email": "admin@example.com", + "password": "password", + "password_confirmation": "password", + "role": "admin" +}' localhost:50051 multieko2.auth.AuthService/Register +{ + "id": "9437e318-818b-4c34-822d-c2d6601b835e", + "username": "testuser_admin_role", + "email": "admin@example.com", + "role": "admin" +} +❯ grpcurl -plaintext -d '{ + "username": "testuser_invalid_role", + "email": "invalid@example.com", + "password": "password", + "password_confirmation": "password", + "role": "invalid_role_name" +}' localhost:50051 multieko2.auth.AuthService/Register +ERROR: + Code: InvalidArgument + Message: Invalid role specified: 'invalid_role_name' +╭─    ~/Doc/pr/multieko2/server    main +3 !1  +╰─ diff --git a/server/src/auth/handlers/register.rs b/server/src/auth/handlers/register.rs index d9dc761..e88c95b 100644 --- a/server/src/auth/handlers/register.rs +++ b/server/src/auth/handlers/register.rs @@ -5,6 +5,8 @@ use common::proto::multieko2::auth::{RegisterRequest, AuthResponse}; use crate::db::PgPool; use crate::auth::models::AuthError; +const DEFAULT_ROLE: &str = "accountant"; + pub async fn register( pool: &PgPool, payload: RegisterRequest, @@ -18,20 +20,28 @@ pub async fn register( let password_hash = hash(payload.password, DEFAULT_COST) .map_err(|e| Status::internal(AuthError::HashingError(e.to_string()).to_string()))?; + let role_to_insert = if payload.role.is_empty() { DEFAULT_ROLE } else { &payload.role }; + // Insert user let user = sqlx::query!( r#" INSERT INTO users (username, email, password_hash, role) - VALUES ($1, $2, $3, 'accountant') + VALUES ($1, $2, $3, $4) RETURNING id, username, email, role "#, payload.username, payload.email, - password_hash + password_hash, + role_to_insert ) .fetch_one(pool) .await .map_err(|e| { + if let Some(db_err) = e.as_database_error() { + if db_err.constraint() == Some("valid_roles") { + return Status::invalid_argument(format!("Invalid role specified: '{}'", role_to_insert)); + } + } if e.to_string().contains("duplicate key") { Status::already_exists(AuthError::UserExists.to_string()) } else {