Skip to content

Commit

Permalink
feat: [#615] authorization layer added to the change password method …
Browse files Browse the repository at this point in the history
…of the user service
  • Loading branch information
mario-nt committed Aug 3, 2024
1 parent 543d804 commit e614e2f
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ pub async fn run(configuration: Configuration, api_version: &Version) -> Running
let profile_service = Arc::new(user::ProfileService::new(
configuration.clone(),
user_authentication_repository.clone(),
authorization_service.clone(),
));
let ban_service = Arc::new(user::BanService::new(
user_profile_repository.clone(),
Expand Down
3 changes: 3 additions & 0 deletions src/services/authorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub enum ACTION {
GetCanonicalInfoHash,
GenerateTorrentInfoListing,
GetTorrentInfo,
ChangePassword,
}

pub struct Service {
Expand Down Expand Up @@ -194,6 +195,7 @@ impl CasbinConfiguration {
admin, GetCanonicalInfoHash
admin, GenerateTorrentInfoListing
admin, GetTorrentInfo
admin, ChangePassword
registered, GetCategories
registered, GetImageByUrl
registered, GetPublicSettings
Expand All @@ -203,6 +205,7 @@ impl CasbinConfiguration {
registered, GetCanonicalInfoHash
registered, GenerateTorrentInfoListing
registered, GetTorrentInfo
registered, ChangePassword
guest, GetCategories
guest, GetTags
guest, GetAboutPage
Expand Down
19 changes: 17 additions & 2 deletions src/services/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,20 @@ impl RegistrationService {
pub struct ProfileService {
configuration: Arc<Configuration>,
user_authentication_repository: Arc<DbUserAuthenticationRepository>,
authorization_service: Arc<authorization::Service>,
}

impl ProfileService {
#[must_use]
pub fn new(configuration: Arc<Configuration>, user_repository: Arc<DbUserAuthenticationRepository>) -> Self {
pub fn new(
configuration: Arc<Configuration>,
user_repository: Arc<DbUserAuthenticationRepository>,
authorization_service: Arc<authorization::Service>,
) -> Self {
Self {
configuration,
user_authentication_repository: user_repository,
authorization_service,
}
}

Expand All @@ -223,7 +229,16 @@ impl ProfileService {
/// * `ServiceError::PasswordTooLong` if the supplied password is too long.
/// * An error if unable to successfully hash the password.
/// * An error if unable to change the password in the database.
pub async fn change_password(&self, user_id: UserId, change_password_form: &ChangePasswordForm) -> Result<(), ServiceError> {
pub async fn change_password(
&self,
user_id: UserId,
change_password_form: &ChangePasswordForm,
maybe_user_id: Option<UserId>,
) -> Result<(), ServiceError> {
self.authorization_service
.authorize(ACTION::ChangePassword, maybe_user_id)
.await?;

info!("changing user password for user ID: {user_id}");

let settings = self.configuration.settings.read().await;
Expand Down
8 changes: 7 additions & 1 deletion src/web/api/server/v1/contexts/user/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use serde::Deserialize;
use super::forms::{ChangePasswordForm, JsonWebToken, LoginForm, RegistrationForm};
use super::responses::{self};
use crate::common::AppData;
use crate::web::api::server::v1::extractors::optional_user_id::ExtractOptionalLoggedInUser;
use crate::web::api::server::v1::extractors::user_id::ExtractLoggedInUser;
use crate::web::api::server::v1::responses::OkResponseData;

Expand Down Expand Up @@ -133,10 +134,15 @@ pub async fn renew_token_handler(
#[allow(clippy::unused_async)]
pub async fn change_password_handler(
State(app_data): State<Arc<AppData>>,
ExtractOptionalLoggedInUser(maybe_user_id): ExtractOptionalLoggedInUser,
ExtractLoggedInUser(user_id): ExtractLoggedInUser,
extract::Json(change_password_form): extract::Json<ChangePasswordForm>,
) -> Response {
match app_data.profile_service.change_password(user_id, &change_password_form).await {
match app_data
.profile_service
.change_password(user_id, &change_password_form, maybe_user_id)
.await
{
Ok(()) => Json(OkResponseData {
data: format!("Password changed for user with ID: {user_id}"),
})
Expand Down

0 comments on commit e614e2f

Please sign in to comment.