Return the username in a separate service
This allows us to use a service implementation which returns a dummy user during development and the actual authenticated user during production. It also simplifies tests.
This commit is contained in:
parent
789981ee92
commit
926ac006e7
3 changed files with 29 additions and 7 deletions
|
|
@ -12,7 +12,15 @@ async fn main() {
|
|||
let hello_dao = dao_impl::HelloDaoImpl::new(pool.clone());
|
||||
let permission_dao = dao_impl::PermissionDaoImpl::new(pool);
|
||||
|
||||
let permission_service = service_impl::PermissionServiceImpl::new(permission_dao.into());
|
||||
// Always authenticate with DEVUSER during development.
|
||||
// This is used to test the permission service locally without a login service.
|
||||
//
|
||||
// TODO: Implement a proper authentication service when used in produciton. Maybe
|
||||
// use differnet implementations on debug then on release. Or control it via a
|
||||
// feature.
|
||||
let user_service = service_impl::UserServiceDev;
|
||||
let permission_service =
|
||||
service_impl::PermissionServiceImpl::new(permission_dao.into(), user_service.into());
|
||||
let hello_service =
|
||||
service_impl::HelloServiceImpl::new(hello_dao.into(), permission_service.into());
|
||||
rest::start_server(hello_service).await
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ pub trait PermissionService {
|
|||
&self,
|
||||
privilege: &str,
|
||||
) -> impl Future<Output = Result<(), ServiceError>> + Send;
|
||||
}
|
||||
|
||||
pub trait UserService {
|
||||
fn current_user(&self) -> impl Future<Output = Result<Arc<str>, ServiceError>> + Send;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,27 +33,35 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub struct PermissionServiceImpl<PermissionDao>
|
||||
pub struct PermissionServiceImpl<PermissionDao, UserService>
|
||||
where
|
||||
PermissionDao: dao::PermissionDao + Send + Sync,
|
||||
UserService: service::UserService + Send + Sync,
|
||||
{
|
||||
permission_dao: Arc<PermissionDao>,
|
||||
user_service: Arc<UserService>,
|
||||
}
|
||||
impl<PermissionDao> PermissionServiceImpl<PermissionDao>
|
||||
impl<PermissionDao, UserService> PermissionServiceImpl<PermissionDao, UserService>
|
||||
where
|
||||
PermissionDao: dao::PermissionDao + Send + Sync,
|
||||
UserService: service::UserService + Send + Sync,
|
||||
{
|
||||
pub fn new(permission_dao: Arc<PermissionDao>) -> Self {
|
||||
Self { permission_dao }
|
||||
pub fn new(permission_dao: Arc<PermissionDao>, user_service: Arc<UserService>) -> Self {
|
||||
Self {
|
||||
permission_dao,
|
||||
user_service,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<PermissionDao> service::PermissionService for PermissionServiceImpl<PermissionDao>
|
||||
impl<PermissionDao, UserService> service::PermissionService
|
||||
for PermissionServiceImpl<PermissionDao, UserService>
|
||||
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.current_user().await?;
|
||||
let current_user = self.user_service.current_user().await?;
|
||||
if self
|
||||
.permission_dao
|
||||
.has_privilege(current_user.as_ref(), privilege)
|
||||
|
|
@ -64,7 +72,11 @@ where
|
|||
Err(service::ServiceError::Forbidden)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UserServiceDev;
|
||||
|
||||
impl service::UserService for UserServiceDev {
|
||||
async fn current_user(&self) -> Result<Arc<str>, service::ServiceError> {
|
||||
Ok("DEVUSER".into())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue