Skip to content

Conversation

@airajena
Copy link
Contributor

Description

Implements FINERACT-2005: Prohibit password re-use with a configurable global setting.

Changes

  • Added new global configuration restrict-reuse-of-password (enabled by default, value=3)
  • Added getPasswordReuseRestrictionCount() method to ConfigurationDomainService
  • Updated AppUserWritePlatformServiceJpaRepositoryImpl to use the configurable value instead of hardcoded constant
  • If the configuration is disabled OR value is 0, password reuse check is skipped entirely

How It Works

  • Enabled (default): Checks last N passwords (configurable, default=3). Throws PasswordPreviouslyUsedException if match found.
  • Disabled: Password reuse check is completely skipped.

Related Issue

Resolves FINERACT-2005

Copy link
Contributor

@IOhacker IOhacker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@airajena airajena force-pushed the FINERACT-2005/prohibit-password-reuse branch from 5ddd32b to 814bb25 Compare January 23, 2026 04:40
public static final String ASSET_OWNER_TRANSFER_OUTSTANDING_INTEREST_CALCULATION_STRATEGY = "outstanding-interest-calculation-strategy-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 RESTRICT_REUSE_OF_PASSWORD = "restrict-reuse-of-password";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont like the naming. This global configuration serves a dual purpose:

  • whether we want to restrict password reusage
  • For the N last used password to be checked.

Can you please use something which fit better for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! I've renamed it to PASSWORD_REUSE_CHECK_HISTORY_COUNT which I think better captures both purposes. Let me know if you'd prefer a different name.

return null;
}
Long value = property.getValue();
return value != null && value > 0 ? value.intValue() : null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go with 0 if no value was provided, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed! Now it returns 0 when enabled but no value is provided, instead of null

if (aPreviewPassword.getPassword().equals(passWordEncodedValue)) {
throw new PasswordPreviouslyUsedException();
final Integer passwordReuseRestrictionCount = this.configurationDomainService.getPasswordReuseRestrictionCount();
if (passwordReuseRestrictionCount != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if its enabled, but no value was provided, it is doing nothing which contradicts with the purpose of this field!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the logic so when it's enabled with value 0 (or no value), it now checks against ALL previous passwords for that user. This ensures password reuse is actually prevented when the feature is enabled.

<column name="string_value"/>
<column name="enabled" valueBoolean="false"/>
<column name="is_trap_door" valueBoolean="false"/>
<column name="description" value="Number of previous passwords to check when a user changes their password. Set to 0 or disable to allow password reuse."/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set to 0 or disable to allow password reuse. i dont like this. If it is enabled, it should prevent password reusage! Having it enabled and value = 0 should not "allow password reuse" but instead do not allow any reused password!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completely agree! I've updated the description to: "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. This makes it clear that enabling with 0 is the strictest setting, not the most permissive.

Copy link
Contributor

@adamsaghy adamsaghy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kindly see my concerns!

@airajena airajena force-pushed the FINERACT-2005/prohibit-password-reuse branch from 814bb25 to 552c5f4 Compare January 24, 2026 10:57
@airajena
Copy link
Contributor Author

Kindly see my concerns!

Addressed all the concerns. Also following pre commits(./gradlew spotlessApply spotbugsMain spotbugsTest checkstyleMain checkstyleTest)

Copy link
Contributor

@adamsaghy adamsaghy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add proper testing to ensure correct behaviour!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants