Skip to content
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

Closed
wants to merge 3 commits into from

Conversation

mouellet
Copy link
Contributor

@mouellet mouellet commented Feb 4, 2017

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

@pivotal-issuemaster
Copy link

@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.

@pivotal-issuemaster
Copy link

@mouellet Thank you for signing the Contributor License Agreement!

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Feb 4, 2017
Copy link
Member

@snicoll snicoll left a 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)) {
Copy link
Member

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).

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! 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.

Copy link
Member

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);
Copy link
Member

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?)

Copy link
Contributor Author

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?

Copy link
Member

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();
Copy link
Member

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;
Copy link
Member

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?

Copy link
Contributor Author

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 added a commit to mouellet/spring-boot that referenced this pull request Feb 6, 2017
mouellet added a commit to mouellet/spring-boot that referenced this pull request Feb 6, 2017
@snicoll
Copy link
Member

snicoll commented Feb 6, 2017

@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.

@snicoll snicoll added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Feb 6, 2017
@snicoll snicoll added this to the 1.5.2 milestone Feb 6, 2017
@snicoll
Copy link
Member

snicoll commented Feb 8, 2017

ping @mouellet

@snicoll
Copy link
Member

snicoll commented Feb 8, 2017

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())));
Copy link
Member

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

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 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 {
Copy link
Member

Choose a reason for hiding this comment

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

Must be public

@snicoll snicoll added the status: on-hold We can't start working on this issue yet label Feb 8, 2017
@snicoll snicoll removed this from the 1.5.2 milestone Feb 8, 2017
Copy link
Member

@snicoll snicoll left a 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(
Copy link
Member

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.

@snicoll snicoll removed the status: on-hold We can't start working on this issue yet label Feb 20, 2017
@snicoll snicoll added this to the 1.5.2 milestone Feb 20, 2017
@snicoll
Copy link
Member

snicoll commented Feb 20, 2017

Awesome, 3.2.1 contains the method I've requested

snicoll pushed a commit that referenced this pull request Feb 20, 2017
snicoll added a commit that referenced this pull request Feb 20, 2017
* pr/8195:
  Polish contribution
  Add schema validation options for embedded LDAP
@snicoll snicoll closed this in 43a534f Feb 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Embedded LDAP server schema validation options
4 participants