From 82e89baeebd6c9cb84efce8478310917bb57362e Mon Sep 17 00:00:00 2001 From: Simon Goller Date: Tue, 30 Apr 2024 15:06:12 +0200 Subject: [PATCH] Restructuring: Move permission code in separate modules --- Cargo.lock | 1 + app/Cargo.toml | 9 +- app/src/main.rs | 28 +- dao/src/lib.rs | 54 +- dao/src/permission.rs | 52 ++ rest/src/permission.rs | 8 +- service/src/lib.rs | 67 +-- service/src/permission.rs | 65 +++ service_impl/src/lib.rs | 677 +---------------------- service_impl/src/permission.rs | 164 ++++++ service_impl/src/test/mod.rs | 1 + service_impl/src/test/permission_test.rs | 457 +++++++++++++++ 12 files changed, 799 insertions(+), 784 deletions(-) create mode 100644 dao/src/permission.rs create mode 100644 service/src/permission.rs create mode 100644 service_impl/src/permission.rs create mode 100644 service_impl/src/test/mod.rs create mode 100644 service_impl/src/test/permission_test.rs diff --git a/Cargo.lock b/Cargo.lock index c92621f..14ca3d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,6 +46,7 @@ checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" name = "app" version = "0.1.0" dependencies = [ + "dao", "dao_impl", "rest", "service_impl", diff --git a/app/Cargo.toml b/app/Cargo.toml index 35f1347..656822c 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -8,12 +8,15 @@ edition = "2021" [dependencies.rest] path = "../rest" -[dependencies.service_impl] -path = "../service_impl" - [dependencies.dao_impl] path = "../dao_impl" +[dependencies.dao] +path = "../dao" + +[dependencies.service_impl] +path = "../service_impl" + [dependencies.tokio] version = "1.37.0" features = ["full"] diff --git a/app/src/main.rs b/app/src/main.rs index f77a62e..e7d2832 100644 --- a/app/src/main.rs +++ b/app/src/main.rs @@ -49,6 +49,30 @@ impl RestStateImpl { } } +async fn create_dev_admin_user(pool: Arc) { + use dao::PermissionDao; + // On development create the DEVUSER and give it admin permissions. + let permission_dao = dao_impl::PermissionDaoImpl::new(pool); + + let users = permission_dao.all_users().await.expect("Expected users"); + let contains_admin_user = users.iter().any(|user| user.name.as_ref() == "DEVUSER"); + if !contains_admin_user { + permission_dao + .create_user( + &dao::UserEntity { + name: "DEVUSER".into(), + }, + "dev-first-start", + ) + .await + .expect("Expected being able to create the DEVUSER"); + permission_dao + .add_user_role("DEVUSER", "admin", "dev-first-start") + .await + .expect("Expected being able to make DEVUSER an admin"); + } +} + #[tokio::main] async fn main() { let pool = Arc::new( @@ -56,6 +80,8 @@ async fn main() { .await .expect("Could not connect to database"), ); - let rest_state = RestStateImpl::new(pool); + + let rest_state = RestStateImpl::new(pool.clone()); + create_dev_admin_user(pool.clone()).await; rest::start_server(rest_state).await } diff --git a/dao/src/lib.rs b/dao/src/lib.rs index e9a1439..c11d00f 100644 --- a/dao/src/lib.rs +++ b/dao/src/lib.rs @@ -4,6 +4,14 @@ use async_trait::async_trait; use mockall::automock; use thiserror::Error; +mod permission; + +pub use permission::MockPermissionDao; +pub use permission::PermissionDao; +pub use permission::PrivilegeEntity; +pub use permission::RoleEntity; +pub use permission::UserEntity; + #[derive(Error, Debug)] pub enum DaoError { #[error("Database query error: {0}")] @@ -15,49 +23,3 @@ pub enum DaoError { 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/src/permission.rs b/dao/src/permission.rs new file mode 100644 index 0000000..f5189af --- /dev/null +++ b/dao/src/permission.rs @@ -0,0 +1,52 @@ +use std::sync::Arc; + +use async_trait::async_trait; +use mockall::automock; + +use crate::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/rest/src/permission.rs b/rest/src/permission.rs index 0b9d12d..967df41 100644 --- a/rest/src/permission.rs +++ b/rest/src/permission.rs @@ -1,3 +1,4 @@ +use serde::{Deserialize, Serialize}; use std::sync::Arc; use axum::{ @@ -7,7 +8,6 @@ use axum::{ routing::{delete, get, post}, Json, Router, }; -use serde::{Deserialize, Serialize}; use crate::{error_handler, RestStateDef}; use service::PermissionService; @@ -243,7 +243,7 @@ pub async fn get_all_users(rest_state: State .get_all_users() .await? .iter() - .map(|u| User::from(u)) + .map(User::from) .collect(); Ok(Response::builder() .status(200) @@ -262,7 +262,7 @@ pub async fn get_all_roles(rest_state: State .get_all_roles() .await? .iter() - .map(|u| Role::from(u)) + .map(Role::from) .collect(); Ok(Response::builder() .status(200) @@ -281,7 +281,7 @@ pub async fn get_all_privileges(rest_state: State 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] #[async_trait] pub trait UserService { diff --git a/service/src/permission.rs b/service/src/permission.rs new file mode 100644 index 0000000..1be3152 --- /dev/null +++ b/service/src/permission.rs @@ -0,0 +1,65 @@ +use std::sync::Arc; + +use async_trait::async_trait; +use mockall::automock; + +use crate::ServiceError; + +#[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>; +} diff --git a/service_impl/src/lib.rs b/service_impl/src/lib.rs index 93e0c32..218bf2e 100644 --- a/service_impl/src/lib.rs +++ b/service_impl/src/lib.rs @@ -2,6 +2,12 @@ use std::sync::Arc; use async_trait::async_trait; +mod permission; +#[cfg(test)] +mod test; + +pub use permission::PermissionServiceImpl; + pub struct HelloServiceImpl where HelloDao: dao::HelloDao + Sync + Send, @@ -35,167 +41,6 @@ where } } -pub struct PermissionServiceImpl -where - PermissionDao: dao::PermissionDao + Send + Sync, - UserService: service::UserService + Send + Sync, -{ - permission_dao: Arc, - user_service: Arc, -} -impl PermissionServiceImpl -where - PermissionDao: dao::PermissionDao + Send + Sync, - UserService: service::UserService + Send + Sync, -{ - pub fn new(permission_dao: Arc, user_service: Arc) -> Self { - Self { - permission_dao, - user_service, - } - } -} - -const PERMISSION_SERVICE_PROCESS: &str = "permission-service"; - -#[async_trait] -impl service::PermissionService - for PermissionServiceImpl -where - PermissionDao: dao::PermissionDao + Send + Sync, - UserService: service::UserService + Send + Sync, -{ - async fn check_permission(&self, privilege: &str) -> Result<(), service::ServiceError> { - let current_user = self.user_service.current_user().await?; - if self - .permission_dao - .has_privilege(current_user.as_ref(), privilege) - .await? - { - Ok(()) - } else { - 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? - .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; #[async_trait] @@ -204,513 +49,3 @@ impl service::UserService for UserServiceDev { Ok("DEVUSER".into()) } } - -#[cfg(test)] -mod tests { - use super::*; - use mockall::predicate::eq; - use service::{HelloService, MockPermissionService, PermissionService}; - use tokio; - - #[tokio::test] - async fn test_get_hello_successful() { - let mut hello_dao = dao::MockHelloDao::new(); - hello_dao - .expect_get_hello() - .times(1) - .returning(|| Ok("Hello, world!".into())); - let mut permission_service = MockPermissionService::new(); - permission_service - .expect_check_permission() - .times(1) - .returning(|_| Ok(())); - - let hello_service = - HelloServiceImpl::new(Arc::new(hello_dao), Arc::new(permission_service)); - assert_eq!( - "Hello, world!", - hello_service.hello().await.unwrap().as_ref() - ); - } - - 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(); - - let mut permission_service = MockPermissionService::new(); - permission_service - .expect_check_permission() - .times(1) - .returning(|_| Err(service::ServiceError::Forbidden)); - - let hello_service = - HelloServiceImpl::new(Arc::new(hello_dao), Arc::new(permission_service)); - test_forbidden(&hello_service.hello().await); - } - - 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(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)); - let result = permission_service.check_permission("hello").await; - result.expect("Expected successful authorization"); - } - - #[tokio::test] - async fn test_check_permission_denied() { - 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; - test_forbidden(&result); - } - - #[tokio::test] - async fn test_user_service_dev() { - use service::UserService; - let user_service = UserServiceDev; - assert_eq!( - "DEVUSER", - 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); - } -} diff --git a/service_impl/src/permission.rs b/service_impl/src/permission.rs new file mode 100644 index 0000000..85d733c --- /dev/null +++ b/service_impl/src/permission.rs @@ -0,0 +1,164 @@ +use std::sync::Arc; + +use async_trait::async_trait; + +pub struct PermissionServiceImpl +where + PermissionDao: dao::PermissionDao + Send + Sync, + UserService: service::UserService + Send + Sync, +{ + permission_dao: Arc, + user_service: Arc, +} +impl PermissionServiceImpl +where + PermissionDao: dao::PermissionDao + Send + Sync, + UserService: service::UserService + Send + Sync, +{ + pub fn new(permission_dao: Arc, user_service: Arc) -> Self { + Self { + permission_dao, + user_service, + } + } +} + +const PERMISSION_SERVICE_PROCESS: &str = "permission-service"; + +#[async_trait] +impl service::PermissionService + for PermissionServiceImpl +where + PermissionDao: dao::PermissionDao + Send + Sync, + UserService: service::UserService + Send + Sync, +{ + async fn check_permission(&self, privilege: &str) -> Result<(), service::ServiceError> { + let current_user = self.user_service.current_user().await?; + if self + .permission_dao + .has_privilege(current_user.as_ref(), privilege) + .await? + { + Ok(()) + } else { + 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? + .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(()) + } +} diff --git a/service_impl/src/test/mod.rs b/service_impl/src/test/mod.rs new file mode 100644 index 0000000..3f46c57 --- /dev/null +++ b/service_impl/src/test/mod.rs @@ -0,0 +1 @@ +mod permission_test; diff --git a/service_impl/src/test/permission_test.rs b/service_impl/src/test/permission_test.rs new file mode 100644 index 0000000..24796b0 --- /dev/null +++ b/service_impl/src/test/permission_test.rs @@ -0,0 +1,457 @@ +use crate::*; +use mockall::predicate::eq; +use service::PermissionService; +use tokio; + +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(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) +} + +fn test_forbidden(result: &Result) { + if let Err(service::ServiceError::Forbidden) = result { + // All good + } else { + panic!("Expected forbidden error"); + } +} + +#[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)); + let result = permission_service.check_permission("hello").await; + result.expect("Expected successful authorization"); +} + +#[tokio::test] +async fn test_check_permission_denied() { + 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; + test_forbidden(&result); +} + +#[tokio::test] +async fn test_user_service_dev() { + use service::UserService; + let user_service = UserServiceDev; + assert_eq!( + "DEVUSER", + 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); +}