-
Notifications
You must be signed in to change notification settings - Fork 40.7k
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
Add schema validation options for embedded LDAP #8195
Conversation
@mouellet Please sign the Contributor License Agreement! Click here to manually synchronize the status of this Pull Request. See the FAQ for frequently asked questions. |
@mouellet Thank you for signing the Contributor License Agreement! |
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.
Thanks for the PR! I've added a few comments there.
if (this.embeddedProperties.getValidation().isEnabled()) { | ||
schema = Schema.getDefaultStandardSchema(); | ||
String schemaLocation = this.embeddedProperties.getValidation().getSchema(); | ||
if (StringUtils.hasText(schemaLocation)) { |
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.
Rather than using a String
there you could use a Resource
. That way the binder will do the work of making sure that resource is valid (if set).
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.
Good point! Should the spring.ldap.embedded.ldif
property also use a Resource
? I'm not sure about having two ways to load a resource in this same configuration.
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.
Good point. I'll take care of that once I've merged this PR.
} | ||
} | ||
} | ||
config.setSchema(schema); |
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.
Not sure why you need to keep a handle to the schema there outside of the if block. I'd rather keep all that private (unless set it to null
has some kind of purpose?)
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.
Yes, setting the schema to null
is what disables the validation. Should it be more explicit with something like https://github.com/jgribonvald/embedded-ldap/blob/master/src/test/java/org/esco/test/ldap/LdapServerRule.java#L69-L76?
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.
I think that just relying on the fact that the property is intialized to null
is not very clear. I'd rather have an explicit call to null. Can you update your PR with what we've discussed here please?
/** | ||
* Schema validation | ||
*/ | ||
private Validation validation = new Validation(); |
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.
Nested configuration properties can be (and should be) final
. You don't need a setter since the object instance for this properties object is always there.
/** | ||
* Enable LDAP schema validation | ||
*/ | ||
private boolean enabled = true; |
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.
What is the semantic of that flag? Does it make sense to set a schema and disable validation? Why do you need to set both a schema and the validation flag. Perhaps we should check for the presence of the schema only?
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.
Those really are two features. Most of the time you'll only need to disable the validation altogether and thats basically what the flag is for.
But if you don't have custom attribute types or object classes you can still have validation against the default standard schema provided by unboundid as it is initialized in InMemoryDirectoryServerConfig
with Schema.getDefaultStandardSchema()
. So not providing a custom schema here doesn't mean you don't want validation.
Of course it doesn't make sense to set a schema and disable validation...
@mouellet it looks like you've done a weird rebase of your branch. Can you squash your commits in a single one and push force in your branch? There are a lot of unrelated changes in your branch now. Thanks. |
ping @mouellet |
Ah sorry I just pinged you but you've fixed it. Awesome, thanks! |
Resource schemaLocation = this.embeddedProperties.getValidation().getSchema(); | ||
try { | ||
config.setSchema(Schema.mergeSchemas(Schema.getDefaultStandardSchema(), | ||
Schema.getSchema(schemaLocation.getFile()))); |
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.
You can't really do that I am afraid. Resource
is an abstraction and it may not return a file. The only reason why the tests currently pass is because you are running them with target/test-classes
so resources effectively point to a file. If you use the same inside a repackaged jar, getFile
will return null
.
I am not super keen to introduce a feature that requires to point to java.io.File
. Looking at the code for Schema
, there isn't an easy way to read a Schema
from a InputStream
. IMO that feature should be available before we proceed with this PR
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.
I took a closer look at the Schema
class and I think there's a simpler solution, delegate the whole file loading to that class... It does mean reverting the property to a String
. I'll push a sample, let me know what you think!
@@ -109,4 +120,34 @@ public void setPassword(String password) { | |||
|
|||
} | |||
|
|||
static class Validation { |
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.
Must be public
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.
Let's keep those changes on hold for the moment. I'll revisit your PR once we have a new version.
try { | ||
config.setSchema(Schema.mergeSchemas(Schema.getDefaultStandardSchema(), | ||
Schema.getSchema(schemaLocation.getFile()))); | ||
Schema.getSchema( |
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.
That's not going to work. That code expects the String to point to a File. I've opened an issue to get an InputStream
variant so I'd rather wait for that.
Awesome, |
* pr/8195: Polish contribution Add schema validation options for embedded LDAP
Unboundid uses a standard schema to validate LDIF files so importing one with a custom attribute type or object class fails.
This
spring.ldap.embedded.validation.enabled
property provides a way to deactivate the schema validation.Alternatively, a custom schema file can be specified with the
spring.ldap.embedded.validation.schema
property. Such schema typically contains new or customized attribute types or object classes, so it's merged with the standard schema.Fixes gh-8171