From 691eccc2a41d18d99a3a014ac7df6d9635f5b011 Mon Sep 17 00:00:00 2001 From: Simon Goller Date: Sun, 28 Apr 2024 16:01:18 +0200 Subject: [PATCH] Create service and DAO layer for user-role-privilege system --- dao/src/lib.rs | 40 +++ dao_impl/src/lib.rs | 151 ++++++++++- service/src/lib.rs | 53 ++++ service_impl/src/lib.rs | 577 ++++++++++++++++++++++++++++++++++++++-- 4 files changed, 795 insertions(+), 26 deletions(-) diff --git a/dao/src/lib.rs b/dao/src/lib.rs index ae439ac..e9a1439 100644 --- a/dao/src/lib.rs +++ b/dao/src/lib.rs @@ -16,8 +16,48 @@ pub trait HelloDao { async fn get_hello(&self) -> Result, DaoError>; } +#[derive(Debug, PartialEq, Eq)] +pub struct UserEntity { + pub name: Arc, +} +#[derive(Debug, PartialEq, Eq)] +pub struct RoleEntity { + pub name: Arc, +} + +#[derive(Debug, PartialEq, Eq)] +pub struct PrivilegeEntity { + pub name: Arc, +} + #[automock] #[async_trait] pub trait PermissionDao { async fn has_privilege(&self, user: &str, privilege: &str) -> Result; + + async fn create_user(&self, user: &UserEntity, process: &str) -> Result<(), DaoError>; + async fn all_users(&self) -> Result, DaoError>; + async fn delete_user(&self, username: &str) -> Result<(), DaoError>; + + async fn create_role(&self, role: &RoleEntity, process: &str) -> Result<(), DaoError>; + async fn all_roles(&self) -> Result, DaoError>; + async fn delete_role(&self, rolename: &str) -> Result<(), DaoError>; + + async fn create_privilege( + &self, + privilege: &PrivilegeEntity, + process: &str, + ) -> Result<(), DaoError>; + async fn all_privileges(&self) -> Result, DaoError>; + async fn delete_privilege(&self, privilege: &str) -> Result<(), DaoError>; + + async fn add_user_role(&self, user: &str, role: &str, process: &str) -> Result<(), DaoError>; + async fn add_role_privilege( + &self, + role: &str, + privilege: &str, + process: &str, + ) -> Result<(), DaoError>; + async fn delete_role_privilege(&self, role: &str, privilege: &str) -> Result<(), DaoError>; + async fn delete_user_role(&self, user: &str, role: &str) -> Result<(), DaoError>; } diff --git a/dao_impl/src/lib.rs b/dao_impl/src/lib.rs index c219518..0e283ca 100644 --- a/dao_impl/src/lib.rs +++ b/dao_impl/src/lib.rs @@ -2,7 +2,16 @@ use std::sync::Arc; use async_trait::async_trait; use dao::DaoError; -use sqlx::{query, SqlitePool}; +use sqlx::{query, query_as, SqlitePool}; + +pub trait ResultDbErrorExt { + fn map_db_error(self) -> Result; +} +impl ResultDbErrorExt for Result { + fn map_db_error(self) -> Result { + self.map_err(|err| DaoError::DatabaseQueryError(Box::new(err))) + } +} pub struct HelloDaoImpl { pool: Arc, @@ -48,7 +57,145 @@ impl dao::PermissionDao for PermissionDaoImpl { ) .fetch_all(self.pool.as_ref()) .await - .map_err(|err| DaoError::DatabaseQueryError(Box::new(err)))?; + .map_db_error()?; Ok(result[0].results > 0) } + + async fn create_user(&self, user: &dao::UserEntity, process: &str) -> Result<(), DaoError> { + let name = user.name.as_ref(); + query!( + r"INSERT INTO user (name, update_process) VALUES (?, ?)", + name, + process + ) + .execute(self.pool.as_ref()) + .await + .map_db_error()?; + Ok(()) + } + async fn all_users(&self) -> Result, DaoError> { + Ok(query_as!(dao::UserEntity, r"SELECT name FROM user") + .fetch_all(self.pool.as_ref()) + .await + .map(Arc::<[dao::UserEntity]>::from) + .map_err(|err| DaoError::DatabaseQueryError(Box::new(err)))?) + } + async fn delete_user(&self, username: &str) -> Result<(), DaoError> { + query!(r"DELETE FROM user WHERE name = ?", username) + .execute(self.pool.as_ref()) + .await + .map_db_error()?; + Ok(()) + } + + async fn create_role(&self, role: &dao::RoleEntity, process: &str) -> Result<(), DaoError> { + let name = role.name.as_ref(); + query!( + "INSERT INTO role (name, update_process) VALUES (?, ?)", + name, + process + ) + .execute(self.pool.as_ref()) + .await + .map_db_error()?; + Ok(()) + } + async fn all_roles(&self) -> Result, DaoError> { + Ok(query_as!(dao::RoleEntity, r"SELECT name FROM role") + .fetch_all(self.pool.as_ref()) + .await + .map(Arc::<[dao::RoleEntity]>::from) + .map_db_error()?) + } + async fn delete_role(&self, rolename: &str) -> Result<(), DaoError> { + query!(r"DELETE FROM role WHERE name = ?", rolename) + .execute(self.pool.as_ref()) + .await + .map_db_error()?; + Ok(()) + } + + async fn create_privilege( + &self, + privilege: &dao::PrivilegeEntity, + process: &str, + ) -> Result<(), DaoError> { + let name = privilege.name.as_ref(); + query!( + r"INSERT INTO privilege (name, update_process) VALUES (?, ?)", + name, + process, + ) + .execute(self.pool.as_ref()) + .await + .map_db_error()?; + Ok(()) + } + async fn all_privileges(&self) -> Result, DaoError> { + Ok( + query_as!(dao::PrivilegeEntity, r"SELECT name FROM privilege") + .fetch_all(self.pool.as_ref()) + .await + .map(Arc::<[dao::PrivilegeEntity]>::from) + .map_db_error()?, + ) + } + async fn delete_privilege(&self, privilege: &str) -> Result<(), DaoError> { + query!(r"DELETE FROM privilege WHERE name = ?", privilege) + .execute(self.pool.as_ref()) + .await + .map_db_error()?; + Ok(()) + } + + async fn add_user_role(&self, user: &str, role: &str, process: &str) -> Result<(), DaoError> { + query!( + r"INSERT INTO user_role (user_name, role_name, update_process) VALUES (?, ?, ?)", + user, + role, + process, + ) + .execute(self.pool.as_ref()) + .await + .map_db_error()?; + Ok(()) + } + async fn add_role_privilege( + &self, + role: &str, + privilege: &str, + process: &str, + ) -> Result<(), DaoError> { + query!( + r"INSERT INTO role_privilege (role_name, privilege_name, update_process) VALUES (?, ?, ?)", + role, + privilege, + process, + ).execute(self.pool.as_ref()) + .await + .map_db_error()?; + Ok(()) + } + async fn delete_role_privilege(&self, role: &str, privilege: &str) -> Result<(), DaoError> { + query!( + r"DELETE FROM role_privilege WHERE role_name = ? AND privilege_name = ?", + role, + privilege + ) + .execute(self.pool.as_ref()) + .await + .map_db_error()?; + Ok(()) + } + async fn delete_user_role(&self, user: &str, role: &str) -> Result<(), DaoError> { + query!( + r"DELETE FROM user_role WHERE user_name = ? AND role_name = ?", + user, + role, + ) + .execute(self.pool.as_ref()) + .await + .map_db_error()?; + Ok(()) + } } diff --git a/service/src/lib.rs b/service/src/lib.rs index a9c22aa..67d2d00 100644 --- a/service/src/lib.rs +++ b/service/src/lib.rs @@ -17,10 +17,63 @@ pub trait HelloService { fn hello(&self) -> impl Future, ServiceError>> + Send; } +#[derive(Debug, PartialEq, Eq)] +pub struct User { + pub name: Arc, +} +impl From<&dao::UserEntity> for User { + fn from(user: &dao::UserEntity) -> Self { + Self { + name: user.name.clone(), + } + } +} + +#[derive(Debug, PartialEq, Eq)] +pub struct Role { + pub name: Arc, +} +impl From<&dao::RoleEntity> for Role { + fn from(role: &dao::RoleEntity) -> Self { + Self { + name: role.name.clone(), + } + } +} + +#[derive(Debug, PartialEq, Eq)] +pub struct Privilege { + pub name: Arc, +} +impl From<&dao::PrivilegeEntity> for Privilege { + fn from(privilege: &dao::PrivilegeEntity) -> Self { + Self { + name: privilege.name.clone(), + } + } +} + #[automock] #[async_trait] pub trait PermissionService { async fn check_permission(&self, privilege: &str) -> Result<(), ServiceError>; + + async fn create_user(&self, user: &str) -> Result<(), ServiceError>; + async fn delete_user(&self, user: &str) -> Result<(), ServiceError>; + async fn get_all_users(&self) -> Result, ServiceError>; + + async fn create_role(&self, role: &str) -> Result<(), ServiceError>; + async fn delete_role(&self, role: &str) -> Result<(), ServiceError>; + async fn get_all_roles(&self) -> Result, ServiceError>; + + async fn create_privilege(&self, privilege: &str) -> Result<(), ServiceError>; + async fn delete_privilege(&self, privilege: &str) -> Result<(), ServiceError>; + async fn get_all_privileges(&self) -> Result, ServiceError>; + + async fn add_user_role(&self, user: &str, role: &str) -> Result<(), ServiceError>; + async fn add_role_privilege(&self, role: &str, privilege: &str) -> Result<(), ServiceError>; + async fn delete_role_privilege(&self, role: &str, privilege: &str) -> Result<(), ServiceError>; + async fn delete_user_role(&self, user: &str, role: &str) -> Result<(), ServiceError>; } #[automock] diff --git a/service_impl/src/lib.rs b/service_impl/src/lib.rs index 431e083..a54c56b 100644 --- a/service_impl/src/lib.rs +++ b/service_impl/src/lib.rs @@ -56,6 +56,8 @@ where } } +const PERMISSION_SERVICE_PROCESS: &str = "permission-service"; + #[async_trait] impl service::PermissionService for PermissionServiceImpl @@ -75,6 +77,123 @@ where Err(service::ServiceError::Forbidden) } } + + async fn create_user(&self, user: &str) -> Result<(), service::ServiceError> { + self.check_permission("admin").await?; + self.permission_dao + .create_user( + &dao::UserEntity { name: user.into() }, + PERMISSION_SERVICE_PROCESS, + ) + .await?; + Ok(()) + } + async fn delete_user(&self, user: &str) -> Result<(), service::ServiceError> { + self.check_permission("admin").await?; + self.permission_dao.delete_user(user).await?; + Ok(()) + } + + async fn get_all_users(&self) -> Result, service::ServiceError> { + self.check_permission("admin").await?; + Ok(self + .permission_dao + .all_users() + .await? + .into_iter() + .map(service::User::from) + .collect()) + } + + async fn create_role(&self, role: &str) -> Result<(), service::ServiceError> { + self.check_permission("admin").await?; + self.permission_dao + .create_role( + &dao::RoleEntity { name: role.into() }, + PERMISSION_SERVICE_PROCESS, + ) + .await?; + Ok(()) + } + async fn delete_role(&self, role: &str) -> Result<(), service::ServiceError> { + self.check_permission("admin").await?; + self.permission_dao.delete_role(role).await?; + Ok(()) + } + async fn get_all_roles(&self) -> Result, service::ServiceError> { + self.check_permission("admin").await?; + Ok(self + .permission_dao + .all_roles() + .await? + .iter() + .map(service::Role::from) + .collect()) + } + + async fn create_privilege(&self, privilege: &str) -> Result<(), service::ServiceError> { + self.check_permission("admin").await?; + self.permission_dao + .create_privilege( + &dao::PrivilegeEntity { + name: privilege.into(), + }, + PERMISSION_SERVICE_PROCESS, + ) + .await?; + Ok(()) + } + + async fn delete_privilege(&self, privilege: &str) -> Result<(), service::ServiceError> { + self.check_permission("admin").await?; + self.permission_dao.delete_privilege(privilege).await?; + Ok(()) + } + async fn get_all_privileges(&self) -> Result, service::ServiceError> { + self.check_permission("admin").await?; + Ok(self + .permission_dao + .all_privileges() + .await? + .iter() + .map(service::Privilege::from) + .collect()) + } + + async fn add_user_role(&self, user: &str, role: &str) -> Result<(), service::ServiceError> { + self.check_permission("admin").await?; + self.permission_dao + .add_user_role(user, role, PERMISSION_SERVICE_PROCESS) + .await?; + Ok(()) + } + async fn add_role_privilege( + &self, + role: &str, + privilege: &str, + ) -> Result<(), service::ServiceError> { + self.check_permission("admin").await?; + self.permission_dao + .add_role_privilege(role, privilege, PERMISSION_SERVICE_PROCESS) + .await?; + Ok(()) + } + async fn delete_role_privilege( + &self, + role: &str, + privilege: &str, + ) -> Result<(), service::ServiceError> { + self.check_permission("admin").await?; + self.permission_dao + .delete_role_privilege(role, privilege) + .await?; + Ok(()) + } + async fn delete_user_role(&self, user: &str, role: &str) -> Result<(), service::ServiceError> { + self.check_permission("admin").await?; + self.permission_dao.delete_user_role(user, role).await?; + Ok(()) + } } pub struct UserServiceDev; @@ -114,6 +233,14 @@ mod tests { ); } + fn test_forbidden(result: &Result) { + if let Err(service::ServiceError::Forbidden) = result { + // All good + } else { + panic!("Expected forbidden error"); + } + } + #[tokio::test] async fn test_get_hello_no_permission() { let hello_dao = dao::MockHelloDao::new(); @@ -126,25 +253,29 @@ mod tests { let hello_service = HelloServiceImpl::new(Arc::new(hello_dao), Arc::new(permission_service)); - if let Err(service::ServiceError::Forbidden) = hello_service.hello().await { - // All good - } else { - panic!("Expected forbidden error"); - } + test_forbidden(&hello_service.hello().await); } - #[tokio::test] - async fn test_check_permission() { + fn generate_dependencies_mocks_permission( + grant: bool, + privilege: &'static str, + ) -> (dao::MockPermissionDao, service::MockUserService) { let mut permission_dao = dao::MockPermissionDao::new(); permission_dao .expect_has_privilege() - .with(eq("DEVUSER"), eq("hello")) - .returning(|_, _| Ok(true)); + .with(eq("DEVUSER"), eq(privilege)) + .returning(move |_, _| Ok(grant)); let mut user_service = service::MockUserService::new(); user_service .expect_current_user() .returning(|| Ok("DEVUSER".into())); + (permission_dao, user_service) + } + + #[tokio::test] + async fn test_check_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(true, "hello"); let permission_service = PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); @@ -154,25 +285,12 @@ mod tests { #[tokio::test] async fn test_check_permission_denied() { - let mut permission_dao = dao::MockPermissionDao::new(); - permission_dao - .expect_has_privilege() - .with(eq("DEVUSER"), eq("hello")) - .returning(|_, _| Ok(false)); - - let mut user_service = service::MockUserService::new(); - user_service - .expect_current_user() - .returning(|| Ok("DEVUSER".into())); + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "hello"); let permission_service = PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); let result = permission_service.check_permission("hello").await; - if let Err(service::ServiceError::Forbidden) = result { - // All good - } else { - panic!("Expected forbidden error"); - } + test_forbidden(&result); } #[tokio::test] @@ -184,4 +302,415 @@ mod tests { user_service.current_user().await.unwrap().as_ref() ); } + + #[tokio::test] + async fn test_create_user() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao + .expect_create_user() + .with( + eq(dao::UserEntity { + name: "testuser".into(), + }), + eq("permission-service"), + ) + .times(1) + .returning(|_, _| Ok(())); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + permission_service + .create_user("testuser") + .await + .expect("Extected successful user creation"); + } + + #[tokio::test] + async fn test_create_user_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden(&permission_service.create_user("testuser").await); + } + + #[tokio::test] + async fn test_delete_user() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao + .expect_delete_user() + .with(eq("testuser")) + .times(1) + .returning(|_| Ok(())); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + + permission_service + .delete_user("testuser") + .await + .expect("Expected successful delete"); + } + #[tokio::test] + async fn test_delete_user_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden(&permission_service.delete_user("testuser").await); + } + + #[tokio::test] + async fn test_create_role() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao + .expect_create_role() + .with( + eq(dao::RoleEntity { + name: "testrole".into(), + }), + eq("permission-service"), + ) + .times(1) + .returning(|_, _| Ok(())); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + permission_service + .create_role("testrole") + .await + .expect("Extected successful role creation"); + } + + #[tokio::test] + async fn test_create_role_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden(&permission_service.create_role("testrole").await); + } + + #[tokio::test] + async fn test_delete_role() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao + .expect_delete_role() + .with(eq("testrole")) + .times(1) + .returning(|_| Ok(())); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + + permission_service + .delete_role("testrole") + .await + .expect("Expected successful delete"); + } + + #[tokio::test] + async fn test_delete_role_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden(&permission_service.delete_role("testrole").await); + } + + #[tokio::test] + async fn test_create_privilege() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao + .expect_create_privilege() + .with( + eq(dao::PrivilegeEntity { + name: "testprivilege".into(), + }), + eq("permission-service"), + ) + .times(1) + .returning(|_, _| Ok(())); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + + permission_service + .create_privilege("testprivilege") + .await + .expect("Extected successful privilege creation"); + } + #[tokio::test] + async fn test_create_privilege_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden(&permission_service.create_privilege("testprivilege").await); + } + + #[tokio::test] + async fn test_delete_privilege() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao + .expect_delete_privilege() + .with(eq("testprivilege")) + .times(1) + .returning(|_| Ok(())); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + + permission_service + .delete_privilege("testprivilege") + .await + .expect("Expected successful delete"); + } + + #[tokio::test] + async fn test_delete_privilege_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden(&permission_service.delete_privilege("testprivilege").await); + } + + #[tokio::test] + async fn test_add_user_role() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao + .expect_add_user_role() + .with(eq("testuser"), eq("testrole"), eq("permission-service")) + .times(1) + .returning(|_, _, _| Ok(())); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + + permission_service + .add_user_role("testuser", "testrole") + .await + .expect("Extected successful user role creation"); + } + + #[tokio::test] + async fn test_add_user_role_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden( + &permission_service + .add_user_role("testuser", "testrole") + .await, + ); + } + + #[tokio::test] + async fn test_add_role_privilege() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao + .expect_add_role_privilege() + .with( + eq("testrole"), + eq("testprivilege"), + eq("permission-service"), + ) + .times(1) + .returning(|_, _, _| Ok(())); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + + permission_service + .add_role_privilege("testrole", "testprivilege") + .await + .expect("Extected successful role privilege creation"); + } + + #[tokio::test] + async fn test_add_role_privilege_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden( + &permission_service + .add_role_privilege("testrole", "testprivilege") + .await, + ); + } + + #[tokio::test] + async fn test_delete_role_privilege() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao + .expect_delete_role_privilege() + .with(eq("testrole"), eq("testprivilege")) + .times(1) + .returning(|_, _| Ok(())); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + + permission_service + .delete_role_privilege("testrole", "testprivilege") + .await + .expect("Extected successful role privilege deletion"); + } + + #[tokio::test] + async fn test_delete_role_privilege_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden( + &permission_service + .delete_role_privilege("testrole", "testprivilege") + .await, + ); + } + + #[tokio::test] + async fn test_delete_user_role() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao + .expect_delete_user_role() + .with(eq("testuser"), eq("testrole")) + .times(1) + .returning(|_, _| Ok(())); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + + permission_service + .delete_user_role("testuser", "testrole") + .await + .expect("Extected successful user role deletion"); + } + + #[tokio::test] + async fn test_delete_user_role_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden( + &permission_service + .delete_user_role("testuser", "testrole") + .await, + ); + } + + #[tokio::test] + async fn test_all_roles() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao.expect_all_roles().times(1).returning(|| { + Ok(Arc::new([ + dao::RoleEntity { + name: "testrole".into(), + }, + dao::RoleEntity { + name: "testrole2".into(), + }, + ])) + }); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + + let all_roles = permission_service + .get_all_roles() + .await + .expect("Expected roles successfully"); + assert_eq!(all_roles.len(), 2); + assert_eq!(all_roles[0].name.as_ref(), "testrole"); + assert_eq!(all_roles[1].name.as_ref(), "testrole2"); + } + + #[tokio::test] + async fn test_all_roles_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden(&permission_service.get_all_roles().await); + } + + #[tokio::test] + async fn test_all_users() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao.expect_all_users().times(1).returning(|| { + Ok(Arc::new([ + dao::UserEntity { + name: "testuser".into(), + }, + dao::UserEntity { + name: "testuser2".into(), + }, + ])) + }); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + + let all_users = permission_service + .get_all_users() + .await + .expect("Expected users successfully"); + + assert_eq!(all_users.len(), 2); + assert_eq!(all_users[0].name.as_ref(), "testuser"); + assert_eq!(all_users[1].name.as_ref(), "testuser2"); + } + + #[tokio::test] + async fn test_all_users_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden(&permission_service.get_all_users().await); + } + + #[tokio::test] + async fn test_all_privileges() { + let (mut permission_dao, user_service) = + generate_dependencies_mocks_permission(true, "admin"); + permission_dao + .expect_all_privileges() + .times(1) + .returning(|| { + Ok(Arc::new([ + dao::PrivilegeEntity { + name: "testprivilege".into(), + }, + dao::PrivilegeEntity { + name: "testprivilege2".into(), + }, + ])) + }); + + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + + let all_privileges = permission_service + .get_all_privileges() + .await + .expect("Expected privileges successfully"); + + assert_eq!(all_privileges.len(), 2); + assert_eq!(all_privileges[0].name.as_ref(), "testprivilege"); + assert_eq!(all_privileges[1].name.as_ref(), "testprivilege2"); + } + + #[tokio::test] + async fn test_all_privileges_without_permission() { + let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "admin"); + let permission_service = + PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service)); + test_forbidden(&permission_service.get_all_privileges().await); + } }