Create service and DAO layer for user-role-privilege system
This commit is contained in:
parent
ab260120f2
commit
691eccc2a4
4 changed files with 795 additions and 26 deletions
|
|
@ -16,8 +16,48 @@ pub trait HelloDao {
|
||||||
async fn get_hello(&self) -> Result<Arc<str>, DaoError>;
|
async fn get_hello(&self) -> Result<Arc<str>, DaoError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct UserEntity {
|
||||||
|
pub name: Arc<str>,
|
||||||
|
}
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct RoleEntity {
|
||||||
|
pub name: Arc<str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct PrivilegeEntity {
|
||||||
|
pub name: Arc<str>,
|
||||||
|
}
|
||||||
|
|
||||||
#[automock]
|
#[automock]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait PermissionDao {
|
pub trait PermissionDao {
|
||||||
async fn has_privilege(&self, user: &str, privilege: &str) -> Result<bool, DaoError>;
|
async fn has_privilege(&self, user: &str, privilege: &str) -> Result<bool, DaoError>;
|
||||||
|
|
||||||
|
async fn create_user(&self, user: &UserEntity, process: &str) -> Result<(), DaoError>;
|
||||||
|
async fn all_users(&self) -> Result<Arc<[UserEntity]>, 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<Arc<[RoleEntity]>, 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<Arc<[PrivilegeEntity]>, 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>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,16 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use dao::DaoError;
|
use dao::DaoError;
|
||||||
use sqlx::{query, SqlitePool};
|
use sqlx::{query, query_as, SqlitePool};
|
||||||
|
|
||||||
|
pub trait ResultDbErrorExt<T, E> {
|
||||||
|
fn map_db_error(self) -> Result<T, DaoError>;
|
||||||
|
}
|
||||||
|
impl<T, E: std::error::Error + 'static> ResultDbErrorExt<T, E> for Result<T, E> {
|
||||||
|
fn map_db_error(self) -> Result<T, DaoError> {
|
||||||
|
self.map_err(|err| DaoError::DatabaseQueryError(Box::new(err)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct HelloDaoImpl {
|
pub struct HelloDaoImpl {
|
||||||
pool: Arc<SqlitePool>,
|
pool: Arc<SqlitePool>,
|
||||||
|
|
@ -48,7 +57,145 @@ impl dao::PermissionDao for PermissionDaoImpl {
|
||||||
)
|
)
|
||||||
.fetch_all(self.pool.as_ref())
|
.fetch_all(self.pool.as_ref())
|
||||||
.await
|
.await
|
||||||
.map_err(|err| DaoError::DatabaseQueryError(Box::new(err)))?;
|
.map_db_error()?;
|
||||||
Ok(result[0].results > 0)
|
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<Arc<[dao::UserEntity]>, 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<Arc<[dao::RoleEntity]>, 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<Arc<[dao::PrivilegeEntity]>, 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(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,63 @@ pub trait HelloService {
|
||||||
fn hello(&self) -> impl Future<Output = Result<Arc<str>, ServiceError>> + Send;
|
fn hello(&self) -> impl Future<Output = Result<Arc<str>, ServiceError>> + Send;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct User {
|
||||||
|
pub name: Arc<str>,
|
||||||
|
}
|
||||||
|
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<str>,
|
||||||
|
}
|
||||||
|
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<str>,
|
||||||
|
}
|
||||||
|
impl From<&dao::PrivilegeEntity> for Privilege {
|
||||||
|
fn from(privilege: &dao::PrivilegeEntity) -> Self {
|
||||||
|
Self {
|
||||||
|
name: privilege.name.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[automock]
|
#[automock]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait PermissionService {
|
pub trait PermissionService {
|
||||||
async fn check_permission(&self, privilege: &str) -> Result<(), ServiceError>;
|
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<Arc<[User]>, 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<Arc<[Role]>, 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<Arc<[Privilege]>, 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]
|
#[automock]
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PERMISSION_SERVICE_PROCESS: &str = "permission-service";
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<PermissionDao, UserService> service::PermissionService
|
impl<PermissionDao, UserService> service::PermissionService
|
||||||
for PermissionServiceImpl<PermissionDao, UserService>
|
for PermissionServiceImpl<PermissionDao, UserService>
|
||||||
|
|
@ -75,6 +77,123 @@ where
|
||||||
Err(service::ServiceError::Forbidden)
|
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<Arc<[service::User]>, 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<Arc<[service::Role]>, 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<Arc<[service::Privilege]>, 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;
|
pub struct UserServiceDev;
|
||||||
|
|
@ -114,6 +233,14 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_forbidden<T>(result: &Result<T, service::ServiceError>) {
|
||||||
|
if let Err(service::ServiceError::Forbidden) = result {
|
||||||
|
// All good
|
||||||
|
} else {
|
||||||
|
panic!("Expected forbidden error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_get_hello_no_permission() {
|
async fn test_get_hello_no_permission() {
|
||||||
let hello_dao = dao::MockHelloDao::new();
|
let hello_dao = dao::MockHelloDao::new();
|
||||||
|
|
@ -126,25 +253,29 @@ mod tests {
|
||||||
|
|
||||||
let hello_service =
|
let hello_service =
|
||||||
HelloServiceImpl::new(Arc::new(hello_dao), Arc::new(permission_service));
|
HelloServiceImpl::new(Arc::new(hello_dao), Arc::new(permission_service));
|
||||||
if let Err(service::ServiceError::Forbidden) = hello_service.hello().await {
|
test_forbidden(&hello_service.hello().await);
|
||||||
// All good
|
|
||||||
} else {
|
|
||||||
panic!("Expected forbidden error");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
fn generate_dependencies_mocks_permission(
|
||||||
async fn test_check_permission() {
|
grant: bool,
|
||||||
|
privilege: &'static str,
|
||||||
|
) -> (dao::MockPermissionDao, service::MockUserService) {
|
||||||
let mut permission_dao = dao::MockPermissionDao::new();
|
let mut permission_dao = dao::MockPermissionDao::new();
|
||||||
permission_dao
|
permission_dao
|
||||||
.expect_has_privilege()
|
.expect_has_privilege()
|
||||||
.with(eq("DEVUSER"), eq("hello"))
|
.with(eq("DEVUSER"), eq(privilege))
|
||||||
.returning(|_, _| Ok(true));
|
.returning(move |_, _| Ok(grant));
|
||||||
|
|
||||||
let mut user_service = service::MockUserService::new();
|
let mut user_service = service::MockUserService::new();
|
||||||
user_service
|
user_service
|
||||||
.expect_current_user()
|
.expect_current_user()
|
||||||
.returning(|| Ok("DEVUSER".into()));
|
.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 =
|
let permission_service =
|
||||||
PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service));
|
PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service));
|
||||||
|
|
@ -154,25 +285,12 @@ mod tests {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_check_permission_denied() {
|
async fn test_check_permission_denied() {
|
||||||
let mut permission_dao = dao::MockPermissionDao::new();
|
let (permission_dao, user_service) = generate_dependencies_mocks_permission(false, "hello");
|
||||||
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_service =
|
let permission_service =
|
||||||
PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service));
|
PermissionServiceImpl::new(Arc::new(permission_dao), Arc::new(user_service));
|
||||||
let result = permission_service.check_permission("hello").await;
|
let result = permission_service.check_permission("hello").await;
|
||||||
if let Err(service::ServiceError::Forbidden) = result {
|
test_forbidden(&result);
|
||||||
// All good
|
|
||||||
} else {
|
|
||||||
panic!("Expected forbidden error");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
@ -184,4 +302,415 @@ mod tests {
|
||||||
user_service.current_user().await.unwrap().as_ref()
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue