FINERACT-2005: Prohibit password re-use with configurable global setting
This commit is contained in:
+1
@@ -80,6 +80,7 @@ public final class GlobalConfigurationConstants {
|
|||||||
public static final String ALLOWED_LOAN_STATUSES_FOR_EXTERNAL_ASSET_TRANSFER = "allowed-loan-statuses-for-external-asset-transfer";
|
public static final String ALLOWED_LOAN_STATUSES_FOR_EXTERNAL_ASSET_TRANSFER = "allowed-loan-statuses-for-external-asset-transfer";
|
||||||
public static final String ALLOWED_LOAN_STATUSES_OF_DELAYED_SETTLEMENT_FOR_EXTERNAL_ASSET_TRANSFER = "allowed-loan-statuses-of-delayed-settlement-for-external-asset-transfer";
|
public static final String ALLOWED_LOAN_STATUSES_OF_DELAYED_SETTLEMENT_FOR_EXTERNAL_ASSET_TRANSFER = "allowed-loan-statuses-of-delayed-settlement-for-external-asset-transfer";
|
||||||
public static final String ENABLE_ORIGINATOR_CREATION_DURING_LOAN_APPLICATION = "enable-originator-creation-during-loan-application";
|
public static final String ENABLE_ORIGINATOR_CREATION_DURING_LOAN_APPLICATION = "enable-originator-creation-during-loan-application";
|
||||||
|
public static final String PASSWORD_REUSE_CHECK_HISTORY_COUNT = "password-reuse-check-history-count";
|
||||||
|
|
||||||
private GlobalConfigurationConstants() {}
|
private GlobalConfigurationConstants() {}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -151,4 +151,6 @@ public interface ConfigurationDomainService {
|
|||||||
boolean isImmediateChargeAccrualPostMaturityEnabled();
|
boolean isImmediateChargeAccrualPostMaturityEnabled();
|
||||||
|
|
||||||
String getAssetOwnerTransferOustandingInterestStrategy();
|
String getAssetOwnerTransferOustandingInterestStrategy();
|
||||||
|
|
||||||
|
Integer getPasswordReuseRestrictionCount();
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -548,4 +548,15 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
|
|||||||
return getGlobalConfigurationPropertyData(
|
return getGlobalConfigurationPropertyData(
|
||||||
GlobalConfigurationConstants.ASSET_OWNER_TRANSFER_OUTSTANDING_INTEREST_CALCULATION_STRATEGY).getStringValue();
|
GlobalConfigurationConstants.ASSET_OWNER_TRANSFER_OUTSTANDING_INTEREST_CALCULATION_STRATEGY).getStringValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getPasswordReuseRestrictionCount() {
|
||||||
|
final GlobalConfigurationPropertyData property = getGlobalConfigurationPropertyData(
|
||||||
|
GlobalConfigurationConstants.PASSWORD_REUSE_CHECK_HISTORY_COUNT);
|
||||||
|
if (!property.isEnabled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Long value = property.getValue();
|
||||||
|
return value != null && value > 0 ? value.intValue() : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-7
@@ -32,6 +32,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||||
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
@@ -48,7 +49,6 @@ import org.apache.fineract.organisation.staff.domain.Staff;
|
|||||||
import org.apache.fineract.organisation.staff.domain.StaffRepositoryWrapper;
|
import org.apache.fineract.organisation.staff.domain.StaffRepositoryWrapper;
|
||||||
import org.apache.fineract.portfolio.client.domain.Client;
|
import org.apache.fineract.portfolio.client.domain.Client;
|
||||||
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
|
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
|
||||||
import org.apache.fineract.useradministration.api.AppUserApiConstant;
|
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
import org.apache.fineract.useradministration.domain.AppUserPreviousPassword;
|
import org.apache.fineract.useradministration.domain.AppUserPreviousPassword;
|
||||||
import org.apache.fineract.useradministration.domain.AppUserPreviousPasswordRepository;
|
import org.apache.fineract.useradministration.domain.AppUserPreviousPasswordRepository;
|
||||||
@@ -83,6 +83,7 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit
|
|||||||
private final AppUserPreviousPasswordRepository appUserPreviewPasswordRepository;
|
private final AppUserPreviousPasswordRepository appUserPreviewPasswordRepository;
|
||||||
private final StaffRepositoryWrapper staffRepositoryWrapper;
|
private final StaffRepositoryWrapper staffRepositoryWrapper;
|
||||||
private final ClientRepositoryWrapper clientRepositoryWrapper;
|
private final ClientRepositoryWrapper clientRepositoryWrapper;
|
||||||
|
private final ConfigurationDomainService configurationDomainService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -269,12 +270,20 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit
|
|||||||
AppUserPreviousPassword currentPasswordToSaveAsPreview = null;
|
AppUserPreviousPassword currentPasswordToSaveAsPreview = null;
|
||||||
|
|
||||||
if (passWordEncodedValue != null) {
|
if (passWordEncodedValue != null) {
|
||||||
PageRequest pageRequest = PageRequest.of(0, AppUserApiConstant.numberOfPreviousPasswords, Sort.Direction.DESC, "removalDate");
|
final Integer passwordReuseRestrictionCount = this.configurationDomainService.getPasswordReuseRestrictionCount();
|
||||||
final List<AppUserPreviousPassword> nLastUsedPasswords = this.appUserPreviewPasswordRepository.findByUserId(user.getId(),
|
if (passwordReuseRestrictionCount != null) {
|
||||||
pageRequest);
|
List<AppUserPreviousPassword> previousPasswords;
|
||||||
for (AppUserPreviousPassword aPreviewPassword : nLastUsedPasswords) {
|
if (passwordReuseRestrictionCount == 0) {
|
||||||
if (aPreviewPassword.getPassword().equals(passWordEncodedValue)) {
|
previousPasswords = this.appUserPreviewPasswordRepository.findByUserId(user.getId(),
|
||||||
throw new PasswordPreviouslyUsedException();
|
PageRequest.of(0, Integer.MAX_VALUE, Sort.Direction.DESC, "removalDate"));
|
||||||
|
} else {
|
||||||
|
PageRequest pageRequest = PageRequest.of(0, passwordReuseRestrictionCount, Sort.Direction.DESC, "removalDate");
|
||||||
|
previousPasswords = this.appUserPreviewPasswordRepository.findByUserId(user.getId(), pageRequest);
|
||||||
|
}
|
||||||
|
for (AppUserPreviousPassword aPreviewPassword : previousPasswords) {
|
||||||
|
if (aPreviewPassword.getPassword().equals(passWordEncodedValue)) {
|
||||||
|
throw new PasswordPreviouslyUsedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.useradministration.starter;
|
package org.apache.fineract.useradministration.starter;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformPasswordEncoder;
|
import org.apache.fineract.infrastructure.security.service.PlatformPasswordEncoder;
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
@@ -75,10 +76,10 @@ public class UserAdministrationConfiguration {
|
|||||||
PlatformPasswordEncoder platformPasswordEncoder, AppUserRepository appUserRepository,
|
PlatformPasswordEncoder platformPasswordEncoder, AppUserRepository appUserRepository,
|
||||||
OfficeRepositoryWrapper officeRepositoryWrapper, RoleRepository roleRepository, UserDataValidator fromApiJsonDeserializer,
|
OfficeRepositoryWrapper officeRepositoryWrapper, RoleRepository roleRepository, UserDataValidator fromApiJsonDeserializer,
|
||||||
AppUserPreviousPasswordRepository appUserPreviewPasswordRepository, StaffRepositoryWrapper staffRepositoryWrapper,
|
AppUserPreviousPasswordRepository appUserPreviewPasswordRepository, StaffRepositoryWrapper staffRepositoryWrapper,
|
||||||
ClientRepositoryWrapper clientRepositoryWrapper) {
|
ClientRepositoryWrapper clientRepositoryWrapper, ConfigurationDomainService configurationDomainService) {
|
||||||
return new AppUserWritePlatformServiceJpaRepositoryImpl(context, userDomainService, platformPasswordEncoder, appUserRepository,
|
return new AppUserWritePlatformServiceJpaRepositoryImpl(context, userDomainService, platformPasswordEncoder, appUserRepository,
|
||||||
officeRepositoryWrapper, roleRepository, fromApiJsonDeserializer, appUserPreviewPasswordRepository, staffRepositoryWrapper,
|
officeRepositoryWrapper, roleRepository, fromApiJsonDeserializer, appUserPreviewPasswordRepository, staffRepositoryWrapper,
|
||||||
clientRepositoryWrapper);
|
clientRepositoryWrapper, configurationDomainService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@@ -228,4 +228,5 @@
|
|||||||
<include file="parts/0207_add_allow_full_term_for_tranche.xml" relativeToChangelogFile="true" />
|
<include file="parts/0207_add_allow_full_term_for_tranche.xml" relativeToChangelogFile="true" />
|
||||||
<include file="parts/0208_trial_balance_summary_with_asset_owner_journal_entry_aggregation_fix.xml" relativeToChangelogFile="true" />
|
<include file="parts/0208_trial_balance_summary_with_asset_owner_journal_entry_aggregation_fix.xml" relativeToChangelogFile="true" />
|
||||||
<include file="parts/0209_transaction_summary_with_asset_owner_and_from_asset_owner_id_for_asset_sales.xml" relativeToChangelogFile="true" />
|
<include file="parts/0209_transaction_summary_with_asset_owner_and_from_asset_owner_id_for_asset_sales.xml" relativeToChangelogFile="true" />
|
||||||
|
<include file="parts/0210_add_configuration_password_reuse_check_history_count.xml" relativeToChangelogFile="true" />
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||||
|
<changeSet author="fineract" id="1">
|
||||||
|
<insert tableName="c_configuration">
|
||||||
|
<column name="name" value="password-reuse-check-history-count"/>
|
||||||
|
<column name="value" valueNumeric="3"/>
|
||||||
|
<column name="date_value"/>
|
||||||
|
<column name="string_value"/>
|
||||||
|
<column name="enabled" valueBoolean="false"/>
|
||||||
|
<column name="is_trap_door" valueBoolean="false"/>
|
||||||
|
<column name="description" value="When enabled, prevents password reuse. The value specifies how many previous passwords to check (e.g., 3 = last 3 passwords). Set to 0 to check ALL previous passwords. Disable this setting to allow password reuse."/>
|
||||||
|
</insert>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
+151
@@ -0,0 +1,151 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.useradministration.service;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.ArgumentMatchers.nullable;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||||
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformPasswordEncoder;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.apache.fineract.organisation.office.domain.Office;
|
||||||
|
import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
|
||||||
|
import org.apache.fineract.organisation.staff.domain.StaffRepositoryWrapper;
|
||||||
|
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUserPreviousPassword;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUserPreviousPasswordRepository;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUserRepository;
|
||||||
|
import org.apache.fineract.useradministration.domain.RoleRepository;
|
||||||
|
import org.apache.fineract.useradministration.domain.UserDomainService;
|
||||||
|
import org.apache.fineract.useradministration.exception.PasswordPreviouslyUsedException;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class AppUserWritePlatformServiceJpaRepositoryImplTest {
|
||||||
|
|
||||||
|
private static final Long USER_ID = 1L;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private PlatformSecurityContext context;
|
||||||
|
@Mock
|
||||||
|
private UserDomainService userDomainService;
|
||||||
|
@Mock
|
||||||
|
private PlatformPasswordEncoder platformPasswordEncoder;
|
||||||
|
@Mock
|
||||||
|
private AppUserRepository appUserRepository;
|
||||||
|
@Mock
|
||||||
|
private OfficeRepositoryWrapper officeRepositoryWrapper;
|
||||||
|
@Mock
|
||||||
|
private RoleRepository roleRepository;
|
||||||
|
@Mock
|
||||||
|
private UserDataValidator fromApiJsonDeserializer;
|
||||||
|
@Mock
|
||||||
|
private AppUserPreviousPasswordRepository appUserPreviewPasswordRepository;
|
||||||
|
@Mock
|
||||||
|
private StaffRepositoryWrapper staffRepositoryWrapper;
|
||||||
|
@Mock
|
||||||
|
private ClientRepositoryWrapper clientRepositoryWrapper;
|
||||||
|
@Mock
|
||||||
|
private ConfigurationDomainService configurationDomainService;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private AppUserWritePlatformServiceJpaRepositoryImpl underTest;
|
||||||
|
|
||||||
|
private JsonCommand command;
|
||||||
|
private AppUser user;
|
||||||
|
private AppUser authenticatedUser;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null));
|
||||||
|
command = mock(JsonCommand.class);
|
||||||
|
user = mock(AppUser.class);
|
||||||
|
authenticatedUser = mock(AppUser.class);
|
||||||
|
|
||||||
|
when(command.json()).thenReturn("{}");
|
||||||
|
when(appUserRepository.findById(USER_ID)).thenReturn(Optional.of(user));
|
||||||
|
when(context.authenticatedUser(any(CommandWrapper.class))).thenReturn(authenticatedUser);
|
||||||
|
doNothing().when(fromApiJsonDeserializer).validateForChangePassword(anyString(), nullable(AppUser.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown() {
|
||||||
|
ThreadLocalContextUtil.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void changeUserPasswordThrowsWhenPasswordPreviouslyUsed() {
|
||||||
|
when(user.getId()).thenReturn(USER_ID);
|
||||||
|
when(user.getEncodedPassword(command, platformPasswordEncoder)).thenReturn("encoded");
|
||||||
|
when(configurationDomainService.getPasswordReuseRestrictionCount()).thenReturn(2);
|
||||||
|
|
||||||
|
AppUserPreviousPassword previousPassword = mock(AppUserPreviousPassword.class);
|
||||||
|
when(previousPassword.getPassword()).thenReturn("encoded");
|
||||||
|
when(appUserPreviewPasswordRepository.findByUserId(eq(USER_ID), any(PageRequest.class))).thenReturn(List.of(previousPassword));
|
||||||
|
|
||||||
|
assertThrows(PasswordPreviouslyUsedException.class, () -> underTest.changeUserPassword(USER_ID, command));
|
||||||
|
|
||||||
|
verify(appUserRepository, never()).saveAndFlush(user);
|
||||||
|
verify(appUserPreviewPasswordRepository, never()).save(any(AppUserPreviousPassword.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void changeUserPasswordSavesPreviousPasswordWhenAllowed() {
|
||||||
|
Office office = mock(Office.class);
|
||||||
|
when(office.getId()).thenReturn(7L);
|
||||||
|
when(user.getOffice()).thenReturn(office);
|
||||||
|
when(user.getId()).thenReturn(USER_ID);
|
||||||
|
when(user.getPassword()).thenReturn("currentEncoded");
|
||||||
|
when(user.getEncodedPassword(command, platformPasswordEncoder)).thenReturn("newEncoded");
|
||||||
|
when(user.changePassword(command, platformPasswordEncoder)).thenReturn(Map.of("password", "new"));
|
||||||
|
when(configurationDomainService.getPasswordReuseRestrictionCount()).thenReturn(2);
|
||||||
|
when(appUserPreviewPasswordRepository.findByUserId(eq(USER_ID), any(PageRequest.class))).thenReturn(List.of());
|
||||||
|
|
||||||
|
CommandProcessingResult result = underTest.changeUserPassword(USER_ID, command);
|
||||||
|
|
||||||
|
assertEquals(USER_ID, result.getResourceId());
|
||||||
|
verify(appUserRepository).saveAndFlush(user);
|
||||||
|
verify(appUserPreviewPasswordRepository).save(any(AppUserPreviousPassword.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -217,6 +217,13 @@ public class GlobalConfigurationHelper {
|
|||||||
forcePasswordResetDaysDefault.put("trapDoor", false);
|
forcePasswordResetDaysDefault.put("trapDoor", false);
|
||||||
defaults.add(forcePasswordResetDaysDefault);
|
defaults.add(forcePasswordResetDaysDefault);
|
||||||
|
|
||||||
|
HashMap<String, Object> passwordReuseCheckHistoryCountDefault = new HashMap<>();
|
||||||
|
passwordReuseCheckHistoryCountDefault.put("name", GlobalConfigurationConstants.PASSWORD_REUSE_CHECK_HISTORY_COUNT);
|
||||||
|
passwordReuseCheckHistoryCountDefault.put("value", 3L);
|
||||||
|
passwordReuseCheckHistoryCountDefault.put("enabled", false);
|
||||||
|
passwordReuseCheckHistoryCountDefault.put("trapDoor", false);
|
||||||
|
defaults.add(passwordReuseCheckHistoryCountDefault);
|
||||||
|
|
||||||
HashMap<String, Object> graceOnPenaltyPostingDefault = new HashMap<>();
|
HashMap<String, Object> graceOnPenaltyPostingDefault = new HashMap<>();
|
||||||
graceOnPenaltyPostingDefault.put("name", GlobalConfigurationConstants.GRACE_ON_PENALTY_POSTING);
|
graceOnPenaltyPostingDefault.put("name", GlobalConfigurationConstants.GRACE_ON_PENALTY_POSTING);
|
||||||
graceOnPenaltyPostingDefault.put("value", 0L);
|
graceOnPenaltyPostingDefault.put("value", 0L);
|
||||||
|
|||||||
Reference in New Issue
Block a user