OPENDJ-3036 Renamed various classes and methods to camel-case
Changed:
AbstractLDAPAttributeMapper.java -> AbstractLdapPropertyMapper.java
JSONConstantAttributeMapper.java -> JsonConstantPropertyMapper.java
NameStrategy.java -> NamingStrategy.java
ObjectAttributeMapper.java -> ObjectPropertyMapper.java
AttributeMapper.java -> PropertyMapper.java
ReferenceAttributeMapper.java -> ReferencePropertyMapper.java
Rest2LDAP.java -> Rest2Ldap.java
Rest2LDAPHttpApplication.java -> Rest2LdapHttpApplication.java
SimpleAttributeMapper.java -> SimplePropertyMapper.java
LDAPCollectionResourceProvider.java -> SubResourceImpl.java
SASLPlainStrategy.java -> SaslPlainStrategy.java
11 files renamed
9 files modified
| File was renamed from opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLDAPAttributeMapper.java |
| | |
| | | import static java.util.Collections.emptyList; |
| | | import static java.util.Collections.singletonList; |
| | | import static org.forgerock.opendj.ldap.Attributes.emptyAttribute; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2LDAP.asResourceException; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2Ldap.asResourceException; |
| | | import static org.forgerock.opendj.rest2ldap.Utils.isNullOrEmpty; |
| | | import static org.forgerock.opendj.rest2ldap.Utils.newBadRequestException; |
| | | import static org.forgerock.opendj.rest2ldap.Utils.newNotSupportedException; |
| | |
| | | import org.forgerock.util.promise.Promises; |
| | | |
| | | /** |
| | | * An abstract LDAP attribute mapper which provides a simple mapping from a JSON |
| | | * An abstract LDAP property mapper which provides a simple mapping from a JSON |
| | | * value to a single LDAP attribute. |
| | | */ |
| | | abstract class AbstractLDAPAttributeMapper<T extends AbstractLDAPAttributeMapper<T>> extends AttributeMapper { |
| | | List<Object> defaultJSONValues = emptyList(); |
| | | abstract class AbstractLdapPropertyMapper<T extends AbstractLdapPropertyMapper<T>> extends PropertyMapper { |
| | | List<Object> defaultJsonValues = emptyList(); |
| | | final AttributeDescription ldapAttributeName; |
| | | private boolean isRequired; |
| | | private boolean isSingleValued; |
| | | private WritabilityPolicy writabilityPolicy = READ_WRITE; |
| | | |
| | | AbstractLDAPAttributeMapper(final AttributeDescription ldapAttributeName) { |
| | | AbstractLdapPropertyMapper(final AttributeDescription ldapAttributeName) { |
| | | this.ldapAttributeName = ldapAttributeName; |
| | | } |
| | | |
| | |
| | | * Indicates that the LDAP attribute is mandatory and must be provided |
| | | * during create requests. |
| | | * |
| | | * @return This attribute mapper. |
| | | * @return This property mapper. |
| | | */ |
| | | public final T isRequired() { |
| | | this.isRequired = true; |
| | |
| | | * Indicates that multi-valued LDAP attribute should be represented as a |
| | | * single-valued JSON value, rather than an array of values. |
| | | * |
| | | * @return This attribute mapper. |
| | | * @return This property mapper. |
| | | */ |
| | | public final T isSingleValued() { |
| | | this.isSingleValued = true; |
| | |
| | | * |
| | | * @param policy |
| | | * The writability policy. |
| | | * @return This attribute mapper. |
| | | * @return This property mapper. |
| | | */ |
| | | public final T writability(final WritabilityPolicy policy) { |
| | | this.writabilityPolicy = policy; |
| | |
| | | @Override |
| | | Promise<List<Attribute>, ResourceException> create( |
| | | final Connection connection, final JsonPointer path, final JsonValue v) { |
| | | return getNewLDAPAttributes(connection, path, v).then( |
| | | return getNewLdapAttributes(connection, path, v).then( |
| | | new Function<Attribute, List<Attribute>, ResourceException>() { |
| | | @Override |
| | | public List<Attribute> apply(Attribute newLDAPAttribute) throws ResourceException { |
| | |
| | | } |
| | | |
| | | @Override |
| | | void getLDAPAttributes(final Connection connection, final JsonPointer path, |
| | | final JsonPointer subPath, final Set<String> ldapAttributes) { |
| | | void getLdapAttributes(final Connection connection, final JsonPointer path, |
| | | final JsonPointer subPath, final Set<String> ldapAttributes) { |
| | | ldapAttributes.add(ldapAttributeName.toString()); |
| | | } |
| | | |
| | | abstract Promise<Attribute, ResourceException> getNewLDAPAttributes(Connection connection, JsonPointer path, |
| | | List<Object> newValues); |
| | | abstract Promise<Attribute, ResourceException> getNewLdapAttributes(Connection connection, JsonPointer path, |
| | | List<Object> newValues); |
| | | |
| | | abstract T getThis(); |
| | | |
| | |
| | | default: |
| | | /* |
| | | * The patch operation targets the child of a sub-field. This is |
| | | * not possible for a LDAP attribute mapper. |
| | | * not possible for a LDAP property mapper. |
| | | */ |
| | | throw newBadRequestException(ERR_UNRECOGNIZED_FIELD.get(path.child(field.get(0)))); |
| | | } |
| | |
| | | singletonList(new Modification(modType, emptyAttribute(ldapAttributeName)))); |
| | | } |
| | | } else { |
| | | return getNewLDAPAttributes(connection, path, newValues) |
| | | return getNewLdapAttributes(connection, path, newValues) |
| | | .then(new Function<Attribute, List<Modification>, ResourceException>() { |
| | | @Override |
| | | public List<Modification> apply(final Attribute value) { |
| | |
| | | @Override |
| | | Promise<List<Modification>, ResourceException> update(final Connection connection, final JsonPointer path, |
| | | final Entry e, final JsonValue v) { |
| | | return getNewLDAPAttributes(connection, path, v).then( |
| | | return getNewLdapAttributes(connection, path, v).then( |
| | | new Function<Attribute, List<Modification>, ResourceException>() { |
| | | @Override |
| | | public List<Modification> apply(final Attribute newLDAPAttribute) throws ResourceException { |
| | |
| | | } |
| | | } |
| | | |
| | | private Promise<Attribute, ResourceException> getNewLDAPAttributes(final Connection connection, |
| | | final JsonPointer path, final JsonValue v) { |
| | | private Promise<Attribute, ResourceException> getNewLdapAttributes(final Connection connection, |
| | | final JsonPointer path, final JsonValue v) { |
| | | try { |
| | | // Ensure that the value is of the correct type. |
| | | checkSchema(path, v); |
| | | final List<Object> newValues = asList(v, defaultJSONValues); |
| | | final List<Object> newValues = asList(v, defaultJsonValues); |
| | | if (newValues.isEmpty()) { |
| | | // Skip sub-class implementation if there are no values. |
| | | return Promises.newResultPromise(emptyAttribute(ldapAttributeName)); |
| | | } else { |
| | | return getNewLDAPAttributes(connection, path, newValues); |
| | | return getNewLdapAttributes(connection, path, newValues); |
| | | } |
| | | } catch (final Exception ex) { |
| | | return Promises.newExceptionPromise(asResourceException(ex)); |
| File was renamed from opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java |
| | |
| | | import org.forgerock.util.promise.Promises; |
| | | |
| | | /** |
| | | * An attribute mapper which maps a single JSON attribute to a fixed value. |
| | | * An property mapper which maps a single JSON attribute to a fixed value. |
| | | */ |
| | | final class JSONConstantAttributeMapper extends AttributeMapper { |
| | | final class JsonConstantPropertyMapper extends PropertyMapper { |
| | | private final JsonValue value; |
| | | |
| | | JSONConstantAttributeMapper(final Object value) { |
| | | JsonConstantPropertyMapper(final Object value) { |
| | | this.value = new JsonValue(value); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | @Override |
| | | void getLDAPAttributes(final Connection connection, final JsonPointer path, final JsonPointer subPath, |
| | | final Set<String> ldapAttributes) { |
| | | void getLdapAttributes(final Connection connection, final JsonPointer path, final JsonPointer subPath, |
| | | final Set<String> ldapAttributes) { |
| | | // Nothing to do. |
| | | } |
| | | |
| | | @Override |
| | | Promise<Filter, ResourceException> getLDAPFilter(final Connection connection, final JsonPointer path, |
| | | final JsonPointer subPath, final FilterType type, final String operator, final Object valueAssertion) { |
| | | Promise<Filter, ResourceException> getLdapFilter(final Connection connection, final JsonPointer path, |
| | | final JsonPointer subPath, final FilterType type, |
| | | final String operator, final Object valueAssertion) { |
| | | final Filter filter; |
| | | final JsonValue subValue = value.get(subPath); |
| | | if (subValue == null) { |
| | |
| | | final Boolean v2 = (Boolean) valueAssertion; |
| | | filter = compare(type, v1, v2); |
| | | } else { |
| | | // This attribute mapper is a candidate but it does not match. |
| | | // This property mapper is a candidate but it does not match. |
| | | filter = alwaysFalse(); |
| | | } |
| | | return Promises.newResultPromise(filter); |
| File was renamed from opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/NameStrategy.java |
| | |
| | | import org.forgerock.opendj.ldap.requests.SearchRequest; |
| | | |
| | | /** |
| | | * A name strategy is responsible for naming REST resources and LDAP entries. |
| | | * A naming strategy is responsible for naming REST resources and LDAP entries. |
| | | */ |
| | | abstract class NameStrategy { |
| | | abstract class NamingStrategy { |
| | | /* |
| | | * This interface is an abstract class so that methods can be made package |
| | | * private until API is finalized. |
| | | */ |
| | | |
| | | NameStrategy() { |
| | | NamingStrategy() { |
| | | // Nothing to do. |
| | | } |
| | | |
| | |
| | | abstract SearchRequest createSearchRequest(Connection connection, DN baseDN, String resourceId); |
| | | |
| | | /** |
| | | * Adds the name of any LDAP attribute required by this name strategy to the |
| | | * Adds the name of any LDAP attribute required by this naming strategy to the |
| | | * provided set. |
| | | * |
| | | * @param connection |
| | |
| | | * The set into which any required LDAP attribute name should be |
| | | * put. |
| | | */ |
| | | abstract void getLDAPAttributes(Connection connection, Set<String> ldapAttributes); |
| | | abstract void getLdapAttributes(Connection connection, Set<String> ldapAttributes); |
| | | |
| | | /** |
| | | * Retrieves the resource ID from the provided LDAP entry. Implementations |
| File was renamed from opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java |
| | |
| | | import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*; |
| | | import static org.forgerock.json.resource.PatchOperation.operation; |
| | | import static org.forgerock.opendj.ldap.Filter.alwaysFalse; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2LDAP.asResourceException; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2Ldap.asResourceException; |
| | | import static org.forgerock.opendj.rest2ldap.Utils.newBadRequestException; |
| | | import static org.forgerock.opendj.rest2ldap.Utils.toLowerCase; |
| | | |
| | |
| | | import org.forgerock.util.promise.Promise; |
| | | import org.forgerock.util.promise.Promises; |
| | | |
| | | /** An attribute mapper which maps JSON objects to LDAP attributes. */ |
| | | public final class ObjectAttributeMapper extends AttributeMapper { |
| | | /** An property mapper which maps JSON objects to LDAP attributes. */ |
| | | public final class ObjectPropertyMapper extends PropertyMapper { |
| | | |
| | | private static final class Mapping { |
| | | private final AttributeMapper mapper; |
| | | private final PropertyMapper mapper; |
| | | private final String name; |
| | | |
| | | private Mapping(final String name, final AttributeMapper mapper) { |
| | | private Mapping(final String name, final PropertyMapper mapper) { |
| | | this.name = name; |
| | | this.mapper = mapper; |
| | | } |
| | |
| | | |
| | | private final Map<String, Mapping> mappings = new LinkedHashMap<>(); |
| | | |
| | | ObjectAttributeMapper() { |
| | | ObjectPropertyMapper() { |
| | | // Nothing to do. |
| | | } |
| | | |
| | |
| | | * @param name |
| | | * The name of the JSON attribute to be mapped. |
| | | * @param mapper |
| | | * The attribute mapper responsible for mapping the JSON |
| | | * The property mapper responsible for mapping the JSON |
| | | * attribute to LDAP attribute(s). |
| | | * @return A reference to this attribute mapper. |
| | | * @return A reference to this property mapper. |
| | | */ |
| | | public ObjectAttributeMapper attribute(final String name, final AttributeMapper mapper) { |
| | | public ObjectPropertyMapper attribute(final String name, final PropertyMapper mapper) { |
| | | mappings.put(toLowerCase(name), new Mapping(name, mapper)); |
| | | return this; |
| | | } |
| | |
| | | } |
| | | |
| | | @Override |
| | | void getLDAPAttributes(final Connection connection, final JsonPointer path, final JsonPointer subPath, |
| | | final Set<String> ldapAttributes) { |
| | | void getLdapAttributes(final Connection connection, final JsonPointer path, final JsonPointer subPath, |
| | | final Set<String> ldapAttributes) { |
| | | if (subPath.isEmpty()) { |
| | | // Request all subordinate mappings. |
| | | for (final Mapping mapping : mappings.values()) { |
| | | mapping.mapper.getLDAPAttributes(connection, path.child(mapping.name), subPath, ldapAttributes); |
| | | mapping.mapper.getLdapAttributes(connection, path.child(mapping.name), subPath, ldapAttributes); |
| | | } |
| | | } else { |
| | | // Request single subordinate mapping. |
| | | final Mapping mapping = getMapping(subPath); |
| | | if (mapping != null) { |
| | | mapping.mapper.getLDAPAttributes( |
| | | mapping.mapper.getLdapAttributes( |
| | | connection, path.child(subPath.get(0)), subPath.relativePointer(), ldapAttributes); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | Promise<Filter, ResourceException> getLDAPFilter(final Connection connection, final JsonPointer path, |
| | | final JsonPointer subPath, final FilterType type, final String operator, final Object valueAssertion) { |
| | | Promise<Filter, ResourceException> getLdapFilter(final Connection connection, final JsonPointer path, |
| | | final JsonPointer subPath, final FilterType type, |
| | | final String operator, final Object valueAssertion) { |
| | | final Mapping mapping = getMapping(subPath); |
| | | if (mapping != null) { |
| | | return mapping.mapper.getLDAPFilter(connection, path.child(subPath.get(0)), |
| | | subPath.relativePointer(), type, operator, valueAssertion); |
| | | return mapping.mapper.getLdapFilter(connection, path.child(subPath.get(0)), |
| | | subPath.relativePointer(), type, operator, valueAssertion); |
| | | } else { |
| | | /* |
| | | * Either the filter targeted the entire object (i.e. it was "/"), |
| File was renamed from opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java |
| | |
| | | import org.forgerock.opendj.ldap.Modification; |
| | | import org.forgerock.util.promise.Promise; |
| | | |
| | | /** An attribute mapper is responsible for converting JSON values to and from LDAP attributes. */ |
| | | public abstract class AttributeMapper { |
| | | /** An property mapper is responsible for converting JSON values to and from LDAP attributes. */ |
| | | public abstract class PropertyMapper { |
| | | /* |
| | | * This interface is an abstract class so that methods can be made package |
| | | * private until API is finalized. |
| | | */ |
| | | |
| | | AttributeMapper() { |
| | | PropertyMapper() { |
| | | // Nothing to do. |
| | | } |
| | | |
| | |
| | | * The LDAP connection to use to perform the operation. |
| | | * @param path |
| | | * The pointer from the root of the JSON resource to this |
| | | * attribute mapper. This may be used when constructing error |
| | | * property mapper. This may be used when constructing error |
| | | * messages. |
| | | * @param v |
| | | * The JSON value to be converted to LDAP attributes, which may |
| | |
| | | abstract Promise<List<Attribute>, ResourceException> create(Connection connection, JsonPointer path, JsonValue v); |
| | | |
| | | /** |
| | | * Adds the names of the LDAP attributes required by this attribute mapper |
| | | * Adds the names of the LDAP attributes required by this property mapper |
| | | * to the provided set. |
| | | * <p> |
| | | * Implementations should only add the names of attributes found in the LDAP |
| | |
| | | * The LDAP connection to use to perform the operation. |
| | | * @param path |
| | | * The pointer from the root of the JSON resource to this |
| | | * attribute mapper. This may be used when constructing error |
| | | * property mapper. This may be used when constructing error |
| | | * messages. |
| | | * @param subPath |
| | | * The targeted JSON field relative to this attribute mapper, or |
| | | * The targeted JSON field relative to this property mapper, or |
| | | * root if all attributes associated with this mapper have been |
| | | * targeted. |
| | | * @param ldapAttributes |
| | | * The set into which the required LDAP attribute names should be |
| | | * put. |
| | | */ |
| | | abstract void getLDAPAttributes(Connection connection, JsonPointer path, JsonPointer subPath, |
| | | Set<String> ldapAttributes); |
| | | abstract void getLdapAttributes(Connection connection, JsonPointer path, JsonPointer subPath, |
| | | Set<String> ldapAttributes); |
| | | |
| | | /** |
| | | * Transforms the provided REST comparison filter parameters to an LDAP |
| | |
| | | * The LDAP connection to use to perform the operation. |
| | | * @param path |
| | | * The pointer from the root of the JSON resource to this |
| | | * attribute mapper. This may be used when constructing error |
| | | * property mapper. This may be used when constructing error |
| | | * messages. |
| | | * @param subPath |
| | | * The targeted JSON field relative to this attribute mapper, or |
| | | * The targeted JSON field relative to this property mapper, or |
| | | * root if all attributes associated with this mapper have been |
| | | * targeted. |
| | | * @param type |
| | |
| | | * {@link FilterType#PRESENT}. |
| | | * @return A {@link Promise} containing the result of the operation. |
| | | */ |
| | | abstract Promise<Filter, ResourceException> getLDAPFilter(Connection connection, JsonPointer path, |
| | | JsonPointer subPath, FilterType type, String operator, Object valueAssertion); |
| | | abstract Promise<Filter, ResourceException> getLdapFilter(Connection connection, JsonPointer path, |
| | | JsonPointer subPath, FilterType type, String operator, |
| | | Object valueAssertion); |
| | | |
| | | /** |
| | | * Maps a JSON patch operation to one or more LDAP modifications, returning |
| | |
| | | * The LDAP connection to use to perform the operation. |
| | | * @param path |
| | | * The pointer from the root of the JSON resource to this |
| | | * attribute mapper. This may be used when constructing error |
| | | * property mapper. This may be used when constructing error |
| | | * messages. |
| | | * @param operation |
| | | * The JSON patch operation to be converted to LDAP |
| | | * modifications. The targeted JSON field will be relative to |
| | | * this attribute mapper, or root if all attributes associated |
| | | * this property mapper, or root if all attributes associated |
| | | * with this mapper have been targeted. |
| | | * @return A {@link Promise} containing the result of the operation. |
| | | */ |
| | |
| | | * The LDAP connection to use to perform the operation. |
| | | * @param path |
| | | * The pointer from the root of the JSON resource to this |
| | | * attribute mapper. This may be used when constructing error |
| | | * property mapper. This may be used when constructing error |
| | | * messages. |
| | | * @param e |
| | | * The LDAP entry to be converted to JSON. |
| File was renamed from opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java |
| | |
| | | import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*; |
| | | import static org.forgerock.opendj.ldap.LdapException.newLdapException; |
| | | import static org.forgerock.opendj.ldap.requests.Requests.newSearchRequest; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2LDAP.asResourceException; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2Ldap.asResourceException; |
| | | import static org.forgerock.opendj.rest2ldap.Utils.newBadRequestException; |
| | | import static org.forgerock.util.Reject.checkNotNull; |
| | | |
| | |
| | | import org.forgerock.opendj.ldap.schema.Schema; |
| | | import org.forgerock.util.AsyncFunction; |
| | | import org.forgerock.util.Function; |
| | | import org.forgerock.util.Reject; |
| | | import org.forgerock.util.promise.ExceptionHandler; |
| | | import org.forgerock.util.promise.Promise; |
| | | import org.forgerock.util.promise.PromiseImpl; |
| | |
| | | import org.forgerock.util.promise.ResultHandler; |
| | | |
| | | /** |
| | | * An attribute mapper which provides a mapping from a JSON value to a single DN |
| | | * An property mapper which provides a mapping from a JSON value to a single DN |
| | | * valued LDAP attribute. |
| | | */ |
| | | public final class ReferenceAttributeMapper extends AbstractLDAPAttributeMapper<ReferenceAttributeMapper> { |
| | | public final class ReferencePropertyMapper extends AbstractLdapPropertyMapper<ReferencePropertyMapper> { |
| | | /** |
| | | * The maximum number of candidate references to allow in search filters. |
| | | */ |
| | | private static final int SEARCH_MAX_CANDIDATES = 1000; |
| | | |
| | | private final DN baseDN; |
| | | private final DN baseDn; |
| | | private final Schema schema; |
| | | private Filter filter; |
| | | private final AttributeMapper mapper; |
| | | private final PropertyMapper mapper; |
| | | private final AttributeDescription primaryKey; |
| | | private SearchScope scope = SearchScope.WHOLE_SUBTREE; |
| | | |
| | | ReferenceAttributeMapper(final Schema schema, final AttributeDescription ldapAttributeName, final DN baseDN, |
| | | final AttributeDescription primaryKey, final AttributeMapper mapper) { |
| | | ReferencePropertyMapper(final Schema schema, final AttributeDescription ldapAttributeName, final DN baseDn, |
| | | final AttributeDescription primaryKey, final PropertyMapper mapper) { |
| | | super(ldapAttributeName); |
| | | this.schema = schema; |
| | | this.baseDN = baseDN; |
| | | this.baseDn = baseDn; |
| | | this.primaryKey = primaryKey; |
| | | this.mapper = mapper; |
| | | } |
| | |
| | | * @param filter |
| | | * The filter which should be used when searching for referenced |
| | | * LDAP entries. |
| | | * @return This attribute mapper. |
| | | * @return This property mapper. |
| | | */ |
| | | public ReferenceAttributeMapper searchFilter(final Filter filter) { |
| | | public ReferencePropertyMapper searchFilter(final Filter filter) { |
| | | this.filter = checkNotNull(filter); |
| | | return this; |
| | | } |
| | |
| | | * @param filter |
| | | * The filter which should be used when searching for referenced |
| | | * LDAP entries. |
| | | * @return This attribute mapper. |
| | | * @return This property mapper. |
| | | */ |
| | | public ReferenceAttributeMapper searchFilter(final String filter) { |
| | | public ReferencePropertyMapper searchFilter(final String filter) { |
| | | return searchFilter(Filter.valueOf(filter)); |
| | | } |
| | | |
| | |
| | | * @param scope |
| | | * The search scope which should be used when searching for |
| | | * referenced LDAP entries. |
| | | * @return This attribute mapper. |
| | | * @return This property mapper. |
| | | */ |
| | | public ReferenceAttributeMapper searchScope(final SearchScope scope) { |
| | | public ReferencePropertyMapper searchScope(final SearchScope scope) { |
| | | this.scope = checkNotNull(scope); |
| | | return this; |
| | | } |
| | |
| | | } |
| | | |
| | | @Override |
| | | Promise<Filter, ResourceException> getLDAPFilter(final Connection connection, final JsonPointer path, |
| | | final JsonPointer subPath, final FilterType type, final String operator, final Object valueAssertion) { |
| | | return mapper.getLDAPFilter(connection, path, subPath, type, operator, valueAssertion) |
| | | Promise<Filter, ResourceException> getLdapFilter(final Connection connection, final JsonPointer path, |
| | | final JsonPointer subPath, final FilterType type, |
| | | final String operator, final Object valueAssertion) { |
| | | return mapper.getLdapFilter(connection, path, subPath, type, operator, valueAssertion) |
| | | .thenAsync(new AsyncFunction<Filter, Filter, ResourceException>() { |
| | | @Override |
| | | public Promise<Filter, ResourceException> apply(final Filter result) { |
| | |
| | | } |
| | | |
| | | @Override |
| | | Promise<Attribute, ResourceException> getNewLDAPAttributes(final Connection connection, final JsonPointer path, |
| | | final List<Object> newValues) { |
| | | Promise<Attribute, ResourceException> getNewLdapAttributes(final Connection connection, final JsonPointer path, |
| | | final List<Object> newValues) { |
| | | /* |
| | | * For each value use the subordinate mapper to obtain the LDAP primary |
| | | * key, the perform a search for each one to find the corresponding entries. |
| | |
| | | } |
| | | |
| | | @Override |
| | | ReferenceAttributeMapper getThis() { |
| | | ReferencePropertyMapper getThis() { |
| | | return this; |
| | | } |
| | | |
| | |
| | | |
| | | private SearchRequest createSearchRequest(final Filter result) { |
| | | final Filter searchFilter = filter != null ? Filter.and(filter, result) : result; |
| | | return newSearchRequest(baseDN, scope, searchFilter, "1.1"); |
| | | return newSearchRequest(baseDn, scope, searchFilter, "1.1"); |
| | | } |
| | | |
| | | private Promise<JsonValue, ResourceException> readEntry( |
| | | final Connection connection, final JsonPointer path, final DN dn) { |
| | | final Set<String> requestedLDAPAttributes = new LinkedHashSet<>(); |
| | | mapper.getLDAPAttributes(connection, path, new JsonPointer(), requestedLDAPAttributes); |
| | | mapper.getLdapAttributes(connection, path, new JsonPointer(), requestedLDAPAttributes); |
| | | |
| | | final Filter searchFilter = filter != null ? filter : Filter.alwaysTrue(); |
| | | final String[] attributes = requestedLDAPAttributes.toArray(new String[requestedLDAPAttributes.size()]); |
| File was renamed from opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java |
| | |
| | | import org.forgerock.util.time.Duration; |
| | | |
| | | /** Provides core factory methods and builders for constructing LDAP resource collections. */ |
| | | public final class Rest2LDAP { |
| | | public final class Rest2Ldap { |
| | | /** Indicates whether LDAP client connections should use SSL or StartTLS. */ |
| | | private enum ConnectionSecurity { |
| | | NONE, SSL, STARTTLS |
| | |
| | | private final List<Attribute> additionalLDAPAttributes = new LinkedList<>(); |
| | | private DN baseDN; // TODO: support template variables. |
| | | private AttributeDescription etagAttribute; |
| | | private NameStrategy nameStrategy; |
| | | private NamingStrategy namingStrategy; |
| | | private ReadOnUpdatePolicy readOnUpdatePolicy = CONTROLS; |
| | | private AttributeMapper rootMapper; |
| | | private PropertyMapper rootMapper; |
| | | private Schema schema = Schema.getDefaultSchema(); |
| | | private boolean usePermissiveModify; |
| | | private boolean useSubtreeDelete; |
| | |
| | | if (rootMapper == null) { |
| | | throw new IllegalStateException(ERR_CONFIG_NO_MAPPINGS_PROVIDED.get().toString()); |
| | | } |
| | | return new LDAPCollectionResourceProvider(baseDN, rootMapper, nameStrategy, etagAttribute, |
| | | new Config(readOnUpdatePolicy, useSubtreeDelete, usePermissiveModify, schema), |
| | | additionalLDAPAttributes); |
| | | return new SubResourceImpl(baseDN, rootMapper, namingStrategy, etagAttribute, |
| | | new Config(readOnUpdatePolicy, useSubtreeDelete, usePermissiveModify, schema), |
| | | additionalLDAPAttributes); |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * Sets the attribute mapper which should be used for mapping JSON |
| | | * Sets the property mapper which should be used for mapping JSON |
| | | * resources to and from LDAP entries. |
| | | * |
| | | * @param mapper |
| | | * The attribute mapper. |
| | | * The property mapper. |
| | | * @return A reference to this LDAP resource collection builder. |
| | | */ |
| | | public Builder mapper(final AttributeMapper mapper) { |
| | | public Builder mapper(final PropertyMapper mapper) { |
| | | this.rootMapper = mapper; |
| | | return this; |
| | | } |
| | |
| | | * @return A reference to this LDAP resource collection builder. |
| | | */ |
| | | public Builder useClientDNNaming(final AttributeType attribute) { |
| | | this.nameStrategy = new DNNameStrategy(attribute); |
| | | this.namingStrategy = new DNNamingStrategy(attribute); |
| | | return this; |
| | | } |
| | | |
| | |
| | | */ |
| | | public Builder useClientNaming(final AttributeType dnAttribute, |
| | | final AttributeDescription idAttribute) { |
| | | this.nameStrategy = new AttributeNameStrategy(dnAttribute, idAttribute, false); |
| | | this.namingStrategy = new AttributeNamingStrategy(dnAttribute, idAttribute, false); |
| | | return this; |
| | | } |
| | | |
| | |
| | | */ |
| | | public Builder useServerNaming(final AttributeType dnAttribute, |
| | | final AttributeDescription idAttribute) { |
| | | this.nameStrategy = new AttributeNameStrategy(dnAttribute, idAttribute, true); |
| | | this.namingStrategy = new AttributeNamingStrategy(dnAttribute, idAttribute, true); |
| | | return this; |
| | | } |
| | | |
| | |
| | | return schema.getAttributeType(attribute); |
| | | } |
| | | |
| | | private AttributeMapper configureMapper(final JsonValue mapper) { |
| | | private PropertyMapper configureMapper(final JsonValue mapper) { |
| | | if (mapper.isDefined("constant")) { |
| | | return constant(mapper.get("constant").getObject()); |
| | | } else if (mapper.isDefined("simple")) { |
| | | final JsonValue config = mapper.get("simple"); |
| | | final SimpleAttributeMapper s = |
| | | final SimplePropertyMapper s = |
| | | simple(ad(config.get("ldapAttribute").required().asString())); |
| | | if (config.isDefined("defaultJSONValue")) { |
| | | s.defaultJSONValue(config.get("defaultJSONValue").getObject()); |
| | | s.defaultJsonValue(config.get("defaultJSONValue").getObject()); |
| | | } |
| | | if (config.get("isBinary").defaultTo(false).asBoolean()) { |
| | | s.isBinary(); |
| | |
| | | final DN baseDN = DN.valueOf(config.get("baseDN").required().asString(), schema); |
| | | final AttributeDescription primaryKey = |
| | | ad(config.get("primaryKey").required().asString()); |
| | | final AttributeMapper m = configureMapper(config.get("mapper").required()); |
| | | final ReferenceAttributeMapper r = reference(ldapAttribute, baseDN, primaryKey, m); |
| | | final PropertyMapper m = configureMapper(config.get("mapper").required()); |
| | | final ReferencePropertyMapper r = reference(ldapAttribute, baseDN, primaryKey, m); |
| | | if (config.get("isRequired").defaultTo(false).asBoolean()) { |
| | | r.isRequired(); |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | private ObjectAttributeMapper configureObjectMapper(final JsonValue mapper) { |
| | | final ObjectAttributeMapper object = object(); |
| | | private ObjectPropertyMapper configureObjectMapper(final JsonValue mapper) { |
| | | final ObjectPropertyMapper object = object(); |
| | | for (final String attribute : mapper.keys()) { |
| | | object.attribute(attribute, configureMapper(mapper.get(attribute))); |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | private static final class AttributeNameStrategy extends NameStrategy { |
| | | private static final class AttributeNamingStrategy extends NamingStrategy { |
| | | private final AttributeDescription dnAttribute; |
| | | private final AttributeDescription idAttribute; |
| | | private final boolean isServerProvided; |
| | | |
| | | private AttributeNameStrategy(final AttributeType dnAttribute, |
| | | final AttributeDescription idAttribute, final boolean isServerProvided) { |
| | | private AttributeNamingStrategy(final AttributeType dnAttribute, |
| | | final AttributeDescription idAttribute, final boolean isServerProvided) { |
| | | this.dnAttribute = AttributeDescription.create(dnAttribute); |
| | | if (this.dnAttribute.equals(idAttribute)) { |
| | | throw newLocalizedIllegalArgumentException(ERR_CONFIG_NAMING_STRATEGY_DN_AND_ID_NOT_DIFFERENT.get()); |
| | |
| | | } |
| | | |
| | | @Override |
| | | void getLDAPAttributes(final Connection connection, final Set<String> ldapAttributes) { |
| | | void getLdapAttributes(final Connection connection, final Set<String> ldapAttributes) { |
| | | ldapAttributes.add(idAttribute.toString()); |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | private static final class DNNameStrategy extends NameStrategy { |
| | | private static final class DNNamingStrategy extends NamingStrategy { |
| | | private final AttributeDescription attribute; |
| | | |
| | | private DNNameStrategy(final AttributeType attribute) { |
| | | private DNNamingStrategy(final AttributeType attribute) { |
| | | this.attribute = AttributeDescription.create(attribute); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | @Override |
| | | void getLDAPAttributes(final Connection connection, final Set<String> ldapAttributes) { |
| | | void getLdapAttributes(final Connection connection, final Set<String> ldapAttributes) { |
| | | ldapAttributes.add(attribute.toString()); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns an attribute mapper which maps a single JSON attribute to a JSON |
| | | * Returns an property mapper which maps a single JSON attribute to a JSON |
| | | * constant. |
| | | * |
| | | * @param value |
| | | * The constant JSON value (a Boolean, Number, String, Map, or |
| | | * List). |
| | | * @return The attribute mapper. |
| | | * @return The property mapper. |
| | | */ |
| | | public static AttributeMapper constant(final Object value) { |
| | | return new JSONConstantAttributeMapper(value); |
| | | public static PropertyMapper constant(final Object value) { |
| | | return new JsonConstantPropertyMapper(value); |
| | | } |
| | | |
| | | /** |
| | | * Returns an attribute mapper which maps JSON objects to LDAP attributes. |
| | | * Returns an property mapper which maps JSON objects to LDAP attributes. |
| | | * |
| | | * @return The attribute mapper. |
| | | * @return The property mapper. |
| | | */ |
| | | public static ObjectAttributeMapper object() { |
| | | return new ObjectAttributeMapper(); |
| | | public static ObjectPropertyMapper object() { |
| | | return new ObjectPropertyMapper(); |
| | | } |
| | | |
| | | /** |
| | | * Returns an attribute mapper which provides a mapping from a JSON value to |
| | | * Returns an property mapper which provides a mapping from a JSON value to |
| | | * a single DN valued LDAP attribute. |
| | | * |
| | | * @param attribute |
| | |
| | | * The search primary key LDAP attribute to use for performing |
| | | * reverse lookups. |
| | | * @param mapper |
| | | * An attribute mapper which will be used to map LDAP attributes |
| | | * An property mapper which will be used to map LDAP attributes |
| | | * in the referenced entry. |
| | | * @return The attribute mapper. |
| | | * @return The property mapper. |
| | | */ |
| | | public static ReferenceAttributeMapper reference(final AttributeDescription attribute, |
| | | final DN baseDN, final AttributeDescription primaryKey, final AttributeMapper mapper) { |
| | | return new ReferenceAttributeMapper(Schema.getDefaultSchema(), attribute, baseDN, primaryKey, mapper); |
| | | public static ReferencePropertyMapper reference(final AttributeDescription attribute, |
| | | final DN baseDN, final AttributeDescription primaryKey, |
| | | final PropertyMapper mapper) { |
| | | return new ReferencePropertyMapper(Schema.getDefaultSchema(), attribute, baseDN, primaryKey, mapper); |
| | | } |
| | | |
| | | /** |
| | | * Returns an attribute mapper which provides a mapping from a JSON value to |
| | | * Returns an property mapper which provides a mapping from a JSON value to |
| | | * a single DN valued LDAP attribute. |
| | | * |
| | | * @param attribute |
| | |
| | | * The search primary key LDAP attribute to use for performing |
| | | * reverse lookups. |
| | | * @param mapper |
| | | * An attribute mapper which will be used to map LDAP attributes |
| | | * An property mapper which will be used to map LDAP attributes |
| | | * in the referenced entry. |
| | | * @return The attribute mapper. |
| | | * @return The property mapper. |
| | | */ |
| | | public static ReferenceAttributeMapper reference(final String attribute, final String baseDN, |
| | | final String primaryKey, final AttributeMapper mapper) { |
| | | public static ReferencePropertyMapper reference(final String attribute, final String baseDN, |
| | | final String primaryKey, final PropertyMapper mapper) { |
| | | return reference(AttributeDescription.valueOf(attribute), DN.valueOf(baseDN), |
| | | AttributeDescription.valueOf(primaryKey), mapper); |
| | | } |
| | | |
| | | /** |
| | | * Returns an attribute mapper which provides a simple mapping from a JSON |
| | | * Returns an property mapper which provides a simple mapping from a JSON |
| | | * value to a single LDAP attribute. |
| | | * |
| | | * @param attribute |
| | | * The LDAP attribute to be mapped. |
| | | * @return The attribute mapper. |
| | | * @return The property mapper. |
| | | */ |
| | | public static SimpleAttributeMapper simple(final AttributeDescription attribute) { |
| | | return new SimpleAttributeMapper(attribute); |
| | | public static SimplePropertyMapper simple(final AttributeDescription attribute) { |
| | | return new SimplePropertyMapper(attribute); |
| | | } |
| | | |
| | | /** |
| | | * Returns an attribute mapper which provides a simple mapping from a JSON |
| | | * Returns an property mapper which provides a simple mapping from a JSON |
| | | * value to a single LDAP attribute. |
| | | * |
| | | * @param attribute |
| | | * The LDAP attribute to be mapped. |
| | | * @return The attribute mapper. |
| | | * @return The property mapper. |
| | | */ |
| | | public static SimpleAttributeMapper simple(final String attribute) { |
| | | public static SimplePropertyMapper simple(final String attribute) { |
| | | return simple(AttributeDescription.valueOf(attribute)); |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | private Rest2LDAP() { |
| | | private Rest2Ldap() { |
| | | // Prevent instantiation. |
| | | } |
| | | } |
| File was renamed from opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAPHttpApplication.java |
| | |
| | | import static org.forgerock.json.JsonValueFunctions.duration; |
| | | import static org.forgerock.json.JsonValueFunctions.enumConstant; |
| | | import static org.forgerock.json.JsonValueFunctions.setOf; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2LDAP.configureConnectionFactory; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2Ldap.configureConnectionFactory; |
| | | import static org.forgerock.opendj.rest2ldap.Utils.newLocalizedIllegalArgumentException; |
| | | import static org.forgerock.opendj.rest2ldap.Utils.newJsonValueException; |
| | | import static org.forgerock.opendj.rest2ldap.authz.AuthenticationStrategies.*; |
| | |
| | | import org.forgerock.util.time.TimeService; |
| | | |
| | | /** Rest2ldap HTTP application. */ |
| | | public class Rest2LDAPHttpApplication implements HttpApplication { |
| | | public class Rest2LdapHttpApplication implements HttpApplication { |
| | | private static final String DEFAULT_ROOT_FACTORY = "root"; |
| | | private static final String DEFAULT_BIND_FACTORY = "bind"; |
| | | |
| | |
| | | /** |
| | | * Default constructor called by the HTTP Framework which will use the default configuration file location. |
| | | */ |
| | | public Rest2LDAPHttpApplication() { |
| | | public Rest2LdapHttpApplication() { |
| | | this.configurationUrl = getClass().getResource("/opendj-rest2ldap-config.json"); |
| | | this.schema = Schema.getDefaultSchema(); |
| | | } |
| | |
| | | * @param schema |
| | | * The {@link Schema} used to perform DN validations |
| | | */ |
| | | public Rest2LDAPHttpApplication(final URL configurationURL, final Schema schema) { |
| | | public Rest2LdapHttpApplication(final URL configurationURL, final Schema schema) { |
| | | this.configurationUrl = checkNotNull(configurationURL, "configurationURL cannot be null"); |
| | | this.schema = checkNotNull(schema, "schema cannot be null"); |
| | | } |
| | |
| | | final Router router = new Router(); |
| | | for (final String mappingUrl : mappings.keys()) { |
| | | final JsonValue mapping = mappings.get(mappingUrl); |
| | | router.addRoute(Router.uriTemplate(mappingUrl), Rest2LDAP.builder().configureMapping(mapping).build()); |
| | | router.addRoute(Router.uriTemplate(mappingUrl), Rest2Ldap.builder().configureMapping(mapping).build()); |
| | | } |
| | | return router; |
| | | } |
| | |
| | | case SEARCH: |
| | | return buildSearchThenBindStrategy(config); |
| | | case SASL_PLAIN: |
| | | return buildSASLBindStrategy(config); |
| | | return buildSaslBindStrategy(config); |
| | | default: |
| | | throw newLocalizedIllegalArgumentException(ERR_CONFIG_UNSUPPORTED_BIND_STRATEGY.get( |
| | | strategy, BindStrategy.listValues())); |
| | |
| | | schema); |
| | | } |
| | | |
| | | private AuthenticationStrategy buildSASLBindStrategy(JsonValue config) { |
| | | private AuthenticationStrategy buildSaslBindStrategy(JsonValue config) { |
| | | return newSASLPlainStrategy( |
| | | getConnectionFactory(config.get("ldapConnectionFactory").defaultTo(DEFAULT_BIND_FACTORY).asString()), |
| | | schema, parseUserNameTemplate(config.get(AUTHZID_TEMPLATE).defaultTo("u:%s"))); |
| File was renamed from opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java |
| | |
| | | import static java.util.Collections.*; |
| | | |
| | | import static org.forgerock.opendj.ldap.Filter.*; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2LDAP.*; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2Ldap.*; |
| | | import static org.forgerock.opendj.rest2ldap.Utils.*; |
| | | import static org.forgerock.util.promise.Promises.newExceptionPromise; |
| | | import static org.forgerock.util.promise.Promises.newResultPromise; |
| | | |
| | | /** |
| | | * An attribute mapper which provides a simple mapping from a JSON value to a |
| | | * An property mapper which provides a simple mapping from a JSON value to a |
| | | * single LDAP attribute. |
| | | */ |
| | | public final class SimpleAttributeMapper extends AbstractLDAPAttributeMapper<SimpleAttributeMapper> { |
| | | public final class SimplePropertyMapper extends AbstractLdapPropertyMapper<SimplePropertyMapper> { |
| | | private Function<ByteString, ?, NeverThrowsException> decoder; |
| | | private Function<Object, ByteString, NeverThrowsException> encoder; |
| | | |
| | | SimpleAttributeMapper(final AttributeDescription ldapAttributeName) { |
| | | SimplePropertyMapper(final AttributeDescription ldapAttributeName) { |
| | | super(ldapAttributeName); |
| | | } |
| | | |
| | |
| | | * |
| | | * @param f |
| | | * The function to use for decoding LDAP attribute values. |
| | | * @return This attribute mapper. |
| | | * @return This property mapper. |
| | | */ |
| | | public SimpleAttributeMapper decoder(final Function<ByteString, ?, NeverThrowsException> f) { |
| | | public SimplePropertyMapper decoder(final Function<ByteString, ?, NeverThrowsException> f) { |
| | | this.decoder = f; |
| | | return this; |
| | | } |
| | |
| | | * |
| | | * @param defaultValue |
| | | * The default JSON value. |
| | | * @return This attribute mapper. |
| | | * @return This property mapper. |
| | | */ |
| | | public SimpleAttributeMapper defaultJSONValue(final Object defaultValue) { |
| | | this.defaultJSONValues = defaultValue != null ? singletonList(defaultValue) : emptyList(); |
| | | public SimplePropertyMapper defaultJsonValue(final Object defaultValue) { |
| | | this.defaultJsonValues = defaultValue != null ? singletonList(defaultValue) : emptyList(); |
| | | return this; |
| | | } |
| | | |
| | |
| | | * |
| | | * @param f |
| | | * The function to use for encoding LDAP attribute values. |
| | | * @return This attribute mapper. |
| | | * @return This property mapper. |
| | | */ |
| | | public SimpleAttributeMapper encoder(final Function<Object, ByteString, NeverThrowsException> f) { |
| | | public SimplePropertyMapper encoder(final Function<Object, ByteString, NeverThrowsException> f) { |
| | | this.encoder = f; |
| | | return this; |
| | | } |
| | |
| | | * mapper.encoder(...); // function that converts base 64 to binary data |
| | | * </pre> |
| | | * |
| | | * @return This attribute mapper. |
| | | * @return This property mapper. |
| | | */ |
| | | public SimpleAttributeMapper isBinary() { |
| | | public SimplePropertyMapper isBinary() { |
| | | decoder = byteStringToBase64(); |
| | | encoder = base64ToByteString(); |
| | | return this; |
| | |
| | | } |
| | | |
| | | @Override |
| | | Promise<Filter, ResourceException> getLDAPFilter(final Connection connection, final JsonPointer path, |
| | | final JsonPointer subPath, final FilterType type, final String operator, final Object valueAssertion) { |
| | | Promise<Filter, ResourceException> getLdapFilter(final Connection connection, final JsonPointer path, |
| | | final JsonPointer subPath, final FilterType type, |
| | | final String operator, final Object valueAssertion) { |
| | | if (subPath.isEmpty()) { |
| | | try { |
| | | final ByteString va = |
| | |
| | | ERR_ILLEGAL_FILTER_ASSERTION_VALUE.get(String.valueOf(valueAssertion), path), e)); |
| | | } |
| | | } else { |
| | | // This attribute mapper does not support partial filtering. |
| | | // This property mapper does not support partial filtering. |
| | | return newResultPromise(alwaysFalse()); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | Promise<Attribute, ResourceException> getNewLDAPAttributes( |
| | | Promise<Attribute, ResourceException> getNewLdapAttributes( |
| | | final Connection connection, final JsonPointer path, final List<Object> newValues) { |
| | | try { |
| | | return newResultPromise(jsonToAttribute(newValues, ldapAttributeName, encoder())); |
| | |
| | | } |
| | | |
| | | @Override |
| | | SimpleAttributeMapper getThis() { |
| | | SimplePropertyMapper getThis() { |
| | | return this; |
| | | } |
| | | |
| | |
| | | try { |
| | | final Object value; |
| | | if (attributeIsSingleValued()) { |
| | | value = |
| | | e.parseAttribute(ldapAttributeName).as(decoder(), |
| | | defaultJSONValues.isEmpty() ? null : defaultJSONValues.get(0)); |
| | | value = e.parseAttribute(ldapAttributeName) |
| | | .as(decoder(), defaultJsonValues.isEmpty() ? null : defaultJsonValues.get(0)); |
| | | } else { |
| | | final Set<Object> s = |
| | | e.parseAttribute(ldapAttributeName).asSetOf(decoder(), defaultJSONValues); |
| | | final Set<Object> s = e.parseAttribute(ldapAttributeName).asSetOf(decoder(), defaultJsonValues); |
| | | value = s.isEmpty() ? null : new ArrayList<>(s); |
| | | } |
| | | return newResultPromise(value != null ? new JsonValue(value) : null); |
| File was renamed from opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java |
| | |
| | | package org.forgerock.opendj.rest2ldap; |
| | | |
| | | import static org.forgerock.i18n.LocalizableMessage.raw; |
| | | import static org.forgerock.json.resource.Responses.newResourceResponse; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*; |
| | | import static java.util.Arrays.asList; |
| | | import static org.forgerock.opendj.ldap.Filter.alwaysFalse; |
| | |
| | | import static org.forgerock.opendj.ldap.requests.Requests.newModifyRequest; |
| | | import static org.forgerock.opendj.ldap.requests.Requests.newSearchRequest; |
| | | import static org.forgerock.opendj.rest2ldap.ReadOnUpdatePolicy.CONTROLS; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2LDAP.asResourceException; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2Ldap.asResourceException; |
| | | import static org.forgerock.opendj.rest2ldap.Utils.newBadRequestException; |
| | | import static org.forgerock.opendj.rest2ldap.Utils.newNotSupportedException; |
| | | import static org.forgerock.opendj.rest2ldap.Utils.toFilter; |
| | |
| | | * A {@code CollectionResourceProvider} implementation which maps a JSON |
| | | * resource collection to LDAP entries beneath a base DN. |
| | | */ |
| | | final class LDAPCollectionResourceProvider implements CollectionResourceProvider { |
| | | final class SubResourceImpl implements CollectionResourceProvider { |
| | | |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | |
| | | private static final DecodeOptions DECODE_OPTIONS = new DecodeOptions(); |
| | | |
| | | private final List<Attribute> additionalLDAPAttributes; |
| | | private final AttributeMapper attributeMapper; |
| | | private final DN baseDN; // TODO: support template variables. |
| | | private final PropertyMapper propertyMapper; |
| | | private final DN baseDn; // TODO: support template variables. |
| | | private final Config config; |
| | | private final AttributeDescription etagAttribute; |
| | | private final NameStrategy nameStrategy; |
| | | private final NamingStrategy namingStrategy; |
| | | |
| | | LDAPCollectionResourceProvider(final DN baseDN, final AttributeMapper mapper, |
| | | final NameStrategy nameStrategy, final AttributeDescription etagAttribute, |
| | | final Config config, final List<Attribute> additionalLDAPAttributes) { |
| | | this.baseDN = baseDN; |
| | | this.attributeMapper = mapper; |
| | | SubResourceImpl(final DN baseDn, final PropertyMapper mapper, |
| | | final NamingStrategy namingStrategy, final AttributeDescription etagAttribute, |
| | | final Config config, final List<Attribute> additionalLDAPAttributes) { |
| | | this.baseDn = baseDn; |
| | | this.propertyMapper = mapper; |
| | | this.config = config; |
| | | this.nameStrategy = nameStrategy; |
| | | this.namingStrategy = namingStrategy; |
| | | this.etagAttribute = etagAttribute; |
| | | this.additionalLDAPAttributes = additionalLDAPAttributes; |
| | | } |
| | |
| | | final CreateRequest request) { |
| | | final Connection connection = context.asContext(AuthenticatedConnectionContext.class).getConnection(); |
| | | // Calculate entry content. |
| | | return attributeMapper |
| | | return propertyMapper |
| | | .create(connection, new JsonPointer(), request.getContent()) |
| | | .thenAsync(new AsyncFunction<List<Attribute>, ResourceResponse, ResourceException>() { |
| | | @Override |
| | |
| | | addRequest.addAttribute(attribute); |
| | | } |
| | | try { |
| | | nameStrategy.setResourceId(connection, getBaseDN(), |
| | | request.getNewResourceId(), |
| | | addRequest); |
| | | namingStrategy.setResourceId(connection, getBaseDn(), |
| | | request.getNewResourceId(), |
| | | addRequest); |
| | | } catch (final ResourceException e) { |
| | | logger.error(raw(e.getLocalizedMessage()), e); |
| | | return Promises.newExceptionPromise(e); |
| | | } |
| | | if (config.readOnUpdatePolicy() == CONTROLS) { |
| | | addRequest.addControl(PostReadRequestControl.newControl(false, |
| | | getLDAPAttributes(connection, request.getFields()))); |
| | | addRequest.addControl(PostReadRequestControl.newControl( |
| | | false, getLdapAttributes(connection, request.getFields()))); |
| | | } |
| | | return connection.applyChangeAsync(addRequest) |
| | | .thenAsync( |
| | |
| | | try { |
| | | final ChangeRecord deleteRequest = newDeleteRequest(dn); |
| | | if (config.readOnUpdatePolicy() == CONTROLS) { |
| | | final String[] attributes = getLDAPAttributes(connection, request.getFields()); |
| | | final String[] attributes = getLdapAttributes(connection, request.getFields()); |
| | | deleteRequest.addControl(PreReadRequestControl.newControl(false, attributes)); |
| | | } |
| | | if (config.useSubtreeDelete()) { |
| | |
| | | List<Promise<List<Modification>, ResourceException>> promises = |
| | | new ArrayList<>(request.getPatchOperations().size()); |
| | | for (final PatchOperation operation : request.getPatchOperations()) { |
| | | promises.add(attributeMapper.patch(connection, new JsonPointer(), operation)); |
| | | promises.add(propertyMapper.patch(connection, new JsonPointer(), operation)); |
| | | } |
| | | |
| | | return Promises.when(promises).thenAsync( |
| | |
| | | } |
| | | |
| | | final List<String> attributes = |
| | | asList(getLDAPAttributes(connection, request.getFields())); |
| | | asList(getLdapAttributes(connection, request.getFields())); |
| | | if (modifyRequest.getModifications().isEmpty()) { |
| | | // This patch is a no-op so just read the entry and check its version. |
| | | return |
| | |
| | | throws ResourceException { |
| | | try { |
| | | // Fail if there is a version mismatch. |
| | | ensureMVCCVersionMatches(entry, request.getRevision()); |
| | | ensureMvccVersionMatches(entry, request.getRevision()); |
| | | return adaptEntry(connection, entry); |
| | | } catch (final Exception e) { |
| | | return Promises.newExceptionPromise(asResourceException(e)); |
| | |
| | | final Context context, final QueryRequest request, final QueryResourceHandler resourceHandler) { |
| | | final Connection connection = context.asContext(AuthenticatedConnectionContext.class).getConnection(); |
| | | // Calculate the filter (this may require the connection). |
| | | return getLDAPFilter(connection, request.getQueryFilter()) |
| | | return getLdapFilter(connection, request.getQueryFilter()) |
| | | .thenAsync(runQuery(request, resourceHandler, connection)); |
| | | } |
| | | |
| | | private Promise<Filter, ResourceException> getLDAPFilter(final Connection connection, |
| | | final QueryFilter<JsonPointer> queryFilter) { |
| | | private Promise<Filter, ResourceException> getLdapFilter(final Connection connection, |
| | | final QueryFilter<JsonPointer> queryFilter) { |
| | | final QueryFilterVisitor<Promise<Filter, ResourceException>, Void, JsonPointer> visitor = |
| | | new QueryFilterVisitor<Promise<Filter, ResourceException>, Void, JsonPointer>() { |
| | | |
| | |
| | | @Override |
| | | public Promise<Filter, ResourceException> visitContainsFilter( |
| | | final Void unused, final JsonPointer field, final Object valueAssertion) { |
| | | return attributeMapper.getLDAPFilter( |
| | | return propertyMapper.getLdapFilter( |
| | | connection, new JsonPointer(), field, FilterType.CONTAINS, null, valueAssertion); |
| | | } |
| | | |
| | | @Override |
| | | public Promise<Filter, ResourceException> visitEqualsFilter( |
| | | final Void unused, final JsonPointer field, final Object valueAssertion) { |
| | | return attributeMapper.getLDAPFilter( |
| | | return propertyMapper.getLdapFilter( |
| | | connection, new JsonPointer(), field, FilterType.EQUAL_TO, null, valueAssertion); |
| | | } |
| | | |
| | | @Override |
| | | public Promise<Filter, ResourceException> visitExtendedMatchFilter(final Void unused, |
| | | final JsonPointer field, final String operator, final Object valueAssertion) { |
| | | return attributeMapper.getLDAPFilter( |
| | | return propertyMapper.getLdapFilter( |
| | | connection, new JsonPointer(), field, FilterType.EXTENDED, operator, valueAssertion); |
| | | } |
| | | |
| | | @Override |
| | | public Promise<Filter, ResourceException> visitGreaterThanFilter( |
| | | final Void unused, final JsonPointer field, final Object valueAssertion) { |
| | | return attributeMapper.getLDAPFilter( |
| | | return propertyMapper.getLdapFilter( |
| | | connection, new JsonPointer(), field, FilterType.GREATER_THAN, null, valueAssertion); |
| | | } |
| | | |
| | | @Override |
| | | public Promise<Filter, ResourceException> visitGreaterThanOrEqualToFilter( |
| | | final Void unused, final JsonPointer field, final Object valueAssertion) { |
| | | return attributeMapper.getLDAPFilter(connection, new JsonPointer(), field, |
| | | FilterType.GREATER_THAN_OR_EQUAL_TO, null, valueAssertion); |
| | | return propertyMapper.getLdapFilter(connection, new JsonPointer(), field, |
| | | FilterType.GREATER_THAN_OR_EQUAL_TO, null, valueAssertion); |
| | | } |
| | | |
| | | @Override |
| | | public Promise<Filter, ResourceException> visitLessThanFilter( |
| | | final Void unused, final JsonPointer field, final Object valueAssertion) { |
| | | return attributeMapper.getLDAPFilter( |
| | | return propertyMapper.getLdapFilter( |
| | | connection, new JsonPointer(), field, FilterType.LESS_THAN, null, valueAssertion); |
| | | } |
| | | |
| | | @Override |
| | | public Promise<Filter, ResourceException> visitLessThanOrEqualToFilter( |
| | | final Void unused, final JsonPointer field, final Object valueAssertion) { |
| | | return attributeMapper.getLDAPFilter(connection, new JsonPointer(), field, |
| | | FilterType.LESS_THAN_OR_EQUAL_TO, null, valueAssertion); |
| | | return propertyMapper.getLdapFilter(connection, new JsonPointer(), field, |
| | | FilterType.LESS_THAN_OR_EQUAL_TO, null, valueAssertion); |
| | | } |
| | | |
| | | @Override |
| | |
| | | @Override |
| | | public Promise<Filter, ResourceException> visitPresentFilter( |
| | | final Void unused, final JsonPointer field) { |
| | | return attributeMapper.getLDAPFilter( |
| | | return propertyMapper.getLdapFilter( |
| | | connection, new JsonPointer(), field, FilterType.PRESENT, null, null); |
| | | } |
| | | |
| | | @Override |
| | | public Promise<Filter, ResourceException> visitStartsWithFilter( |
| | | final Void unused, final JsonPointer field, final Object valueAssertion) { |
| | | return attributeMapper.getLDAPFilter( |
| | | return propertyMapper.getLdapFilter( |
| | | connection, new JsonPointer(), field, FilterType.STARTS_WITH, null, valueAssertion); |
| | | } |
| | | |
| | | }; |
| | | // Note that the returned LDAP filter may be null if it could not be mapped by any attribute mappers. |
| | | // Note that the returned LDAP filter may be null if it could not be mapped by any property mappers. |
| | | return queryFilter.accept(visitor, null); |
| | | } |
| | | |
| | |
| | | } |
| | | final PromiseImpl<QueryResponse, ResourceException> promise = PromiseImpl.create(); |
| | | // Perform the search. |
| | | final String[] attributes = getLDAPAttributes(connection, request.getFields()); |
| | | final String[] attributes = getLdapAttributes(connection, request.getFields()); |
| | | final Filter searchFilter = ldapFilter == Filter.alwaysTrue() ? Filter.objectClassPresent() |
| | | : ldapFilter; |
| | | final SearchRequest searchRequest = newSearchRequest( |
| | | getBaseDN(), SearchScope.SINGLE_LEVEL, searchFilter, attributes); |
| | | getBaseDn(), SearchScope.SINGLE_LEVEL, searchFilter, attributes); |
| | | |
| | | // Add the page results control. We can support the page offset by |
| | | // reading the next offset pages, or offset x page size resources. |
| | |
| | | * The best solution is probably to process the primary search results in batches using |
| | | * the paged results control. |
| | | */ |
| | | final String id = nameStrategy.getResourceId(connection, entry); |
| | | final String id = namingStrategy.getResourceId(connection, entry); |
| | | final String revision = getRevisionFromEntry(entry); |
| | | attributeMapper.read(connection, new JsonPointer(), entry) |
| | | .thenOnResult(new ResultHandler<JsonValue>() { |
| | | propertyMapper.read(connection, new JsonPointer(), entry) |
| | | .thenOnResult(new ResultHandler<JsonValue>() { |
| | | @Override |
| | | public void handleResult(final JsonValue result) { |
| | | synchronized (sequenceLock) { |
| | |
| | | final SearchResultEntry entry) { |
| | | try { |
| | | // Fail-fast if there is a version mismatch. |
| | | ensureMVCCVersionMatches(entry, request.getRevision()); |
| | | ensureMvccVersionMatches(entry, request.getRevision()); |
| | | |
| | | // Create the modify request. |
| | | final ModifyRequest modifyRequest = newModifyRequest(entry.getName()); |
| | | if (config.readOnUpdatePolicy() == CONTROLS) { |
| | | final String[] attributes = |
| | | getLDAPAttributes(connection, request.getFields()); |
| | | getLdapAttributes(connection, request.getFields()); |
| | | modifyRequest.addControl( |
| | | PostReadRequestControl.newControl(false, attributes)); |
| | | } |
| | |
| | | addAssertionControl(modifyRequest, request.getRevision()); |
| | | |
| | | // Determine the set of changes that need to be performed. |
| | | return attributeMapper.update( |
| | | return propertyMapper.update( |
| | | connection, new JsonPointer(), entry, request.getContent()) |
| | | .thenAsync(new AsyncFunction< |
| | | .thenAsync(new AsyncFunction< |
| | | List<Modification>, ResourceResponse, ResourceException>() { |
| | | @Override |
| | | public Promise<ResourceResponse, ResourceException> apply( |
| | |
| | | } |
| | | |
| | | private Promise<ResourceResponse, ResourceException> adaptEntry(final Connection connection, final Entry entry) { |
| | | final String actualResourceId = nameStrategy.getResourceId(connection, entry); |
| | | final String actualResourceId = namingStrategy.getResourceId(connection, entry); |
| | | final String revision = getRevisionFromEntry(entry); |
| | | return attributeMapper.read(connection, new JsonPointer(), entry) |
| | | .then(new Function<JsonValue, ResourceResponse, ResourceException>() { |
| | | return propertyMapper.read(connection, new JsonPointer(), entry) |
| | | .then(new Function<JsonValue, ResourceResponse, ResourceException>() { |
| | | @Override |
| | | public ResourceResponse apply(final JsonValue value) { |
| | | return Responses.newResourceResponse( |
| | | return newResourceResponse( |
| | | actualResourceId, revision, new JsonValue(value)); |
| | | } |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | private void addAssertionControl(final ChangeRecord request, final String expectedRevision) |
| | | throws ResourceException { |
| | | if (expectedRevision != null) { |
| | | ensureMVCCSupported(); |
| | | ensureMvccSupported(); |
| | | request.addControl(AssertionRequestControl.newControl(true, Filter.equality( |
| | | etagAttribute.toString(), expectedRevision))); |
| | | } |
| | |
| | | private Promise<DN, ResourceException> doUpdateFunction(final Connection connection, final String resourceId, |
| | | final String revision) { |
| | | final String ldapAttribute = (etagAttribute != null && revision != null) ? etagAttribute.toString() : "1.1"; |
| | | final SearchRequest searchRequest = nameStrategy.createSearchRequest(connection, getBaseDN(), resourceId) |
| | | .addAttribute(ldapAttribute); |
| | | final SearchRequest searchRequest = namingStrategy.createSearchRequest(connection, getBaseDn(), resourceId) |
| | | .addAttribute(ldapAttribute); |
| | | if (searchRequest.getScope().equals(SearchScope.BASE_OBJECT)) { |
| | | // There's no point in doing a search because we already know the DN. |
| | | return Promises.newResultPromise(searchRequest.getName()); |
| | |
| | | public Promise<DN, ResourceException> apply(SearchResultEntry entry) throws ResourceException { |
| | | try { |
| | | // Fail-fast if there is a version mismatch. |
| | | ensureMVCCVersionMatches(entry, revision); |
| | | ensureMvccVersionMatches(entry, revision); |
| | | // Perform update operation. |
| | | return Promises.newResultPromise(entry.getName()); |
| | | } catch (final Exception e) { |
| | |
| | | }); |
| | | } |
| | | |
| | | private void ensureMVCCSupported() throws NotSupportedException { |
| | | private void ensureMvccSupported() throws NotSupportedException { |
| | | if (etagAttribute == null) { |
| | | throw newNotSupportedException(ERR_MVCC_NOT_SUPPORTED.get()); |
| | | } |
| | | } |
| | | |
| | | private void ensureMVCCVersionMatches(final Entry entry, final String expectedRevision) throws ResourceException { |
| | | private void ensureMvccVersionMatches(final Entry entry, final String expectedRevision) throws ResourceException { |
| | | if (expectedRevision != null) { |
| | | ensureMVCCSupported(); |
| | | ensureMvccSupported(); |
| | | final String actualRevision = entry.parseAttribute(etagAttribute).asString(); |
| | | if (actualRevision == null) { |
| | | throw new PreconditionFailedException(ERR_MVCC_NO_VERSION_INFORMATION.get(expectedRevision).toString()); |
| | |
| | | } |
| | | } |
| | | |
| | | private DN getBaseDN() { |
| | | return baseDN; |
| | | private DN getBaseDn() { |
| | | return baseDn; |
| | | } |
| | | |
| | | /** |
| | |
| | | * @return The set of LDAP attributes associated with the resource |
| | | * attributes. |
| | | */ |
| | | private String[] getLDAPAttributes(final Connection connection, final Collection<JsonPointer> requestedAttributes) { |
| | | // Get all the LDAP attributes required by the attribute mappers. |
| | | private String[] getLdapAttributes(final Connection connection, final Collection<JsonPointer> requestedAttributes) { |
| | | // Get all the LDAP attributes required by the property mappers. |
| | | final Set<String> requestedLDAPAttributes; |
| | | if (requestedAttributes.isEmpty()) { |
| | | // Full read. |
| | | requestedLDAPAttributes = new LinkedHashSet<>(); |
| | | attributeMapper.getLDAPAttributes(connection, new JsonPointer(), new JsonPointer(), |
| | | requestedLDAPAttributes); |
| | | propertyMapper.getLdapAttributes(connection, new JsonPointer(), new JsonPointer(), |
| | | requestedLDAPAttributes); |
| | | } else { |
| | | // Partial read. |
| | | requestedLDAPAttributes = new LinkedHashSet<>(requestedAttributes.size()); |
| | | for (final JsonPointer requestedAttribute : requestedAttributes) { |
| | | attributeMapper.getLDAPAttributes(connection, new JsonPointer(), requestedAttribute, |
| | | requestedLDAPAttributes); |
| | | propertyMapper.getLdapAttributes(connection, new JsonPointer(), requestedAttribute, |
| | | requestedLDAPAttributes); |
| | | } |
| | | } |
| | | |
| | | // Get the LDAP attributes required by the Etag and name stategies. |
| | | nameStrategy.getLDAPAttributes(connection, requestedLDAPAttributes); |
| | | namingStrategy.getLdapAttributes(connection, requestedLDAPAttributes); |
| | | if (etagAttribute != null) { |
| | | requestedLDAPAttributes.add(etagAttribute.toString()); |
| | | } |
| | |
| | | return adaptEntry(connection, entry); |
| | | } else { |
| | | return Promises.newResultPromise( |
| | | Responses.newResourceResponse(null, null, new JsonValue(Collections.emptyMap()))); |
| | | newResourceResponse(null, null, new JsonValue(Collections.emptyMap()))); |
| | | } |
| | | } |
| | | }; |
| | |
| | | |
| | | private SearchRequest searchRequest( |
| | | final Connection connection, final String resourceId, final List<JsonPointer> requestedAttributes) { |
| | | final String[] attributes = getLDAPAttributes(connection, requestedAttributes); |
| | | return nameStrategy.createSearchRequest(connection, getBaseDN(), resourceId).addAttribute(attributes); |
| | | final String[] attributes = getLdapAttributes(connection, requestedAttributes); |
| | | return namingStrategy.createSearchRequest(connection, getBaseDn(), resourceId).addAttribute(attributes); |
| | | } |
| | | |
| | | private static final class Exceptions { |
| | |
| | | return String.format(format, args); |
| | | } |
| | | |
| | | private static boolean isJSONPrimitive(final Object value) { |
| | | private static boolean isJsonPrimitive(final Object value) { |
| | | return value instanceof String || value instanceof Boolean || value instanceof Number; |
| | | } |
| | | |
| | |
| | | |
| | | static Attribute jsonToAttribute(final Object value, final AttributeDescription ad, |
| | | final Function<Object, ByteString, NeverThrowsException> f) { |
| | | if (isJSONPrimitive(value)) { |
| | | if (isJsonPrimitive(value)) { |
| | | return new LinkedAttribute(ad, f.apply(value)); |
| | | } else if (value instanceof Collection<?>) { |
| | | final Attribute a = new LinkedAttribute(ad); |
| | |
| | | return new Function<Object, ByteString, NeverThrowsException>() { |
| | | @Override |
| | | public ByteString apply(final Object value) { |
| | | if (isJSONPrimitive(value)) { |
| | | if (isJsonPrimitive(value)) { |
| | | final Syntax syntax = ad.getAttributeType().getSyntax(); |
| | | if (syntax.equals(getGeneralizedTimeSyntax())) { |
| | | return ByteString.valueOfObject(GeneralizedTime.valueOf(parseDateTime(value.toString()))); |
| | |
| | | */ |
| | | public static AuthenticationStrategy newSASLPlainStrategy(ConnectionFactory connectionFactory, Schema schema, |
| | | String authcIdTemplate) { |
| | | return new SASLPlainStrategy(connectionFactory, schema, authcIdTemplate); |
| | | return new SaslPlainStrategy(connectionFactory, schema, authcIdTemplate); |
| | | } |
| | | } |
| File was renamed from opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/SASLPlainStrategy.java |
| | |
| | | import org.forgerock.util.promise.Promise; |
| | | |
| | | /** Bind using a computed DN from a template and the current request/context. */ |
| | | final class SASLPlainStrategy implements AuthenticationStrategy { |
| | | final class SaslPlainStrategy implements AuthenticationStrategy { |
| | | |
| | | private final ConnectionFactory connectionFactory; |
| | | private final Function<String, String, LdapException> formatter; |
| | |
| | | * @throws NullPointerException |
| | | * If a parameter is null |
| | | */ |
| | | public SASLPlainStrategy(final ConnectionFactory connectionFactory, final Schema schema, |
| | | final String authcIdTemplate) { |
| | | public SaslPlainStrategy(final ConnectionFactory connectionFactory, final Schema schema, |
| | | final String authcIdTemplate) { |
| | | this.connectionFactory = checkNotNull(connectionFactory, "connectionFactory cannot be null"); |
| | | checkNotNull(schema, "schema cannot be null"); |
| | | checkNotNull(authcIdTemplate, "authcIdTemplate cannot be null"); |
| | |
| | | @Override |
| | | public Promise<SecurityContext, LdapException> apply(Connection connection) throws LdapException { |
| | | connectionHolder.set(connection); |
| | | return doSASLPlainBind(connection, parentContext, username, password); |
| | | return doSaslPlainBind(connection, parentContext, username, password); |
| | | } |
| | | }).thenFinally(close(connectionHolder)); |
| | | } |
| | | |
| | | private Promise<SecurityContext, LdapException> doSASLPlainBind(final Connection connection, |
| | | final Context parentContext, final String authzId, final String password) throws LdapException { |
| | | private Promise<SecurityContext, LdapException> doSaslPlainBind(final Connection connection, |
| | | final Context parentContext, final String authzId, |
| | | final String password) throws LdapException { |
| | | final String authcId = formatter.apply(authzId); |
| | | return connection |
| | | .bindAsync(newPlainSASLBindRequest(authcId, password.toCharArray()) |
| | |
| | | */ |
| | | package org.forgerock.opendj.rest2ldap.authz; |
| | | |
| | | import static org.forgerock.opendj.rest2ldap.Rest2LDAP.asResourceException; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2Ldap.asResourceException; |
| | | import static org.forgerock.util.Utils.closeSilently; |
| | | |
| | | import java.io.Closeable; |
| | |
| | | |
| | | /** |
| | | * APIs for implementing REST to LDAP gateways. The API is implemented by |
| | | * {@link org.forgerock.opendj.rest2ldap.LDAPCollectionResourceProvider} which is using a pre-established |
| | | * {@link org.forgerock.opendj.rest2ldap.SubResourceImpl} which is using a pre-established |
| | | * {@link org.forgerock.opendj.ldap.Connection} encapsulated in the |
| | | * {@link org.forgerock.opendj.rest2ldap.AuthenticatedConnectionContext}. This context is injected by the |
| | | * {@link org.forgerock.opendj.rest2ldap.authz.ProxiedAuthV2Filter} depending on the |
| | |
| | | # |
| | | # Copyright 2015 ForgeRock AS. |
| | | # |
| | | org.forgerock.opendj.rest2ldap.Rest2LDAPHttpApplication |
| | | org.forgerock.opendj.rest2ldap.Rest2LdapHttpApplication |
| | |
| | | import static org.forgerock.json.resource.Resources.newInternalConnection; |
| | | import static org.forgerock.opendj.ldap.Connections.newInternalConnectionFactory; |
| | | import static org.forgerock.opendj.ldap.Functions.byteStringToInteger; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2LDAP.constant; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2LDAP.object; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2LDAP.simple; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2Ldap.constant; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2Ldap.object; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2Ldap.simple; |
| | | import static org.forgerock.opendj.rest2ldap.TestUtils.asResource; |
| | | import static org.forgerock.opendj.rest2ldap.TestUtils.content; |
| | | import static org.forgerock.opendj.rest2ldap.TestUtils.ctx; |
| | |
| | | import org.forgerock.opendj.ldap.responses.ExtendedResult; |
| | | import org.forgerock.opendj.ldap.responses.Result; |
| | | import org.forgerock.opendj.ldif.LDIFEntryReader; |
| | | import org.forgerock.opendj.rest2ldap.Rest2LDAP.Builder; |
| | | import org.forgerock.opendj.rest2ldap.Rest2Ldap.Builder; |
| | | import org.forgerock.services.context.Context; |
| | | import org.forgerock.testng.ForgeRockTestCase; |
| | | import org.forgerock.util.query.QueryFilter; |
| | |
| | | } |
| | | |
| | | private Builder builder(final List<Request> requests) throws IOException { |
| | | return Rest2LDAP.builder() |
| | | .baseDN("dc=test") |
| | | .useEtagAttribute() |
| | | .useClientDNNaming("uid") |
| | | .readOnUpdatePolicy(ReadOnUpdatePolicy.CONTROLS) |
| | | .additionalLDAPAttribute("objectClass", "top", "person") |
| | | .mapper(object() |
| | | return Rest2Ldap.builder() |
| | | .baseDN("dc=test") |
| | | .useEtagAttribute() |
| | | .useClientDNNaming("uid") |
| | | .readOnUpdatePolicy(ReadOnUpdatePolicy.CONTROLS) |
| | | .additionalLDAPAttribute("objectClass", "top", "person") |
| | | .mapper(object() |
| | | .attribute("schemas", constant(asList("urn:scim:schemas:core:1.0"))) |
| | | .attribute("_id", simple("uid").isSingleValued() |
| | | .isRequired() |
| | |
| | | private AccessTokenResolver resolver; |
| | | |
| | | @Spy |
| | | private Rest2LDAPHttpApplication fakeApp; |
| | | private Rest2LdapHttpApplication fakeApp; |
| | | |
| | | @BeforeMethod |
| | | public void setUp() throws Exception { |
| | | MockitoAnnotations.initMocks(this); |
| | | fakeApp = spy(Rest2LDAPHttpApplication.class); |
| | | fakeApp = spy(Rest2LdapHttpApplication.class); |
| | | } |
| | | |
| | | @DataProvider |
| | |
| | | */ |
| | | package org.opends.server.protocols.http.authz; |
| | | |
| | | import static org.forgerock.opendj.rest2ldap.Rest2LDAP.asResourceException; |
| | | import static org.forgerock.opendj.rest2ldap.Rest2Ldap.asResourceException; |
| | | import static org.forgerock.services.context.SecurityContext.AUTHZID_DN; |
| | | import static org.forgerock.services.context.SecurityContext.AUTHZID_ID; |
| | | import static org.forgerock.util.Reject.checkNotNull; |
| | |
| | | import org.forgerock.json.JsonValueException; |
| | | import org.forgerock.json.resource.Router; |
| | | import org.forgerock.json.resource.http.CrestHttp; |
| | | import org.forgerock.opendj.rest2ldap.Rest2LDAP; |
| | | import org.forgerock.opendj.rest2ldap.Rest2Ldap; |
| | | import org.forgerock.opendj.server.config.server.Rest2ldapEndpointCfg; |
| | | import org.forgerock.util.Factory; |
| | | import org.opends.server.api.HttpEndpoint; |
| | |
| | | for (final String mappingUrl : mappings.keys()) |
| | | { |
| | | final JsonValue mapping = mappings.get(mappingUrl); |
| | | router.addRoute(Router.uriTemplate(mappingUrl), Rest2LDAP.builder().configureMapping(mapping).build()); |
| | | router.addRoute(Router.uriTemplate(mappingUrl), Rest2Ldap.builder().configureMapping(mapping).build()); |
| | | } |
| | | } |
| | | catch (JsonValueException e) |