-
Notifications
You must be signed in to change notification settings - Fork 6
[NAE-2173] Password change #345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b9d18b1
e86404b
f4e7c5a
e9d26c8
cba755d
ca8a6d0
bc3dd08
5690350
56cc11f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -261,6 +261,19 @@ public List<Group> getUserGroups(AbstractActor actor) { | |||||||||||||||||||||||||||||||||
| return groupService.findAllByIds(actor.getGroupIds(), Pageable.unpaged()).stream().toList(); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||||||||
| public AbstractUser changePassword(AbstractUser user, String newPassword, String oldPassword) { | ||||||||||||||||||||||||||||||||||
| canUpdatePassword(user, newPassword); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (!verifyPasswords(user, oldPassword)) { | ||||||||||||||||||||||||||||||||||
| throw new IllegalArgumentException("Old password does not match."); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| log.debug("Setting password for user [{}]", user.getUsername()); | ||||||||||||||||||||||||||||||||||
| user.setPassword(passwordEncoder.encode(newPassword)); | ||||||||||||||||||||||||||||||||||
| return saveUser(user); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||||||||
| public void addDefaultAuthorities(AbstractUser user) { | ||||||||||||||||||||||||||||||||||
| log.trace("Assigning default authorities to user [{}]", user.getUsername()); | ||||||||||||||||||||||||||||||||||
|
|
@@ -636,4 +649,22 @@ private void resolveRelatedProcessRoles(AbstractUser user) { | |||||||||||||||||||||||||||||||||
| user.getAuthoritySet().addAll(getUserGroups(user).stream().map(Group::getAuthoritySet).flatMap(Set::stream).collect(Collectors.toSet())); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| private boolean verifyPasswords(AbstractUser user, String password) { | ||||||||||||||||||||||||||||||||||
| if (password == null) { | ||||||||||||||||||||||||||||||||||
| throw new IllegalArgumentException("confirmation password is not set"); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| log.trace("Verifying password for user [{}]", user.getUsername()); | ||||||||||||||||||||||||||||||||||
| return passwordEncoder.matches(password, user.getPassword()); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+654
to
+659
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Null-safe verification and clearer message. Handle null stored password and align message with param meaning. - if (password == null) {
- throw new IllegalArgumentException("confirmation password is not set");
- }
-
- log.trace("Verifying password for user [{}]", user.getUsername());
- return passwordEncoder.matches(password, user.getPassword());
+ if (password == null) {
+ throw new IllegalArgumentException("Old password is not set");
+ }
+ String stored = user.getPassword();
+ if (stored == null) {
+ log.warn("User [{}] has no stored password to verify against", user.getUsername());
+ return false;
+ }
+ log.trace("Verifying old password for user [{}]", user.getUsername());
+ return passwordEncoder.matches(password, stored);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| protected void canUpdatePassword(AbstractUser user, String password) { | ||||||||||||||||||||||||||||||||||
| if (!user.isCredentialEnabled("password")) { | ||||||||||||||||||||||||||||||||||
| throw new RuntimeException("Password does not exists or authorization is not enabled"); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+661
to
+664
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) Clarify exception text; avoid generic RuntimeException. Use precise wording and a more specific exception type. - if (!user.isCredentialEnabled("password")) {
- throw new RuntimeException("Password does not exists or authorization is not enabled");
- }
+ if (!user.isCredentialEnabled("password")) {
+ throw new IllegalStateException("Password credential does not exist or is disabled");
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (password == null) { | ||||||||||||||||||||||||||||||||||
| throw new IllegalArgumentException("Password is not set"); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -407,4 +407,14 @@ Page<AbstractUser> searchAllCoMembers(String query, Collection<ProcessResourceId | |||||||||||||||||||||||||||||||||||||||||||
| * @param roles collection of process roles to assign to admin users | ||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||
| void updateAdminWithRoles(Collection<ProcessRole> roles); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||
| * Resets password for user. | ||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||
| * @param user user | ||||||||||||||||||||||||||||||||||||||||||||
| * @param newPassword new password | ||||||||||||||||||||||||||||||||||||||||||||
| * @param oldPassword old password | ||||||||||||||||||||||||||||||||||||||||||||
| * @return the updated user | ||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||
| AbstractUser changePassword(AbstractUser user, String newPassword, String oldPassword); | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+411
to
+419
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Clarify admin bypass and parameter intent in Javadoc. - /**
- * Resets password for user.
- *
- * @param user user
- * @param newPassword new password
- * @param oldPassword old password
- * @return the updated user
- */
+ /**
+ * Changes the user's password.
+ * Non-admin callers must supply the current password; admins may pass {@code null} for {@code oldPassword}.
+ *
+ * @param user the target user
+ * @param newPassword the new password (raw)
+ * @param oldPassword the current password (raw), or {@code null} when invoked by an admin
+ * @return the updated user
+ * @throws IllegalArgumentException if {@code newPassword} is null or (for non-admin callers) {@code oldPassword} does not match
+ * @throws IllegalStateException if the password credential does not exist or is disabled
+ */
AbstractUser changePassword(AbstractUser user, String newPassword, String oldPassword);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Add tests for self-change vs admin-change paths.
Cover: non-admin correct/incorrect old password; admin with null oldPassword; disabled password credential.
I can draft unit tests for UserServiceImpl.changePassword(), mocking PasswordEncoder and SecurityContext. Want me to add them?
Admin bypass not implemented; service always requires old password.
This contradicts PR behavior (“admin doesn’t confirm old password”) and will block admin flows. Also, reuse setPassword() for consistency.
📝 Committable suggestion
🤖 Prompt for AI Agents