Add set-role command
This commit is contained in:
parent
01f956b6ce
commit
1f9669ad7c
6 changed files with 71 additions and 1 deletions
|
@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Implemented roles & permissions.
|
||||
- Added "read-only user" role.
|
||||
- Added configuration option for automatic assigning of "read-only user" role after registration.
|
||||
- Added `set-role` command.
|
||||
|
||||
### Deprecated
|
||||
|
||||
|
|
|
@ -38,6 +38,12 @@ Set or change password:
|
|||
mitractl set-password <user-id> <password>
|
||||
```
|
||||
|
||||
Change user's role:
|
||||
|
||||
```shell
|
||||
mitractl set-role <user-id> <role-name>
|
||||
```
|
||||
|
||||
Delete profile:
|
||||
|
||||
```shell
|
||||
|
|
|
@ -39,7 +39,9 @@ use mitra::models::{
|
|||
get_invite_codes,
|
||||
get_user_by_id,
|
||||
set_user_password,
|
||||
set_user_role,
|
||||
},
|
||||
users::types::Role,
|
||||
};
|
||||
use mitra::monero::{
|
||||
helpers::check_expired_invoice,
|
||||
|
@ -70,6 +72,7 @@ pub enum SubCommand {
|
|||
GenerateInviteCode(GenerateInviteCode),
|
||||
ListInviteCodes(ListInviteCodes),
|
||||
SetPassword(SetPassword),
|
||||
SetRole(SetRole),
|
||||
RefetchActor(RefetchActor),
|
||||
DeleteProfile(DeleteProfile),
|
||||
DeletePost(DeletePost),
|
||||
|
@ -169,6 +172,25 @@ impl SetPassword {
|
|||
}
|
||||
}
|
||||
|
||||
/// Change user's role
|
||||
#[derive(Parser)]
|
||||
pub struct SetRole {
|
||||
id: Uuid,
|
||||
role: String,
|
||||
}
|
||||
|
||||
impl SetRole {
|
||||
pub async fn execute(
|
||||
&self,
|
||||
db_client: &impl DatabaseClient,
|
||||
) -> Result<(), Error> {
|
||||
let role = Role::from_name(&self.role)?;
|
||||
set_user_role(db_client, &self.id, role).await?;
|
||||
println!("role changed");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Re-fetch actor profile by actor ID
|
||||
#[derive(Parser)]
|
||||
pub struct RefetchActor {
|
||||
|
|
|
@ -32,6 +32,7 @@ async fn main() {
|
|||
SubCommand::GenerateInviteCode(cmd) => cmd.execute(db_client).await.unwrap(),
|
||||
SubCommand::ListInviteCodes(cmd) => cmd.execute(db_client).await.unwrap(),
|
||||
SubCommand::SetPassword(cmd) => cmd.execute(db_client).await.unwrap(),
|
||||
SubCommand::SetRole(cmd) => cmd.execute(db_client).await.unwrap(),
|
||||
SubCommand::RefetchActor(cmd) => cmd.execute(&config, db_client).await.unwrap(),
|
||||
SubCommand::DeleteProfile(cmd) => cmd.execute(&config, db_client).await.unwrap(),
|
||||
SubCommand::DeletePost(cmd) => cmd.execute(&config, db_client).await.unwrap(),
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::identity::{did::Did, did_pkh::DidPkh};
|
|||
use crate::models::profiles::queries::create_profile;
|
||||
use crate::models::profiles::types::{DbActorProfile, ProfileCreateData};
|
||||
use crate::utils::currencies::Currency;
|
||||
use super::types::{DbUser, User, UserCreateData};
|
||||
use super::types::{DbUser, Role, User, UserCreateData};
|
||||
use super::utils::generate_invite_code;
|
||||
|
||||
pub async fn create_invite_code(
|
||||
|
@ -154,6 +154,24 @@ pub async fn set_user_password(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn set_user_role(
|
||||
db_client: &impl DatabaseClient,
|
||||
user_id: &Uuid,
|
||||
role: Role,
|
||||
) -> Result<(), DatabaseError> {
|
||||
let updated_count = db_client.execute(
|
||||
"
|
||||
UPDATE user_account SET user_role = $1
|
||||
WHERE id = $2
|
||||
",
|
||||
&[&role, &user_id],
|
||||
).await?;
|
||||
if updated_count == 0 {
|
||||
return Err(DatabaseError::NotFound("user"));
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_user_by_id(
|
||||
db_client: &impl DatabaseClient,
|
||||
user_id: &Uuid,
|
||||
|
@ -307,4 +325,16 @@ mod tests {
|
|||
let result = create_user(db_client, another_user_data).await;
|
||||
assert!(matches!(result, Err(DatabaseError::AlreadyExists("user"))));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_set_user_role() {
|
||||
let db_client = &mut create_test_database().await;
|
||||
let user_data = UserCreateData::default();
|
||||
let user = create_user(db_client, user_data).await.unwrap();
|
||||
assert_eq!(user.role, Role::NormalUser);
|
||||
set_user_role(db_client, &user.id, Role::ReadOnlyUser).await.unwrap();
|
||||
let user = get_user_by_id(db_client, &user.id).await.unwrap();
|
||||
assert_eq!(user.role, Role::ReadOnlyUser);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,16 @@ impl Default for Role {
|
|||
}
|
||||
|
||||
impl Role {
|
||||
pub fn from_name(name: &str) -> Result<Self, ValidationError> {
|
||||
let role = match name {
|
||||
"user" => Self::NormalUser,
|
||||
"admin" => Self::Admin,
|
||||
"read_only_user" => Self::ReadOnlyUser,
|
||||
_ => return Err(ValidationError("unknown role")),
|
||||
};
|
||||
Ok(role)
|
||||
}
|
||||
|
||||
pub fn get_permissions(&self) -> Vec<Permission> {
|
||||
match self {
|
||||
Self::Guest => vec![],
|
||||
|
|
Loading…
Reference in a new issue