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
KEYCLOAK-2045 Add support for flexible Validation #7324
KEYCLOAK-2045 Add support for flexible Validation #7324
Conversation
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.
@thomasdarimont Nice stuff!
I don't have much to add but a few implementation points like those for loops to lookup keys that could maybe be improved with a map.
The other thing would be the correct place for this new SPI, if not in server-spi-private
. At least for now and while we get more feedback from people using it.
@pedroigor thanks for the quick review. Okay, so I'm going to move everything under server-spi-private for now and address the loop idea. |
@thomasdarimont I adapted the PR according to your changes. I moved the interfaces from server-spi to server-spi-private and refactored the key lookups for ValidationKey and ValidationContextKey. I just noticed that the I also simplified the
I'm not sure whether it would make sense to create the I think the API is now quite pragmatic to serve most use cases in a lean way.
The |
To ease access to the validation API, we could also add a method to
... once the |
return validate(context, value, Collections.singleton(key)); | ||
} | ||
|
||
default ValidationResult validate(ValidationContext context, Object value) { |
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.
We could also offer a variant like:
ValidationResult validate(Object value)
which could create a ValidationContext internally which extracts information like the current, realm, client, etc. from the KeycloakSession.getContext()
server-spi-private/src/main/java/org/keycloak/validation/ConditionalValidation.java
Outdated
Show resolved
Hide resolved
/** | ||
* Holds the current {@link RealmModel} | ||
*/ | ||
private final RealmModel realm; |
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.
could be extracted from the KeycloakSession
/** | ||
* Holds the current {@link ClientModel} | ||
*/ | ||
private final ClientModel client; |
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.
could be extracted from the KeycloakSession
* @param client | ||
* @param failFast | ||
*/ | ||
public ValidationContext(ValidationContextKey contextKey, Map<String, Object> attributes, RealmModel realm, UserModel user, ClientModel client, boolean failFast, ValidationActionKey actionKey) { |
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.
We could add a ctor variant that accepts a KeycloakSession, with this we could access Realm and Client information via session.getContext()
9440f00
to
abe518c
Compare
See discussion on mailing list: https://groups.google.com/g/keycloak-dev/c/-XjQu7rn56s
(cherry picked from commit aa01f776433e3abf8fb62ff09bdbf3de14dd9b89)
- Added support for named Validations - Added proper exception handling around validations - Revised support for conditional validations
This enables users to define validations that should run for a whole class of ValidationContextKey's. The special ValidationContextKey.DEFAULT would run the validation always.
…hange types, e.g. create / update etc.
abe518c
to
f598245
Compare
Just rebased this on current master |
@thomasdarimont I liked it very much. Great work. It LGTM and I'm OK to merge it. One thing though, what do you think about this construct?
Which could possibly be chained as:
Or this one to validate everything on a user:
Considering that the built-in context keys are usually what you'll be validating maybe we could make the usage simpler by not forcing client code to explicitly use constants, what I think makes code more readable. |
Hi @pedroigor, Thank you for your feedback! Of course we could add some convenience methods but I'd add those to a dedicated class instead of the default Btw. I just noticed that a stripped down version of a validation framework was just added to keycloak in 11.0.3 With this PR I think there are now at least 4 different ways to do validation in Keycloak.
I need to check again whether those can be combined, or whether the new functionality partially supersedes the Validation implementation of this PR. Cheers, |
As per the different validation approaches, that is one of my main concerns right now :) So far the validation we had was specific for clients but now it is changing the scope and becoming a really overlap with your changes and make things even more interesting (or not). See #7586. Regarding the convenience methods, my main point is related to not making this API so generic but tied with our requirements and use cases. Thus the proposed convenience methods from a single place instead of spreading them across different classes. |
@thomasdarimont How we are going to proceed with this one? |
@pedroigor sorry for the late reply I was busy quite this week... as discussed. I'll catch up with the latest design document and create a smaller (but extensible) version of this PR without all the bells and whistles. We can then close this PR. |
Thanks. |
This proposal shall serve as a more flexible foundation for user profile validations and much more.
This is a squashed and cleaned-up version of my experimental branch poc/validation-spi.
See discussion on mailing list: https://groups.google.com/g/keycloak-dev/c/-XjQu7rn56s
Some API examples can be found in the DefaultValidatorProviderTest
Additionally some integration examples can be seen here: