+
Skip to content

Implemented validation to ensure each OTP device has a unique label #38657

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

Merged

Conversation

SaikrishnaPavuluri
Copy link
Contributor

@SaikrishnaPavuluri SaikrishnaPavuluri commented Apr 3, 2025

Closes #38465

### Summary of Changes
This PR enhances the OTP credential creation process by improving duplicate device validation and error handling.

Changes in JpaUserCredentialStore and JpaUserFederatedStorageProvider

  1. Added duplicate credential validation for both create and update methods.

  2. Ensured that users cannot register an OTP device with the same name multiple times.

  3. Introduced validateDuplicateUserCredential to handle duplicate detection.

### Enhancements in createOTPCredential (CredentialHelper.java)

  1. Changed return type from boolean to Map<String, Boolean> for more detailed status tracking:

  2. isDeviceDuplicate: true if a duplicate OTP device exists.

  3. isOTPCreationSuccess: true if OTP credential creation was successful.

Handled ModelDuplicateException to prevent duplicate device registrations.

### Updates in processAction() (UpdateTotp class)

  1. Now checks isDeviceDuplicate before proceeding with OTP creation.

  2. If a duplicate device is detected, it shows an error message:

"Device already exists with the same name"

  1. If OTP creation fails for other reasons, it shows:

"Invalid TOTP"

Additional Update:

  1. Added duplicate and empty device name validation in setCredentialUserLabel method (UserResource class).

  2. This ensures users cannot update a userlabel (i.e device name) to a blank value or a label that already exists.

### Feedback & Review Request

This is my first contribution to Keycloak, and I would appreciate any feedback on the implementation, approach, or any best practices I might have missed.

Please find the validated screenshot after implementation

image

Let me know if any improvements or additional changes are needed. Thanks! 🙌

@SaikrishnaPavuluri SaikrishnaPavuluri force-pushed the feature/38465-unique-otp-device-name branch 2 times, most recently from b98ce83 to e11ef12 Compare April 5, 2025 09:10
@SaikrishnaPavuluri
Copy link
Contributor Author

Additional Update:

  1. Added duplicate and empty device name validation in setCredentialUserLabel method (UserResource class).
  2. This ensures users cannot update a userlabel (i.e device name) to a blank value or a label that already exists.

Please find validated screenshots:

image
image

Thanks!

@SaikrishnaPavuluri
Copy link
Contributor Author

Hi @ahus1,

I've made two commits to this draft PR and would really appreciate it if you could take a look whenever you get a chance. Please let me know if you have any feedback, suggestions, or improvements you'd like to see. I'd be happy to incorporate them.

Thank you for your time

@ahus1 ahus1 changed the title #38465 Implemented validation to ensure each OTP device has a unique … Implemented validation to ensure each OTP device has a unique label Apr 8, 2025
@ahus1 ahus1 force-pushed the feature/38465-unique-otp-device-name branch from e0e429d to a1b5f99 Compare April 8, 2025 18:55
Copy link
Contributor

@ahus1 ahus1 left a comment

Choose a reason for hiding this comment

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

Thank you for the pull request. I pushed one more commit to suggest a change that doesn't make as many assumptions about the type of exceptions thrown, as there might be other exceptions appearing in other places.

I also see that you reformatted parts of the code, so the indentation has changed. Please revert those changes as they make it hard to review the changes on GitHub.

Comment on lines 889 to 894

if (userLabel == null || userLabel.trim().isEmpty()) {
throw new ErrorResponseException("missingDeviceName", "Please specify the device name", Status.BAD_REQUEST);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

As this is also used for all credentials including passwords, having an error message that is specific for a device name isn't a good fit here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @ahus1, I have updated the error to:

throw new ErrorResponseException("missingCredentialLabel", "Credential label must not be empty", Status.BAD_REQUEST);

Please let me know if this looks good or if you’d prefer a different message/key. Thanks!

@ahus1
Copy link
Contributor

ahus1 commented Apr 8, 2025

Another hint: Please avoid to merge the main branch into the PR, instead rebase the pull request when needed. This makes it again simpler to review.

@ahus1
Copy link
Contributor

ahus1 commented Apr 9, 2025

@SaikrishnaPavuluri - please don't merge the main branch into your PR, as this makes it difficult to review.

Rebasing should only be done when there are conflicts or a maintainer asks you to rebase. This avoid unnecessary CI runs and unnecessary notifications to maintainers.

Copy link
Contributor

@ahus1 ahus1 left a comment

Choose a reason for hiding this comment

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

In a previous review I commented the following, which hasn't been addressed yet:

I also see that you reformatted parts of the code, so the indentation has changed. Please revert those changes as they make it hard to review the changes on GitHub.

The functional changes look good, please now add a test case that validates the new behavior. Maybe you can extend an existing test, maybe you need to write a new test. Let me know if you need pointers.

@SaikrishnaPavuluri
Copy link
Contributor Author

@ahus1
Thanks! I've addressed the review changes.
Could you also please share some pointers on where I can add or extend the test case to validate the new behavior? That would help me get started in the right direction.

@SaikrishnaPavuluri
Copy link
Contributor Author

@SaikrishnaPavuluri - please don't merge the main branch into your PR, as this makes it difficult to review.

Rebasing should only be done when there are conflicts or a maintainer asks you to rebase. This avoid unnecessary CI runs and unnecessary notifications to maintainers.

I have fixed the indentation issues and pushed the updated commit. Thanks a lot for your guidance I will be careful with formatting in future contributions to avoid this again.

@SaikrishnaPavuluri
Copy link
Contributor Author

The functional changes look good, please now add a test case that validates the new behavior. Maybe you can extend an existing test, maybe you need to write a new test. Let me know if you need pointers.

Hi @ahus1
Could you please share the pointers you mentioned yesterday for adding the test case? Appreciate your help. Thanks!

@ahus1
Copy link
Contributor

ahus1 commented Apr 10, 2025

@SaikrishnaPavuluri - I've read your comment, but allow for some more time to get back to you.

@ahus1
Copy link
Contributor

ahus1 commented Apr 15, 2025

Ok, KC 26.2 has been released, and as the dust settles, here's my reply.

Sebastian and me recorded a session in Keycloak Hour of Code. See https://www.youtube.com/watch?v=gX9BWk-AiqE&list=PLFoHXRSurvbHNojMgLsn76-tdm13carIh&index=4&t=14s&ab_channel=AlexanderSchwartz for the video. And you find links including the script in the description of the video.

I hope this is helpful. Please let me know if you have questions.

@ahus1 ahus1 self-assigned this Apr 15, 2025
@SaikrishnaPavuluri
Copy link
Contributor Author

Ok, KC 26.2 has been released, and as the dust settles, here's my reply.

Sebastian and me recorded a session in Keycloak Hour of Code. See https://www.youtube.com/watch?v=gX9BWk-AiqE&list=PLFoHXRSurvbHNojMgLsn76-tdm13carIh&index=4&t=14s&ab_channel=AlexanderSchwartz for the video. And you find links including the script in the description of the video.

I hope this is helpful. Please let me know if you have questions.

I will try to complete this by the end of the week. Thanks

@SaikrishnaPavuluri
Copy link
Contributor Author

Hi @ahus1, I have added test cases in the latest commit for setCredentialUserLabel, createCredential, and updateCredential to validate behavior with empty and duplicate device labels.

I also looked for a test class covering the processAction() method in UpdateTotp, but couldn’t find one. Please let me know if it exists elsewhere.

Thanks!

@SaikrishnaPavuluri
Copy link
Contributor Author

Hi @ahus1
Could you please review the code for the integration tests and let me know if any changes are needed?
Thanks for your time!

Saikrishna and others added 5 commits May 3, 2025 11:05
… unique name

Signed-off-by: Saikrishna <saikrishnap@optimeyes.ai>
…tCredentialUserLabel (UserResource)

Signed-off-by: Saikrishna <saikrishnap@optimeyes.ai>
Closes keycloak#38465

Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
…Credential and updateCredential (duplicate label)

Signed-off-by: Saikrishna <saikrishnap@optimeyes.ai>

Fix indentation issues

Completed review changes and reverted formatting
Closes keycloak#38465

Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
@ahus1 ahus1 force-pushed the feature/38465-unique-otp-device-name branch from beada4b to 3abafb0 Compare May 3, 2025 09:49
@ahus1
Copy link
Contributor

ahus1 commented May 3, 2025

I found a place in AppInitiatedActionTotpSetupTest where to add a test and pushed it to this PR. As there were several merge commits, I also rebased it for better reviewability.

Let's look at the test results once the tests complete.

ahus1 added 3 commits May 3, 2025 13:18
Closes keycloak#38465

Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
Closes keycloak#38465

Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
Closes keycloak#38465

Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
ahus1 added 2 commits May 3, 2025 16:43
Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
@keycloak keycloak deleted a comment from keycloak-github-bot bot May 3, 2025
keycloak-github-bot[bot]

This comment was marked as outdated.

@keycloak keycloak deleted a comment from keycloak-github-bot bot May 3, 2025
@ahus1
Copy link
Contributor

ahus1 commented May 5, 2025

Thank you for the code and the test, the build is now green and the tests are stable. Unfortunately the changes broke some existing tests which I didn't foresee, and it also touched some browser-only tests that are difficult to reproduce locally.

I'm now marking it ready for review and have someone else from the team look at it as well.

When you look at my commits, please take a moment to review them. Given the documentation above, I hope it is sufficient to run a single test locally, and possibly even debug it. While running all tests locally is very time consuming and better handled by the GitHub actions, running a single test locally is a great skill that allows you to iterate faster when developing tests. If the documentation isn't sufficient, please let me know and we'll look into enhancing it.

@ahus1 ahus1 marked this pull request as ready for review May 5, 2025 06:14
@ahus1 ahus1 requested review from a team as code owners May 5, 2025 06:14
@ahus1
Copy link
Contributor

ahus1 commented May 5, 2025

@mposolda - this PR looks good to me, and the error messages shown to the users when they try to have a credential with the same label are IMHO descriptive.

As this touches the core-clients area, please give it a review as well. As this is a first-time contribution, I'm willing to give a helping hand where needed.

Thanks!

@ahus1 ahus1 requested a review from mposolda May 5, 2025 06:16
@SaikrishnaPavuluri
Copy link
Contributor Author

Thank you for the code and the test, the build is now green and the tests are stable. Unfortunately the changes broke some existing tests which I didn't foresee, and it also touched some browser-only tests that are difficult to reproduce locally.

I'm now marking it ready for review and have someone else from the team look at it as well.

When you look at my commits, please take a moment to review them. Given the documentation above, I hope it is sufficient to run a single test locally, and possibly even debug it. While running all tests locally is very time consuming and better handled by the GitHub actions, running a single test locally is a great skill that allows you to iterate faster when developing tests. If the documentation isn't sufficient, please let me know and we'll look into enhancing it.

@ahus1 I’m truly grateful for all the detailed feedback and support you’ve given me throughout my first contribution. Your guidance has been invaluable not only in understanding development and debugging, but also in helping me navigate the codebase with more confidence. The video you and Sebastian shared was fantastic and really helped clarify many concepts.

I’m happy to have a mentor like you and excited to keep learning, contributing, and growing. Your encouragement motivates me to take on more challenges. I’ll definitely take your advice and spend time understanding the tests better so it helps me in future contributions.

I’d really appreciate a review of this PR when time permits. As this is my first contribution, I’m eager to learn and grow with your guidance. It’s a privilege to collaborate with such experienced contributors, and I’m open to any suggestions or improvements you may have.

@ahus1
Copy link
Contributor

ahus1 commented May 6, 2025

@SaikrishnaPavuluri - thank you for sharing this, and kudos so @srose for preparing the recordings!

@SaikrishnaPavuluri
Copy link
Contributor Author

Hi @mposolda and @ahus1 just checking in is this PR ready to be merged, or is there anything else needed from my side?

@mabartos
Copy link
Contributor

@rmartinc Could you or someone from your team check this PR as @mposolda is currently out? Thanks!

Copy link
Contributor

@rmartinc rmartinc left a comment

Choose a reason for hiding this comment

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

Thanks @SaikrishnaPavuluri and @ahus1! Changes LGTM. I was thinking about adding some note in the upgrading guide. But I understand that this is more a bug than something else. Approved.

@ahus1
Copy link
Contributor

ahus1 commented Jun 12, 2025

@rmartinc - thank you for the review. I'll create a follow-up issue with a "notable change" to the upgrade guide.

UPDATE: #40445

@ahus1 ahus1 merged commit 76ab8bd into keycloak:main Jun 12, 2025
76 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Name for OTP device should be unique
4 participants
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载