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 hello_dao = dao_impl::HelloDaoImpl::new(pool.clone());
|
||||||
let permission_dao = dao_impl::PermissionDaoImpl::new(pool);
|
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 =
|
let hello_service =
|
||||||
service_impl::HelloServiceImpl::new(hello_dao.into(), permission_service.into());
|
service_impl::HelloServiceImpl::new(hello_dao.into(), permission_service.into());
|
||||||
rest::start_server(hello_service).await
|
rest::start_server(hello_service).await
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ pub trait PermissionService {
|
||||||
&self,
|
&self,
|
||||||
privilege: &str,
|
privilege: &str,
|
||||||
) -> impl Future<Output = Result<(), ServiceError>> + Send;
|
) -> impl Future<Output = Result<(), ServiceError>> + Send;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait UserService {
|
||||||
fn current_user(&self) -> impl Future<Output = Result<Arc<str>, ServiceError>> + Send;
|
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
|
where
|
||||||
PermissionDao: dao::PermissionDao + Send + Sync,
|
PermissionDao: dao::PermissionDao + Send + Sync,
|
||||||
|
UserService: service::UserService + Send + Sync,
|
||||||
{
|
{
|
||||||
permission_dao: Arc<PermissionDao>,
|
permission_dao: Arc<PermissionDao>,
|
||||||
|
user_service: Arc<UserService>,
|
||||||
}
|
}
|
||||||
impl<PermissionDao> PermissionServiceImpl<PermissionDao>
|
impl<PermissionDao, UserService> PermissionServiceImpl<PermissionDao, UserService>
|
||||||
where
|
where
|
||||||
PermissionDao: dao::PermissionDao + Send + Sync,
|
PermissionDao: dao::PermissionDao + Send + Sync,
|
||||||
|
UserService: service::UserService + Send + Sync,
|
||||||
{
|
{
|
||||||
pub fn new(permission_dao: Arc<PermissionDao>) -> Self {
|
pub fn new(permission_dao: Arc<PermissionDao>, user_service: Arc<UserService>) -> Self {
|
||||||
Self { permission_dao }
|
Self {
|
||||||
|
permission_dao,
|
||||||
|
user_service,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<PermissionDao> service::PermissionService for PermissionServiceImpl<PermissionDao>
|
impl<PermissionDao, UserService> service::PermissionService
|
||||||
|
for PermissionServiceImpl<PermissionDao, UserService>
|
||||||
where
|
where
|
||||||
PermissionDao: dao::PermissionDao + Send + Sync,
|
PermissionDao: dao::PermissionDao + Send + Sync,
|
||||||
|
UserService: service::UserService + Send + Sync,
|
||||||
{
|
{
|
||||||
async fn check_permission(&self, privilege: &str) -> Result<(), service::ServiceError> {
|
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
|
if self
|
||||||
.permission_dao
|
.permission_dao
|
||||||
.has_privilege(current_user.as_ref(), privilege)
|
.has_privilege(current_user.as_ref(), privilege)
|
||||||
|
|
@ -64,7 +72,11 @@ where
|
||||||
Err(service::ServiceError::Forbidden)
|
Err(service::ServiceError::Forbidden)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct UserServiceDev;
|
||||||
|
|
||||||
|
impl service::UserService for UserServiceDev {
|
||||||
async fn current_user(&self) -> Result<Arc<str>, service::ServiceError> {
|
async fn current_user(&self) -> Result<Arc<str>, service::ServiceError> {
|
||||||
Ok("DEVUSER".into())
|
Ok("DEVUSER".into())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue