This is an automated email from the ASF dual-hosted git repository. dahn pushed a commit to branch 4.20 in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit 5ee61c226a377932a7361e84940778804ca7dee5 Merge: b3dc402aa8f 52584d93dc7 Author: Daan Hoogland <d...@onecht.net> AuthorDate: Wed Dec 4 13:04:18 2024 +0100 Merge branch '4.19' into 4.20 .../com/cloud/projects/dao/ProjectAccountDao.java | 2 + .../cloud/projects/dao/ProjectAccountDaoImpl.java | 11 ++++ .../com/cloud/upgrade/dao/Upgrade41910to41920.java | 66 ++++++++++++++++++++++ .../META-INF/db/schema-41910to41920-cleanup.sql | 23 ++++++++ .../resources/META-INF/db/schema-41910to41920.sql | 20 +++++++ .../utils/crypt/EncryptionSecretKeyChanger.java | 2 +- .../java/com/cloud/user/AccountManagerImpl.java | 8 +++ .../com/cloud/user/AccountManagerImplTest.java | 30 ++++++++++ 8 files changed, 161 insertions(+), 1 deletion(-) diff --cc engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDaoImpl.java index 8947cc600b3,9adb1a9e9b3..b6eb6d44cea --- a/engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDaoImpl.java @@@ -192,6 -194,17 +192,17 @@@ public class ProjectAccountDaoImpl exte } } + @Override + public void removeUserFromProjects(long userId) { + SearchCriteria<ProjectAccountVO> sc = AllFieldsSearch.create(); + sc.setParameters("userId", userId); + + int removedCount = remove(sc); + if (removedCount > 0) { - s_logger.debug(String.format("Removed user [%s] from %s project(s).", userId, removedCount)); ++ logger.debug(String.format("Removed user [%s] from %s project(s).", userId, removedCount)); + } + } + @Override public boolean canUserModifyProject(long projectId, long accountId, long userId) { SearchCriteria<ProjectAccountVO> sc = AllFieldsSearch.create(); diff --cc server/src/main/java/com/cloud/user/AccountManagerImpl.java index fa177428e51,c21d8b830dd..bea799944be --- a/server/src/main/java/com/cloud/user/AccountManagerImpl.java +++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java @@@ -1514,6 -1475,12 +1516,12 @@@ public class AccountManagerImpl extend throw new InvalidParameterValueException("Password cannot be empty or blank."); } + User.Source userSource = user.getSource(); + if (userSource == User.Source.SAML2 || userSource == User.Source.SAML2DISABLED || userSource == User.Source.LDAP) { - s_logger.warn(String.format("Unable to update the password for user [%d], as its source is [%s].", user.getId(), user.getSource().toString())); ++ logger.warn(String.format("Unable to update the password for user [%d], as its source is [%s].", user.getId(), user.getSource().toString())); + throw new InvalidParameterValueException("CloudStack does not support updating passwords for SAML or LDAP users. Please contact your cloud administrator for assistance."); + } + passwordPolicy.verifyIfPasswordCompliesWithPasswordPolicies(newPassword, user.getUsername(), getAccount(user.getAccountId()).getDomainId()); Account callingAccount = getCurrentCallingAccount(); diff --cc server/src/test/java/com/cloud/user/AccountManagerImplTest.java index 11fc69c538c,a98d187b5a9..645c9e5aa67 --- a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java +++ b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java @@@ -871,9 -742,39 +871,39 @@@ public class AccountManagerImplTest ext Mockito.doThrow(new InvalidParameterValueException("")).when(passwordPolicyMock).verifyIfPasswordCompliesWithPasswordPolicies(Mockito.anyString(), Mockito.anyString(), Mockito.anyLong()); - accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword); + accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword, false); } + @Test(expected = InvalidParameterValueException.class) + public void validateUserPasswordAndUpdateIfNeededTestSaml2UserShouldNotBeAllowedToUpdateTheirPassword() { + String newPassword = "newPassword"; + String currentPassword = "theCurrentPassword"; + + Mockito.when(userVoMock.getSource()).thenReturn(User.Source.SAML2); + - accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword); ++ accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword, false); + } + + @Test(expected = InvalidParameterValueException.class) + public void validateUserPasswordAndUpdateIfNeededTestSaml2DisabledUserShouldNotBeAllowedToUpdateTheirPassword() { + String newPassword = "newPassword"; + String currentPassword = "theCurrentPassword"; + + Mockito.when(userVoMock.getSource()).thenReturn(User.Source.SAML2DISABLED); + - accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword); ++ accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword, false); + } + + @Test(expected = InvalidParameterValueException.class) + public void validateUserPasswordAndUpdateIfNeededTestLdapUserShouldNotBeAllowedToUpdateTheirPassword() { + String newPassword = "newPassword"; + String currentPassword = "theCurrentPassword"; + + Mockito.when(userVoMock.getSource()).thenReturn(User.Source.LDAP); + - accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword); ++ accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword, false); + } + private String configureUserMockAuthenticators(String newPassword) { accountManagerImpl._userPasswordEncoders = new ArrayList<>(); UserAuthenticator authenticatorMock1 = Mockito.mock(UserAuthenticator.class);