diff --git a/src/services/authentication.rs b/src/services/authentication.rs index e04342a4..170cac82 100644 --- a/src/services/authentication.rs +++ b/src/services/authentication.rs @@ -5,17 +5,18 @@ use argon2::{Argon2, PasswordHash, PasswordVerifier}; use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation}; use pbkdf2::Pbkdf2; -use super::user::{DbUserProfileRepository, DbUserRepository}; +use super::user::DbUserProfileRepository; use crate::config::Configuration; use crate::databases::database::{Database, Error}; use crate::errors::ServiceError; use crate::models::user::{UserAuthentication, UserClaims, UserCompact, UserId}; +use crate::services::user::Repository; use crate::utils::clock; pub struct Service { configuration: Arc, json_web_token: Arc, - user_repository: Arc, + user_repository: Arc>, user_profile_repository: Arc, user_authentication_repository: Arc, } @@ -24,7 +25,7 @@ impl Service { pub fn new( configuration: Arc, json_web_token: Arc, - user_repository: Arc, + user_repository: Arc>, user_profile_repository: Arc, user_authentication_repository: Arc, ) -> Self { diff --git a/src/services/category.rs b/src/services/category.rs index ec3e5ca2..b5b4523f 100644 --- a/src/services/category.rs +++ b/src/services/category.rs @@ -1,7 +1,7 @@ //! Category service. use std::sync::Arc; -use super::user::DbUserRepository; +use super::authorization::{self, ACTION}; use crate::databases::database::{Category, Database, Error as DatabaseError}; use crate::errors::ServiceError; use crate::models::category::CategoryId; @@ -9,15 +9,15 @@ use crate::models::user::UserId; pub struct Service { category_repository: Arc, - user_repository: Arc, + authorization_service: Arc, } impl Service { #[must_use] - pub fn new(category_repository: Arc, user_repository: Arc) -> Service { + pub fn new(category_repository: Arc, authorization_service: Arc) -> Service { Service { category_repository, - user_repository, + authorization_service, } } @@ -32,13 +32,9 @@ impl Service { /// * The category already exists. /// * There is a database error. pub async fn add_category(&self, category_name: &str, user_id: &UserId) -> Result { - let user = self.user_repository.get_compact(user_id).await?; - - // Check if user is administrator - // todo: extract authorization service - if !user.administrator { - return Err(ServiceError::Unauthorized); - } + self.authorization_service + .authorize(ACTION::AddCategory, Some(*user_id)) + .await?; let trimmed_name = category_name.trim(); @@ -70,13 +66,9 @@ impl Service { /// * The user does not have the required permissions. /// * There is a database error. pub async fn delete_category(&self, category_name: &str, user_id: &UserId) -> Result<(), ServiceError> { - let user = self.user_repository.get_compact(user_id).await?; - - // Check if user is administrator - // todo: extract authorization service - if !user.administrator { - return Err(ServiceError::Unauthorized); - } + self.authorization_service + .authorize(ACTION::DeleteCategory, Some(*user_id)) + .await?; match self.category_repository.delete(category_name).await { Ok(()) => Ok(()), diff --git a/src/services/proxy.rs b/src/services/proxy.rs index 9ea5ef3d..7ac2a475 100644 --- a/src/services/proxy.rs +++ b/src/services/proxy.rs @@ -10,18 +10,18 @@ use std::sync::Arc; use bytes::Bytes; -use super::user::DbUserRepository; use crate::cache::image::manager::{Error, ImageCacheService}; use crate::models::user::UserId; +use crate::services::user::Repository; pub struct Service { image_cache_service: Arc, - user_repository: Arc, + user_repository: Arc>, } impl Service { #[must_use] - pub fn new(image_cache_service: Arc, user_repository: Arc) -> Self { + pub fn new(image_cache_service: Arc, user_repository: Arc>) -> Self { Self { image_cache_service, user_repository, diff --git a/src/services/settings.rs b/src/services/settings.rs index a4b0e92e..d587fb9b 100644 --- a/src/services/settings.rs +++ b/src/services/settings.rs @@ -1,22 +1,22 @@ //! Settings service. use std::sync::Arc; -use super::user::DbUserRepository; +use super::authorization::{self, ACTION}; use crate::config::{Configuration, ConfigurationPublic, Settings}; use crate::errors::ServiceError; use crate::models::user::UserId; pub struct Service { configuration: Arc, - user_repository: Arc, + authorization_service: Arc, } impl Service { #[must_use] - pub fn new(configuration: Arc, user_repository: Arc) -> Service { + pub fn new(configuration: Arc, authorization_service: Arc) -> Service { Service { configuration, - user_repository, + authorization_service, } } @@ -26,13 +26,9 @@ impl Service { /// /// It returns an error if the user does not have the required permissions. pub async fn get_all(&self, user_id: &UserId) -> Result { - let user = self.user_repository.get_compact(user_id).await?; - - // Check if user is administrator - // todo: extract authorization service - if !user.administrator { - return Err(ServiceError::Unauthorized); - } + self.authorization_service + .authorize(ACTION::GetSettings, Some(*user_id)) + .await?; let torrust_index_configuration = self.configuration.get_all().await; @@ -45,13 +41,9 @@ impl Service { /// /// It returns an error if the user does not have the required permissions. pub async fn get_all_masking_secrets(&self, user_id: &UserId) -> Result { - let user = self.user_repository.get_compact(user_id).await?; - - // Check if user is administrator - // todo: extract authorization service - if !user.administrator { - return Err(ServiceError::Unauthorized); - } + self.authorization_service + .authorize(ACTION::GetSettingsSecret, Some(*user_id)) + .await?; let mut torrust_index_configuration = self.configuration.get_all().await; diff --git a/src/services/tag.rs b/src/services/tag.rs index fcbf56c3..e8684b52 100644 --- a/src/services/tag.rs +++ b/src/services/tag.rs @@ -1,7 +1,7 @@ //! Tag service. use std::sync::Arc; -use super::user::DbUserRepository; +use super::authorization::{self, ACTION}; use crate::databases::database::{Database, Error as DatabaseError, Error}; use crate::errors::ServiceError; use crate::models::torrent_tag::{TagId, TorrentTag}; @@ -9,15 +9,15 @@ use crate::models::user::UserId; pub struct Service { tag_repository: Arc, - user_repository: Arc, + authorization_service: Arc, } impl Service { #[must_use] - pub fn new(tag_repository: Arc, user_repository: Arc) -> Service { + pub fn new(tag_repository: Arc, authorization_service: Arc) -> Service { Service { tag_repository, - user_repository, + authorization_service, } } @@ -30,13 +30,7 @@ impl Service { /// * The user does not have the required permissions. /// * There is a database error. pub async fn add_tag(&self, tag_name: &str, user_id: &UserId) -> Result { - let user = self.user_repository.get_compact(user_id).await?; - - // Check if user is administrator - // todo: extract authorization service - if !user.administrator { - return Err(ServiceError::Unauthorized); - } + self.authorization_service.authorize(ACTION::AddTag, Some(*user_id)).await?; let trimmed_name = tag_name.trim(); @@ -62,13 +56,9 @@ impl Service { /// * The user does not have the required permissions. /// * There is a database error. pub async fn delete_tag(&self, tag_id: &TagId, user_id: &UserId) -> Result<(), ServiceError> { - let user = self.user_repository.get_compact(user_id).await?; - - // Check if user is administrator - // todo: extract authorization service - if !user.administrator { - return Err(ServiceError::Unauthorized); - } + self.authorization_service + .authorize(ACTION::DeleteTag, Some(*user_id)) + .await?; match self.tag_repository.delete(tag_id).await { Ok(()) => Ok(()), diff --git a/src/services/torrent.rs b/src/services/torrent.rs index 606f8550..b98ef90b 100644 --- a/src/services/torrent.rs +++ b/src/services/torrent.rs @@ -6,7 +6,6 @@ use serde_derive::{Deserialize, Serialize}; use url::Url; use super::category::DbCategoryRepository; -use super::user::DbUserRepository; use crate::config::{Configuration, TrackerMode}; use crate::databases::database::{Database, Error, Sorting}; use crate::errors::ServiceError; @@ -17,6 +16,7 @@ use crate::models::torrent::{Metadata, TorrentId, TorrentListing}; use crate::models::torrent_file::{DbTorrent, Torrent, TorrentFile}; use crate::models::torrent_tag::{TagId, TorrentTag}; use crate::models::user::UserId; +use crate::services::user::Repository; use crate::tracker::statistics_importer::StatisticsImporter; use crate::utils::parse_torrent::decode_and_validate_torrent_file; use crate::{tracker, AsCSV}; @@ -25,7 +25,7 @@ pub struct Index { configuration: Arc, tracker_statistics_importer: Arc, tracker_service: Arc, - user_repository: Arc, + user_repository: Arc>, category_repository: Arc, torrent_repository: Arc, torrent_info_hash_repository: Arc, @@ -81,7 +81,7 @@ impl Index { configuration: Arc, tracker_statistics_importer: Arc, tracker_service: Arc, - user_repository: Arc, + user_repository: Arc>, category_repository: Arc, torrent_repository: Arc, torrent_info_hash_repository: Arc,