diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationWritePlatformServiceImpl.java index 6d9eeef92..d54088d48 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/registration/service/SelfServiceRegistrationWritePlatformServiceImpl.java @@ -286,7 +286,7 @@ public class SelfServiceRegistrationWritePlatformServiceImpl implements SelfServ List clients = new ArrayList<>(Arrays.asList(client)); User user = new User(selfServiceRegistration.getUsername(), selfServiceRegistration.getPassword(), authorities); AppUser appUser = new AppUser(client.getOffice(), user, allRoles, selfServiceRegistration.getEmail(), client.getFirstname(), - client.getLastname(), null, passwordNeverExpire, isSelfServiceUser, clients); + client.getLastname(), null, passwordNeverExpire, isSelfServiceUser, clients, null); this.userDomainService.create(appUser, true); return appUser; diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java index 449ec233e..a88611a13 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java @@ -123,6 +123,9 @@ public class AppUser extends AbstractPersistableCustom implements PlatformUser { @JoinColumn(name = "appuser_id", referencedColumnName = "id", nullable = false) private Set appUserClientMappings = new HashSet<>(); + @Column(name = "cannot_change_password", nullable = true) + private Boolean cannotChangePassword; + public static AppUser fromJson(final Office userOffice, final Staff linkedStaff, final Set allRoles, final Collection clients, final JsonCommand command) { @@ -144,6 +147,7 @@ public class AppUser extends AbstractPersistableCustom implements PlatformUser { final boolean userAccountNonExpired = true; final boolean userCredentialsNonExpired = true; final boolean userAccountNonLocked = true; + final boolean cannotChangePassword = false; final Collection authorities = new ArrayList<>(); authorities.add(new SimpleGrantedAuthority("DUMMY_ROLE_NOT_USED_OR_PERSISTED_TO_AVOID_EXCEPTION")); @@ -158,7 +162,7 @@ public class AppUser extends AbstractPersistableCustom implements PlatformUser { final boolean isSelfServiceUser = command.booleanPrimitiveValueOfParameterNamed(AppUserConstants.IS_SELF_SERVICE_USER); return new AppUser(userOffice, user, allRoles, email, firstname, lastname, linkedStaff, passwordNeverExpire, isSelfServiceUser, - clients); + clients, cannotChangePassword); } protected AppUser() { @@ -169,7 +173,7 @@ public class AppUser extends AbstractPersistableCustom implements PlatformUser { public AppUser(final Office office, final User user, final Set roles, final String email, final String firstname, final String lastname, final Staff staff, final boolean passwordNeverExpire, final boolean isSelfServiceUser, - final Collection clients) { + final Collection clients, final Boolean cannotChangePassword) { this.office = office; this.email = email.trim(); this.username = user.getUsername().trim(); @@ -187,6 +191,7 @@ public class AppUser extends AbstractPersistableCustom implements PlatformUser { this.passwordNeverExpires = passwordNeverExpire; this.isSelfServiceUser = isSelfServiceUser; this.appUserClientMappings = createAppUserClientMappings(clients); + this.cannotChangePassword = cannotChangePassword; } public EnumOptionData organisationalRoleData() { @@ -198,6 +203,10 @@ public class AppUser extends AbstractPersistableCustom implements PlatformUser { } public void updatePassword(final String encodePassword) { + if (cannotChangePassword != null && cannotChangePassword == true) { + throw new NoAuthorizationException("Password of this user may not be modified"); + } + this.password = encodePassword; this.firstTimeLoginRemaining = false; this.lastTimePasswordUpdated = DateUtils.getDateOfTenant(); diff --git a/fineract-provider/src/main/resources/sql/migrations/core_db/V379__user_cannot_change_password.sql b/fineract-provider/src/main/resources/sql/migrations/core_db/V379__user_cannot_change_password.sql new file mode 100644 index 000000000..3dc7a25a2 --- /dev/null +++ b/fineract-provider/src/main/resources/sql/migrations/core_db/V379__user_cannot_change_password.sql @@ -0,0 +1,20 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. +-- + +ALTER TABLE m_appuser ADD COLUMN cannot_change_password BOOLEAN NULL DEFAULT NULL; diff --git a/fineract-provider/src/test/java/org/apache/fineract/notification/StorageTest.java b/fineract-provider/src/test/java/org/apache/fineract/notification/StorageTest.java index 614c9523e..4cc72b75e 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/notification/StorageTest.java +++ b/fineract-provider/src/test/java/org/apache/fineract/notification/StorageTest.java @@ -83,7 +83,7 @@ public class StorageTest { now); AppUser appUser = new AppUser(null, new User("J.J.", "", true, true, true, true, Collections.emptyList()), null, "user@com", "John", - "", null, false, false, null); + "", null, false, false, null, null); NotificationMapper notificationMapper = new NotificationMapper(notification, appUser, false, now);