From 32edddb11bcc204628fbdaddf3b0d0e86530f6f8 Mon Sep 17 00:00:00 2001
From: Gaetan Boismal <gaetan.boismal@forgerock.com>
Date: Wed, 08 Jun 2016 15:18:05 +0000
Subject: [PATCH] OPENDJ-2955 Use i18n in rest2ldap
---
opendj-rest2ldap/pom.xml | 23 ++
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAPHttpApplication.java | 63 ++++-
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/AuthzIdTemplate.java | 14
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Utils.java | 14 +
opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_ca_ES.properties | 15 +
opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_ja.properties | 15 +
opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_es.properties | 15 +
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Authorizations.java | 6
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Rfc7662AccessTokenResolver.java | 13
opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/authz/CtsAccessTokenResolverTestCase.java | 2
opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_pl.properties | 15 +
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/FileAccessTokenResolver.java | 6
opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_fr.properties | 15 +
opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_zh_CN.properties | 15 +
opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap.properties | 110 ++++++++++
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java | 23 -
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java | 35 ++
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/CtsAccessTokenResolver.java | 13
opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_zh_TW.properties | 15 +
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLDAPAttributeMapper.java | 76 +-----
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java | 17 -
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java | 16
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java | 14
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java | 28 +-
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java | 38 +-
opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_de.properties | 15 +
opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_ko.properties | 15 +
27 files changed, 463 insertions(+), 183 deletions(-)
diff --git a/opendj-rest2ldap/pom.xml b/opendj-rest2ldap/pom.xml
index f293562..f04c4de 100644
--- a/opendj-rest2ldap/pom.xml
+++ b/opendj-rest2ldap/pom.xml
@@ -60,6 +60,11 @@
</dependency>
<dependency>
+ <groupId>org.forgerock.commons</groupId>
+ <artifactId>i18n-core</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>org.forgerock.openig</groupId>
<artifactId>openig-oauth2-resource-server-filter</artifactId>
<version>${openig.version}</version>
@@ -81,6 +86,24 @@
<build>
<plugins>
<plugin>
+ <groupId>org.forgerock.commons</groupId>
+ <artifactId>i18n-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>generate-messages</goal>
+ </goals>
+ <configuration>
+ <messageFiles>
+ <messageFile>org/forgerock/opendj/rest2ldap/rest2ldap.properties</messageFile>
+ </messageFiles>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLDAPAttributeMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLDAPAttributeMapper.java
index 547dac0..d211438 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLDAPAttributeMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLDAPAttributeMapper.java
@@ -15,12 +15,14 @@
*/
package org.forgerock.opendj.rest2ldap;
+import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*;
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.Utils.i18n;
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 static org.forgerock.opendj.rest2ldap.WritabilityPolicy.READ_WRITE;
import java.util.ArrayList;
@@ -31,7 +33,6 @@
import org.forgerock.json.JsonPointer;
import org.forgerock.json.JsonValue;
import org.forgerock.json.resource.BadRequestException;
-import org.forgerock.json.resource.NotSupportedException;
import org.forgerock.json.resource.PatchOperation;
import org.forgerock.json.resource.ResourceException;
import org.forgerock.opendj.ldap.Attribute;
@@ -108,14 +109,12 @@
public List<Attribute> apply(Attribute newLDAPAttribute) throws ResourceException {
if (!writabilityPolicy.canCreate(ldapAttributeName)) {
if (!newLDAPAttribute.isEmpty() && !writabilityPolicy.discardWrites()) {
- throw new BadRequestException(i18n("The request cannot be processed because it attempts "
- + "to create the read-only field '%s'", path));
+ throw newBadRequestException(ERR_CREATION_READ_ONLY_FIELD.get(path));
}
return Collections.emptyList();
} else if (newLDAPAttribute.isEmpty()) {
if (isRequired) {
- throw new BadRequestException(i18n("The request cannot be processed because it attempts "
- + "to remove the required field '%s'", path));
+ throw newBadRequestException(ERR_REMOVE_REQUIRED_FIELD.get("create", path));
}
return Collections.emptyList();
}
@@ -148,9 +147,7 @@
* if it is configured to discard writes.
*/
if (!writabilityPolicy.canWrite(ldapAttributeName)) {
- throw new BadRequestException(i18n(
- "The request cannot be processed because it attempts to modify "
- + "the read-only field '%s'", path));
+ throw newBadRequestException(ERR_MODIFY_READ_ONLY_FIELD.get("patch", path));
}
switch (field.size()) {
@@ -164,16 +161,12 @@
if (attributeIsSingleValued()) {
if (v.isList()) {
// Single-valued field violation.
- throw new BadRequestException(i18n(
- "The request cannot be processed because an array of values was "
- + "provided for the single valued field '%s'", path));
+ throw newBadRequestException(ERR_ARRAY_FOR_SINGLE_VALUED_FIELD.get(path));
}
} else if (!v.isList() && !operation.isIncrement()
&& !(v.isNull() && (operation.isReplace() || operation.isRemove()))) {
// Multi-valued field violation.
- throw new BadRequestException(i18n(
- "The request cannot be processed because an array of values was "
- + "not provided for the multi-valued field '%s'", path));
+ throw newBadRequestException(ERR_NO_ARRAY_FOR_MULTI_VALUED_FIELD.get(path));
}
break;
case 1:
@@ -189,25 +182,16 @@
if (fieldName.equals("-") && operation.isAdd()) {
// Append a single value.
if (attributeIsSingleValued()) {
- throw new BadRequestException(i18n(
- "The request cannot be processed because it attempts to append a "
- + "value to the single valued field '%s'", path));
+ throw newBadRequestException(ERR_PATCH_APPEND_IN_SINGLE_VALUED_FIELD.get(path));
} else if (v.isList()) {
- throw new BadRequestException(i18n(
- "The request cannot be processed because it attempts to "
- + "perform an indexed append of an array of values to "
- + "the multi-valued field '%s'", path.child(fieldName)));
+ throw newBadRequestException(
+ ERR_PATCH_INDEXED_APPEND_TO_MULTI_VALUED_FIELD.get(path.child(fieldName)));
}
} else if (fieldName.matches("[0-9]+")) {
// Array index - not allowed.
- throw new NotSupportedException(i18n(
- "The request cannot be processed because it included "
- + "an indexed patch operation '%s' which is not supported "
- + "by this resource provider", path.child(fieldName)));
+ throw newNotSupportedException(ERR_PATCH_INDEXED_OPERATION.get(path.child(fieldName)));
} else {
- throw new BadRequestException(i18n(
- "The request cannot be processed because it included "
- + "an unrecognized field '%s'", path.child(fieldName)));
+ throw newBadRequestException(ERR_UNRECOGNIZED_FIELD.get(path.child(fieldName)));
}
break;
default:
@@ -215,9 +199,7 @@
* The patch operation targets the child of a sub-field. This is
* not possible for a LDAP attribute mapper.
*/
- throw new BadRequestException(i18n(
- "The request cannot be processed because it included "
- + "an unrecognized field '%s'", path.child(field.get(0))));
+ throw newBadRequestException(ERR_UNRECOGNIZED_FIELD.get(path.child(field.get(0))));
}
// Check that the values are compatible with the type of patch operation.
@@ -232,10 +214,7 @@
modType =
attributeIsSingleValued() ? ModificationType.REPLACE : ModificationType.ADD;
if (newValues.isEmpty()) {
- throw new BadRequestException(i18n(
- "The request cannot be processed because it included "
- + "an add patch operation but no value(s) for field '%s'", path
- .child(field.get(0))));
+ throw newBadRequestException(ERR_PATCH_ADD_NO_VALUE_FOR_FIELD.get(path.child(field.get(0))));
}
} else if (operation.isRemove()) {
modType = ModificationType.DELETE;
@@ -244,10 +223,7 @@
} else if (operation.isIncrement()) {
modType = ModificationType.INCREMENT;
} else {
- throw new NotSupportedException(i18n(
- "The request cannot be processed because it included "
- + "an unsupported type of patch operation '%s'", operation
- .getOperation()));
+ throw newNotSupportedException(ERR_PATCH_UNSUPPORTED_OPERATION.get(operation.getOperation()));
}
// Create the modification.
@@ -255,9 +231,7 @@
// Deleting the attribute.
if (isRequired) {
return Promises.<List<Modification>, ResourceException> newExceptionPromise(
- new BadRequestException(i18n(
- "The request cannot be processed because it attempts to remove the required field '%s'",
- path)));
+ newBadRequestException(ERR_REMOVE_REQUIRED_FIELD.get("update", path)));
} else {
return Promises.newResultPromise(
singletonList(new Modification(modType, emptyAttribute(ldapAttributeName))));
@@ -300,9 +274,7 @@
// No change.
return Collections.emptyList();
}
- throw new BadRequestException(i18n(
- "The request cannot be processed because it attempts to modify the read-only field '%s'",
- path));
+ throw newBadRequestException(ERR_MODIFY_READ_ONLY_FIELD.get("update", path));
}
if (oldLDAPAttribute.isEmpty() && newLDAPAttribute.isEmpty()) {
@@ -314,9 +286,7 @@
} else if (newLDAPAttribute.isEmpty()) {
// The attribute is being deleted - this is not allowed if the attribute is required.
if (isRequired) {
- throw new BadRequestException(i18n(
- "The request cannot be processed because it attempts to remove the required field '%s'",
- path));
+ throw newBadRequestException(ERR_REMOVE_REQUIRED_FIELD.get("update", path));
}
return singletonList(new Modification(ModificationType.REPLACE, newLDAPAttribute));
} else {
@@ -359,15 +329,11 @@
if (attributeIsSingleValued()) {
if (v != null && v.isList()) {
// Single-valued field violation.
- throw new BadRequestException(i18n(
- "The request cannot be processed because an array of values was "
- + "provided for the single valued field '%s'", path));
+ throw newBadRequestException(ERR_ARRAY_FOR_SINGLE_VALUED_FIELD.get(path));
}
} else if (v != null && !v.isList()) {
// Multi-valued field violation.
- throw new BadRequestException(i18n(
- "The request cannot be processed because an array of values was "
- + "not provided for the multi-valued field '%s'", path));
+ throw newBadRequestException(ERR_NO_ARRAY_FOR_MULTI_VALUED_FIELD.get(path));
}
}
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java
index 7d1f0a5..53fdd62 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java
@@ -15,10 +15,11 @@
*/
package org.forgerock.opendj.rest2ldap;
+import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*;
import static org.forgerock.opendj.ldap.Filter.alwaysFalse;
import static org.forgerock.opendj.ldap.Filter.alwaysTrue;
-import static org.forgerock.opendj.rest2ldap.Utils.i18n;
import static org.forgerock.opendj.rest2ldap.Utils.isNullOrEmpty;
+import static org.forgerock.opendj.rest2ldap.Utils.newBadRequestException;
import static org.forgerock.opendj.rest2ldap.Utils.toFilter;
import static org.forgerock.opendj.rest2ldap.Utils.toLowerCase;
@@ -28,7 +29,6 @@
import org.forgerock.json.JsonPointer;
import org.forgerock.json.JsonValue;
-import org.forgerock.json.resource.BadRequestException;
import org.forgerock.json.resource.PatchOperation;
import org.forgerock.json.resource.ResourceException;
import org.forgerock.opendj.ldap.Attribute;
@@ -58,8 +58,8 @@
Promise<List<Attribute>, ResourceException> create(final Connection connection, final JsonPointer path,
final JsonValue v) {
if (!isNullOrEmpty(v) && !v.getObject().equals(value.getObject())) {
- return Promises.<List<Attribute>, ResourceException> newExceptionPromise(new BadRequestException(i18n(
- "The request cannot be processed because it attempts to create the read-only field '%s'", path)));
+ return Promises.<List<Attribute>, ResourceException> newExceptionPromise(
+ newBadRequestException(ERR_CREATION_READ_ONLY_FIELD.get(path)));
} else {
return Promises.newResultPromise(Collections.<Attribute> emptyList());
}
@@ -112,8 +112,8 @@
@Override
Promise<List<Modification>, ResourceException> patch(final Connection connection, final JsonPointer path,
final PatchOperation operation) {
- return Promises.<List<Modification>, ResourceException> newExceptionPromise(new BadRequestException(i18n(
- "The request cannot be processed because it attempts to patch the read-only field '%s'", path)));
+ return Promises.<List<Modification>, ResourceException> newExceptionPromise(
+ newBadRequestException(ERR_PATCH_READ_ONLY_FIELD.get(path)));
}
@Override
@@ -125,8 +125,8 @@
Promise<List<Modification>, ResourceException> update(
final Connection connection, final JsonPointer path, final Entry e, final JsonValue v) {
if (!isNullOrEmpty(v) && !v.getObject().equals(value.getObject())) {
- return Promises.<List<Modification>, ResourceException> newExceptionPromise(new BadRequestException(i18n(
- "The request cannot be processed because it attempts to modify the read-only field '%s'", path)));
+ return Promises.<List<Modification>, ResourceException> newExceptionPromise(
+ newBadRequestException(ERR_MODIFY_READ_ONLY_FIELD.get("update", path)));
} else {
return Promises.newResultPromise(Collections.<Modification> emptyList());
}
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java
index c150a44..e0ff373 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java
@@ -15,6 +15,7 @@
*/
package org.forgerock.opendj.rest2ldap;
+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.Filter.alwaysTrue;
@@ -24,7 +25,8 @@
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.Utils.i18n;
+import static org.forgerock.opendj.rest2ldap.Utils.newBadRequestException;
+import static org.forgerock.opendj.rest2ldap.Utils.newNotSupportedException;
import static org.forgerock.opendj.rest2ldap.Utils.toFilter;
import java.nio.charset.StandardCharsets;
@@ -135,7 +137,7 @@
public Promise<ActionResponse, ResourceException> actionCollection(
final Context context, final ActionRequest request) {
return Promises.<ActionResponse, ResourceException> newExceptionPromise(
- new NotSupportedException("Not yet implemented"));
+ newNotSupportedException(ERR_NOT_YET_IMPLEMENTED.get()));
}
@Override
@@ -146,7 +148,7 @@
return passwordModify(context, resourceId, request);
}
return Promises.<ActionResponse, ResourceException> newExceptionPromise(
- new NotSupportedException("The action '" + actionId + "' is not supported"));
+ newNotSupportedException(ERR_ACTION_NOT_SUPPORTED.get(actionId)));
}
private Promise<ActionResponse, ResourceException> passwordModify(
@@ -154,12 +156,12 @@
if (!context.containsContext(ClientContext.class)
|| !context.asContext(ClientContext.class).isSecure()) {
return Promises.newExceptionPromise(ResourceException.newResourceException(
- ResourceException.FORBIDDEN, "Password modify requires a secure connection."));
+ ResourceException.FORBIDDEN, ERR_PASSWORD_MODIFY_SECURE_CONNECTION.get().toString()));
}
if (!context.containsContext(SecurityContext.class)
|| context.asContext(SecurityContext.class).getAuthenticationId() == null) {
return Promises.newExceptionPromise(ResourceException.newResourceException(
- ResourceException.FORBIDDEN, "Password modify requires user to be authenticated."));
+ ResourceException.FORBIDDEN, ERR_PASSWORD_MODIFY_USER_AUTHENTICATED.get().toString()));
}
final JsonValue jsonContent = request.getContent();
@@ -169,8 +171,8 @@
oldPassword = jsonContent.get("oldPassword").asString();
newPassword = jsonContent.get("newPassword").asString();
} catch (JsonValueException e) {
- return Promises.newExceptionPromise(
- ResourceException.newResourceException(ResourceException.BAD_REQUEST, e.getLocalizedMessage(), e));
+ final ResourceException ex = newBadRequestException(ERR_PASSWORD_MODIFY_REQUEST_IS_INVALID.get(), e);
+ return Promises.newExceptionPromise(ex);
}
final Connection connection = context.asContext(AuthenticatedConnectionContext.class).getConnection();
@@ -844,8 +846,7 @@
private void ensureMVCCSupported() throws NotSupportedException {
if (etagAttribute == null) {
- throw new NotSupportedException(
- i18n("Multi-version concurrency control is not supported by this resource"));
+ throw newNotSupportedException(ERR_MVCC_NOT_SUPPORTED.get());
}
}
@@ -854,13 +855,10 @@
ensureMVCCSupported();
final String actualRevision = entry.parseAttribute(etagAttribute).asString();
if (actualRevision == null) {
- throw new PreconditionFailedException(i18n(
- "The resource could not be accessed because it did not contain any "
- + "version information, when the version '%s' was expected", expectedRevision));
+ throw new PreconditionFailedException(ERR_MVCC_NO_VERSION_INFORMATION.get(expectedRevision).toString());
} else if (!expectedRevision.equals(actualRevision)) {
- throw new PreconditionFailedException(i18n(
- "The resource could not be accessed because the expected version '%s' "
- + "does not match the current version '%s'", expectedRevision, actualRevision));
+ throw new PreconditionFailedException(
+ ERR_MVCC_VERSIONS_MISMATCH.get(expectedRevision, actualRevision).toString());
}
}
}
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java
index 508d424..984dd69 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java
@@ -15,10 +15,11 @@
*/
package org.forgerock.opendj.rest2ldap;
+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.Utils.i18n;
+import static org.forgerock.opendj.rest2ldap.Utils.newBadRequestException;
import static org.forgerock.opendj.rest2ldap.Utils.toLowerCase;
import java.util.AbstractMap.SimpleImmutableEntry;
@@ -31,7 +32,6 @@
import org.forgerock.json.JsonPointer;
import org.forgerock.json.JsonValue;
-import org.forgerock.json.resource.BadRequestException;
import org.forgerock.json.resource.PatchOperation;
import org.forgerock.json.resource.ResourceException;
import org.forgerock.opendj.ldap.Attribute;
@@ -196,9 +196,7 @@
final String fieldName = field.get(0);
final Mapping mapping = getMapping(fieldName);
if (mapping == null) {
- throw new BadRequestException(i18n(
- "The request cannot be processed because it included "
- + "an unrecognized field '%s'", path.child(fieldName)));
+ throw newBadRequestException(ERR_UNRECOGNIZED_FIELD.get(path.child(fieldName)));
}
final PatchOperation subOperation =
operation(operation.getOperation(), field.relativePointer(), v);
@@ -314,16 +312,11 @@
if (v.isMap()) {
for (final String attribute : v.asMap().keySet()) {
if (missingMappings.remove(toLowerCase(attribute)) == null) {
- throw new BadRequestException(i18n(
- "The request cannot be processed because it included "
- + "an unrecognized field '%s'", path.child(attribute)));
+ throw newBadRequestException(ERR_UNRECOGNIZED_FIELD.get(path.child(attribute)));
}
}
} else {
- throw new BadRequestException(i18n(
- "The request cannot be processed because it included "
- + "the field '%s' whose value is the wrong type: "
- + "an object is expected", path));
+ throw newBadRequestException(ERR_FIELD_WRONG_TYPE.get(path));
}
}
return missingMappings;
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java
index 140a94c..b599436 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java
@@ -15,11 +15,12 @@
*/
package org.forgerock.opendj.rest2ldap;
+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.Utils.ensureNotNull;
-import static org.forgerock.opendj.rest2ldap.Utils.i18n;
+import static org.forgerock.opendj.rest2ldap.Utils.newBadRequestException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
@@ -31,7 +32,6 @@
import org.forgerock.json.JsonPointer;
import org.forgerock.json.JsonValue;
-import org.forgerock.json.resource.BadRequestException;
import org.forgerock.json.resource.ResourceException;
import org.forgerock.opendj.ldap.Attribute;
import org.forgerock.opendj.ldap.AttributeDescription;
@@ -206,15 +206,12 @@
}
if (primaryKeyAttribute == null || primaryKeyAttribute.isEmpty()) {
- promise.handleException(new BadRequestException(
- i18n("The request cannot be processed because the reference field '%s' contains "
- + "a value which does not contain a primary key", path)));
+ promise.handleException(newBadRequestException(ERR_REFERENCE_FIELD_NO_PRIMARY_KEY.get(path)));
}
if (primaryKeyAttribute.size() > 1) {
- promise.handleException(new BadRequestException(
- i18n("The request cannot be processed because the reference field '%s' contains "
- + "a value which contains multiple primary keys", path)));
+ promise.handleException(
+ newBadRequestException(ERR_REFERENCE_FIELD_MULTIPLE_PRIMARY_KEYS.get(path)));
}
// Now search for the referenced entry in to get its DN.
@@ -237,15 +234,11 @@
try {
throw error;
} catch (final EntryNotFoundException e) {
- re = new BadRequestException(i18n(
- "The request cannot be processed because the resource "
- + "'%s' referenced in field '%s' does not exist",
+ re = newBadRequestException(ERR_REFERENCE_FIELD_DOES_NOT_EXIST.get(
primaryKeyValue.toString(), path));
} catch (final MultipleEntriesFoundException e) {
- re = new BadRequestException(i18n(
- "The request cannot be processed because the resource "
- + "'%s' referenced in field '%s' is ambiguous",
- primaryKeyValue.toString(), path));
+ re = newBadRequestException(
+ ERR_REFERENCE_FIELD_AMBIGUOUS.get(primaryKeyValue.toString(), path));
} catch (final LdapException e) {
re = asResourceException(e);
}
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
index 32fba74..4aa085f 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
@@ -15,6 +15,7 @@
*/
package org.forgerock.opendj.rest2ldap;
+import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*;
import static java.util.Arrays.asList;
import static org.forgerock.json.resource.ResourceException.newResourceException;
import static org.forgerock.opendj.ldap.Connections.newCachedConnectionPool;
@@ -26,6 +27,9 @@
import static org.forgerock.opendj.ldap.schema.CoreSchema.getEntryUUIDAttributeType;
import static org.forgerock.opendj.rest2ldap.ReadOnUpdatePolicy.CONTROLS;
import static org.forgerock.opendj.rest2ldap.Utils.ensureNotNull;
+import static org.forgerock.opendj.rest2ldap.Utils.newBadRequestException;
+import static org.forgerock.opendj.rest2ldap.Utils.newLocalizedIllegalArgumentException;
+import static org.forgerock.opendj.rest2ldap.Utils.newJsonValueException;
import static org.forgerock.util.time.Duration.*;
import java.io.IOException;
@@ -39,8 +43,6 @@
import java.util.concurrent.TimeUnit;
import org.forgerock.json.JsonValue;
-import org.forgerock.json.JsonValueException;
-import org.forgerock.json.resource.BadRequestException;
import org.forgerock.json.resource.CollectionResourceProvider;
import org.forgerock.json.resource.ResourceException;
import org.forgerock.opendj.ldap.AssertionFailureException;
@@ -170,7 +172,7 @@
public CollectionResourceProvider build() {
ensureNotNull(baseDN);
if (rootMapper == null) {
- throw new IllegalStateException("No mappings provided");
+ throw new IllegalStateException(ERR_CONFIG_NO_MAPPINGS_PROVIDED.get().toString());
}
return new LDAPCollectionResourceProvider(baseDN, rootMapper, nameStrategy, etagAttribute,
new Config(readOnUpdatePolicy, useSubtreeDelete, usePermissiveModify, schema),
@@ -215,8 +217,8 @@
useServerNaming(namingStrategy.get("dnAttribute").required().asString(),
namingStrategy.get("idAttribute").required().asString());
} else {
- throw new IllegalArgumentException(
- "Illegal naming strategy. Must be one of: clientDNNaming, clientNaming, or serverNaming");
+ throw newLocalizedIllegalArgumentException(ERR_CONFIG_UNKNOWN_NAMING_CONFIGURATION.get(
+ namingStrategy.asString(), "clientDNNaming, clientNaming or serverNaming"));
}
}
@@ -586,8 +588,8 @@
} else if (mapper.isDefined("object")) {
return configureObjectMapper(mapper.get("object"));
} else {
- throw new JsonValueException(mapper,
- "Illegal mapping: must contain constant, simple, or object");
+ throw newJsonValueException(mapper, ERR_CONFIG_NO_MAPPING_IN_CONFIGURATION.get(
+ "constant, simple, reference or object"));
}
}
@@ -613,9 +615,8 @@
} else if (writability.equalsIgnoreCase("readWrite")) {
return WritabilityPolicy.READ_WRITE;
} else {
- throw new JsonValueException(mapper,
- "Illegal writability: must be one of readOnly, readOnlyDiscardWrites, "
- + "createOnly, createOnlyDiscardWrites, or readWrite");
+ throw newJsonValueException(mapper, ERR_CONFIG_UNKNOWN_WRITABILITY.get(writability,
+ "readOnly, readOnlyDiscardWrites, createOnly, createOnlyDiscardWrites, or readWrite"));
}
} else {
return WritabilityPolicy.READ_WRITE;
@@ -632,7 +633,7 @@
final AttributeDescription idAttribute, final boolean isServerProvided) {
this.dnAttribute = AttributeDescription.create(dnAttribute);
if (this.dnAttribute.equals(idAttribute)) {
- throw new IllegalArgumentException("DN and ID attributes must be different");
+ throw newLocalizedIllegalArgumentException(ERR_CONFIG_NAMING_STRATEGY_DN_AND_ID_NOT_DIFFERENT.get());
}
this.idAttribute = ensureNotNull(idAttribute);
this.isServerProvided = isServerProvided;
@@ -659,8 +660,7 @@
final Entry entry) throws ResourceException {
if (isServerProvided) {
if (resourceId != null) {
- throw new BadRequestException("Resources cannot be created with a "
- + "client provided resource ID");
+ throw newBadRequestException(ERR_CLIENT_PROVIDER_RESOURCE_ID_MISSING.get());
}
} else {
entry.addAttribute(new LinkedAttribute(idAttribute, ByteString.valueOfUtf8(resourceId)));
@@ -703,8 +703,7 @@
} else if (entry.getAttribute(attribute) != null) {
entry.setName(baseDN.child(rdn(entry.parseAttribute(attribute).asString())));
} else {
- throw new BadRequestException("Resources cannot be created without a "
- + "client provided resource ID");
+ throw newBadRequestException(ERR_CLIENT_PROVIDER_RESOURCE_ID_MISSING.get());
}
}
@@ -937,7 +936,7 @@
simple.get("bindPassword").required().asString().toCharArray());
options.set(AUTHN_BIND_REQUEST, bindRequest);
} else {
- throw new IllegalArgumentException("Only simple authentication is supported");
+ throw newLocalizedIllegalArgumentException(ERR_CONFIG_INVALID_AUTHENTICATION.get());
}
}
@@ -995,7 +994,7 @@
secondary = parseLDAPServers(secondaryLDAPServers, connectionPoolSize, options);
}
} else if (!secondaryLDAPServers.isNull()) {
- throw new IllegalArgumentException("Invalid secondaryLDAPServers configuration");
+ throw newLocalizedIllegalArgumentException(ERR_CONFIG_INVALID_SECONDARY_LDAP_SERVER.get());
}
// Create fail-over.
@@ -1010,10 +1009,7 @@
final String name, final int depth) {
// Protect against infinite recursion in the configuration.
if (depth > 100) {
- throw new IllegalArgumentException(
- "The LDAP server configuration '"
- + name
- + "' could not be parsed because of potential circular inheritance dependencies");
+ throw newLocalizedIllegalArgumentException(ERR_CONFIG_SERVER_CIRCULAR_DEPENDENCIES.get(name));
}
final JsonValue current = configuration.get(name).required();
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAPHttpApplication.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAPHttpApplication.java
index b994823..3e312f7 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAPHttpApplication.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAPHttpApplication.java
@@ -16,17 +16,21 @@
package org.forgerock.opendj.rest2ldap;
+import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*;
import static org.forgerock.http.util.Json.readJsonLenient;
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.Utils.newLocalizedIllegalArgumentException;
+import static org.forgerock.opendj.rest2ldap.Utils.newJsonValueException;
import static org.forgerock.opendj.rest2ldap.authz.AuthenticationStrategies.*;
import static org.forgerock.opendj.rest2ldap.authz.Authorizations.*;
import static org.forgerock.opendj.rest2ldap.authz.ConditionalFilters.*;
import static org.forgerock.opendj.rest2ldap.authz.CredentialExtractors.*;
import static org.forgerock.util.Reject.checkNotNull;
import static org.forgerock.util.Utils.closeSilently;
+import static org.forgerock.util.Utils.joinAsString;
import java.io.IOException;
import java.io.InputStream;
@@ -57,7 +61,6 @@
import org.forgerock.http.io.Buffer;
import org.forgerock.http.protocol.Headers;
import org.forgerock.json.JsonValue;
-import org.forgerock.json.JsonValueException;
import org.forgerock.json.resource.RequestHandler;
import org.forgerock.json.resource.Router;
import org.forgerock.json.resource.http.CrestHttp;
@@ -112,16 +115,39 @@
/** Define the method which should be used to resolve an OAuth2 access token. */
private enum OAuth2ResolverType {
- RFC7662,
- OPENAM,
- CTS,
- FILE
+ RFC7662, OPENAM, CTS, FILE;
+
+ private static String listValues() {
+ final List<String> values = new ArrayList<>();
+ for (final OAuth2ResolverType value : OAuth2ResolverType.values()) {
+ values.add(value.name().toLowerCase());
+ }
+ return joinAsString(",", values);
+ }
}
@VisibleForTesting
enum Policy { OAUTH2, BASIC, ANONYMOUS }
- private enum BindStrategy { SIMPLE, SEARCH, SASL_PLAIN }
+ private enum BindStrategy {
+ SIMPLE("simple"),
+ SEARCH("search"),
+ SASL_PLAIN("sasl-plain");
+
+ private final String jsonField;
+
+ BindStrategy(final String jsonField) {
+ this.jsonField = jsonField;
+ }
+
+ private static String listValues() {
+ final List<String> values = new ArrayList<>();
+ for (final BindStrategy mapping : BindStrategy.values()) {
+ values.add(mapping.jsonField);
+ }
+ return joinAsString(",", values);
+ }
+ }
/**
* Default constructor called by the HTTP Framework which will use the default configuration file location.
@@ -154,8 +180,7 @@
CrestHttp.newHttpHandler(configureRest2Ldap(configuration)),
buildAuthorizationFilter(configuration.get("authorization").required()));
} catch (final Exception e) {
- // TODO i18n, once supported in opendj-rest2ldap
- final String errorMsg = "Unable to start Rest2Ldap Http Application";
+ final String errorMsg = ERR_FAIL_PARSE_CONFIGURATION.get(e.getLocalizedMessage()).toString();
LOG.error(errorMsg, e);
stop();
throw new HttpApplicationException(errorMsg, e);
@@ -267,7 +292,9 @@
case FILE:
return newFileAccessTokenResolver(configuration.get("file").get("folderPath").required().asString());
default:
- throw new JsonValueException(resolver, "is not a supported access token resolver");
+ throw newJsonValueException(resolver,
+ ERR_CONFIG_OAUTH2_UNSUPPORTED_ACCESS_TOKEN_RESOLVER.get(
+ resolver.getObject(), OAuth2ResolverType.listValues()));
}
}
@@ -280,8 +307,8 @@
rfc7662.get("clientId").required().asString(),
rfc7662.get("clientSecret").required().asString());
} catch (final URISyntaxException e) {
- throw new IllegalArgumentException("The token introspection endpoint '"
- + introspectionEndPointURL + "' URL has an invalid syntax: " + e.getLocalizedMessage(), e);
+ throw new IllegalArgumentException(ERR_CONIFG_OAUTH2_INVALID_INTROSPECT_URL.get(
+ introspectionEndPointURL, e.getLocalizedMessage()).toString(), e);
}
}
@@ -289,15 +316,14 @@
try {
final Duration expiration = expirationJson.as(duration());
if (expiration.isZero() || expiration.isUnlimited()) {
- throw new JsonValueException(expirationJson, "The cache expiration duration cannot be "
- + (expiration.isZero() ? "zero" : "unlimited."));
+ throw newJsonValueException(expirationJson,
+ expiration.isZero() ? ERR_CONIFG_OAUTH2_CACHE_ZERO_DURATION.get()
+ : ERR_CONIFG_OAUTH2_CACHE_UNLIMITED_DURATION.get());
}
return expiration;
} catch (final Exception e) {
- throw new JsonValueException(expirationJson,
- "Malformed duration value '" + expirationJson.toString() + "' for cache expiration. "
- + "The duration syntax supports all human readable notations from day ('days'', 'day'', 'd'') "
- + "to nanosecond ('nanoseconds', 'nanosecond', 'nanosec', 'nanos', 'nano', 'ns')");
+ throw newJsonValueException(expirationJson,
+ ERR_CONFIG_OAUTH2_CACHE_INVALID_DURATION.get(expirationJson.toString()));
}
}
@@ -381,7 +407,8 @@
case SASL_PLAIN:
return buildSASLBindStrategy(config);
default:
- throw new IllegalArgumentException("Unsupported strategy '" + strategy + "'");
+ throw newLocalizedIllegalArgumentException(ERR_CONFIG_UNSUPPORTED_BIND_STRATEGY.get(
+ strategy, BindStrategy.listValues()));
}
}
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
index b6d3d4a..dc36f31 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
@@ -15,13 +15,14 @@
*/
package org.forgerock.opendj.rest2ldap;
+import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.forgerock.json.JsonPointer;
import org.forgerock.json.JsonValue;
-import org.forgerock.json.resource.BadRequestException;
import org.forgerock.json.resource.ResourceException;
import org.forgerock.opendj.ldap.Attribute;
import org.forgerock.opendj.ldap.AttributeDescription;
@@ -124,10 +125,8 @@
return newResultPromise(toFilter(type, ldapAttributeName.toString(), va));
} catch (final Exception e) {
// Invalid assertion value - bad request.
- return newExceptionPromise((ResourceException) new BadRequestException(i18n(
- "The request cannot be processed because it contained an "
- + "illegal filter assertion value '%s' for field '%s'",
- String.valueOf(valueAssertion), path), e));
+ return newExceptionPromise((ResourceException) newBadRequestException(
+ ERR_ILLEGAL_FILTER_ASSERTION_VALUE.get(String.valueOf(valueAssertion), path), e));
}
} else {
// This attribute mapper does not support partial filtering.
@@ -141,9 +140,8 @@
try {
return newResultPromise(jsonToAttribute(newValues, ldapAttributeName, encoder()));
} catch (final Exception ex) {
- return newExceptionPromise((ResourceException) new BadRequestException(i18n(
- "The request cannot be processed because an error occurred while "
- + "encoding the values for the field '%s': %s", path, ex.getMessage())));
+ return newExceptionPromise((ResourceException) newBadRequestException(
+ ERR_ENCODING_VALUES_FOR_FIELD.get(path, ex.getMessage())));
}
}
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
index e810f21..b67dda7 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
@@ -11,10 +11,11 @@
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions Copyright [year] [name of copyright owner]".
*
- * Copyright 2012-2015 ForgeRock AS.
+ * Copyright 2012-2016 ForgeRock AS.
*/
package org.forgerock.opendj.rest2ldap;
+import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*;
import static javax.xml.bind.DatatypeConverter.parseDateTime;
import static javax.xml.bind.DatatypeConverter.printDateTime;
import static org.forgerock.opendj.ldap.Filter.alwaysFalse;
@@ -32,7 +33,12 @@
import java.util.List;
import java.util.Locale;
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.forgerock.json.JsonValue;
+import org.forgerock.json.JsonValueException;
+import org.forgerock.json.resource.BadRequestException;
+import org.forgerock.json.resource.NotSupportedException;
import org.forgerock.opendj.ldap.Attribute;
import org.forgerock.opendj.ldap.AttributeDescription;
import org.forgerock.opendj.ldap.ByteString;
@@ -152,8 +158,7 @@
}
return a;
} else {
- throw new IllegalArgumentException("Unrecognized type of JSON value: "
- + value.getClass().getName());
+ throw newLocalizedIllegalArgumentException(ERR_UNRECOGNIZED_JSON_VALUE.get(value.getClass().getName()));
}
}
@@ -169,8 +174,8 @@
return ByteString.valueOfObject(value);
}
} else {
- throw new IllegalArgumentException("Unrecognized type of JSON value: "
- + value.getClass().getName());
+ throw newLocalizedIllegalArgumentException(
+ ERR_UNRECOGNIZED_JSON_VALUE.get(value.getClass().getName()));
}
}
};
@@ -208,6 +213,26 @@
return s != null ? s.toLowerCase(Locale.ENGLISH) : null;
}
+ static NotSupportedException newNotSupportedException(final LocalizableMessage message) {
+ return new NotSupportedException(message.toString());
+ }
+
+ static JsonValueException newJsonValueException(final JsonValue value, final LocalizableMessage message) {
+ return new JsonValueException(value, message.toString());
+ }
+
+ static LocalizedIllegalArgumentException newLocalizedIllegalArgumentException(final LocalizableMessage message) {
+ return new LocalizedIllegalArgumentException(message);
+ }
+
+ static BadRequestException newBadRequestException(final LocalizableMessage message) {
+ return newBadRequestException(message, null);
+ }
+
+ static BadRequestException newBadRequestException(final LocalizableMessage message, final Throwable cause) {
+ return new BadRequestException(message.toString(), cause);
+ }
+
private static <T> List<T> asList(final Collection<T> c) {
if (c instanceof List) {
return (List<T>) c;
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Authorizations.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Authorizations.java
index 16ad36a..9324c98 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Authorizations.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Authorizations.java
@@ -15,6 +15,7 @@
*/
package org.forgerock.opendj.rest2ldap.authz;
+import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*;
import static org.forgerock.opendj.rest2ldap.authz.ConditionalFilters.asConditionalFilter;
import static org.forgerock.opendj.rest2ldap.authz.ConditionalFilters.newConditionalFilter;
import static org.forgerock.util.promise.Promises.newResultPromise;
@@ -266,8 +267,9 @@
try {
authz.put(template.getSecurityContextID(), template.formatAsAuthzId(token.asJsonValue()));
} catch (final IllegalArgumentException e) {
- return newResultPromise(
- new Response().setStatus(Status.FORBIDDEN).setCause(e).setEntity("Invalid configuration"));
+ return newResultPromise(new Response().setStatus(Status.FORBIDDEN)
+ .setCause(e)
+ .setEntity(ERR_AUTHZID_DECODER_RESPONSE.get().toString()));
}
final Context securityContext = new SecurityContext(context, token.getToken(), authz);
return next.handle(securityContext, request);
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/AuthzIdTemplate.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/AuthzIdTemplate.java
index 589bb5b..096ad78 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/AuthzIdTemplate.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/AuthzIdTemplate.java
@@ -15,6 +15,8 @@
*/
package org.forgerock.opendj.rest2ldap.authz;
+import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*;
+import static org.forgerock.opendj.rest2ldap.authz.Utils.newIllegalArgumentException;
import static org.forgerock.util.Utils.joinAsString;
import java.util.ArrayList;
@@ -87,8 +89,8 @@
return type;
}
}
- throw new IllegalArgumentException("Invalid authorization ID template: '" + template + "'. Templates must "
- + "start with one of the following elements: " + joinAsString(",", getSupportedStartKeys()));
+ throw newIllegalArgumentException(
+ ERR_CONFIG_INVALID_AUTHZID_TEMPLATE.get(template, joinAsString(",", getSupportedStartKeys())));
}
private static List<String> getSupportedStartKeys() {
@@ -162,16 +164,12 @@
final String key = keys.get(i);
final JsonValue value = principals.get(new JsonPointer(key));
if (value == null) {
- throw new IllegalArgumentException(String.format(
- "The request could not be authorized because the required "
- + "security principal '%s' could not be determined", key));
+ throw newIllegalArgumentException(ERR_AUTHZID_DECODER_PRINCIPAL_CANNOT_BE_DETERMINED.get(key));
}
final Object object = value.getObject();
if (!isJSONPrimitive(object)) {
- throw new IllegalArgumentException(String.format(
- "The request could not be authorized because the required "
- + "security principal '%s' had an invalid data type", key));
+ throw newIllegalArgumentException(ERR_AUTHZID_DECODER_PRINCIPAL_INVALID_DATA_TYPE.get(key));
}
values[i] = String.valueOf(object);
}
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/CtsAccessTokenResolver.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/CtsAccessTokenResolver.java
index 253726a..0a0e957 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/CtsAccessTokenResolver.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/CtsAccessTokenResolver.java
@@ -15,8 +15,10 @@
*/
package org.forgerock.opendj.rest2ldap.authz;
+import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*;
import static org.forgerock.opendj.ldap.requests.Requests.newSingleEntrySearchRequest;
import static org.forgerock.opendj.rest2ldap.authz.Utils.close;
+import static org.forgerock.opendj.rest2ldap.authz.Utils.newAccessTokenException;
import static org.forgerock.util.Reject.checkNotNull;
import java.io.IOException;
@@ -78,8 +80,7 @@
final String tokenName = getRequiredFirstValue(accessToken.get("tokenName"));
if (!tokenName.equals("access_token")) {
- throw new AccessTokenException(
- "The token '" + token + "' must be an access token, but it is a \"" + tokenName + "\"");
+ throw newAccessTokenException(ERR_OAUTH2_CTS_INVALID_TOKEN_TYPE.get(token, tokenName));
}
return new AccessTokenInfo(accessToken, token,
@@ -89,14 +90,12 @@
}, new Function<LdapException, AccessTokenInfo, AccessTokenException>() {
@Override
public AccessTokenInfo apply(final LdapException e) throws AccessTokenException {
- throw new AccessTokenException("Unable to find the token '" + token + "' in the CTS because: "
- + e.getMessage(), e);
+ throw newAccessTokenException(ERR_OAUTH2_CTS_TOKEN_NOT_FOUND.get(token, e.getMessage()), e);
}
}).thenCatchRuntimeException(new Function<RuntimeException, AccessTokenInfo, AccessTokenException>() {
@Override
public AccessTokenInfo apply(final RuntimeException e) throws AccessTokenException {
- throw new AccessTokenException("Unable to resolve access token '" + token
- + "' due to the following reason: " + e.getMessage(), e);
+ throw newAccessTokenException(ERR_OAUTH2_CTS_TOKEN_RESOLUTION.get(token, e.getMessage()), e);
}
}).thenFinally(close(connectionHolder));
}
@@ -109,7 +108,7 @@
try {
return new JsonValue(Json.readJson(accessTokenJson));
} catch (final IOException e) {
- throw new AccessTokenException("Json of token '" + token + "' is malformed");
+ throw newAccessTokenException(ERR_OAUTH2_CTS_INVALID_JSON_TOKEN.get(token));
}
}
}
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/FileAccessTokenResolver.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/FileAccessTokenResolver.java
index dca7987..65f16a1 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/FileAccessTokenResolver.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/FileAccessTokenResolver.java
@@ -15,6 +15,8 @@
*/
package org.forgerock.opendj.rest2ldap.authz;
+import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*;
+import static org.forgerock.opendj.rest2ldap.authz.Utils.newAccessTokenException;
import static org.forgerock.util.Reject.checkNotNull;
import static org.forgerock.util.promise.Promises.newExceptionPromise;
import static org.forgerock.util.promise.Promises.newResultPromise;
@@ -48,7 +50,7 @@
try (final InputStream stream = new FileInputStream(new File(folderPath, token))) {
accessToken = new JsonValue(Json.readJsonLenient(stream));
} catch (final IOException e) {
- return newExceptionPromise(new AccessTokenException("Unable to find token file '" + token + "'", e));
+ return newExceptionPromise(newAccessTokenException(ERR_OAUTH2_FILE_NO_TOKEN.get(token) , e));
}
try {
@@ -58,7 +60,7 @@
return newResultPromise(result);
} catch (final JsonValueException e) {
return newExceptionPromise(
- new AccessTokenException("Malformed token file '" + token + "': '" + e.getMessage() + "'.", e));
+ newAccessTokenException(ERR_OAUTH2_FILE_INVALID_JSON_TOKEN.get(token, e.getMessage()), e));
}
}
}
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Rfc7662AccessTokenResolver.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Rfc7662AccessTokenResolver.java
index 4277291..9c22fb7 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Rfc7662AccessTokenResolver.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Rfc7662AccessTokenResolver.java
@@ -15,7 +15,9 @@
*/
package org.forgerock.opendj.rest2ldap.authz;
+import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.forgerock.opendj.rest2ldap.authz.Utils.newAccessTokenException;
import static org.forgerock.util.Reject.checkNotNull;
import java.io.IOException;
@@ -99,19 +101,18 @@
public AccessTokenInfo apply(final Response response) throws AccessTokenException {
final Status status = response.getStatus();
if (!Status.OK.equals(status)) {
- throw new AccessTokenException(
- "Authorization server returned an error: " + status, response.getCause());
+ throw newAccessTokenException(
+ ERR_OAUTH2_RFC7662_RETURNED_ERROR.get(status), response.getCause());
}
try (final Entity entity = response.getEntity()) {
final JsonValue jsonResponse = asJson(entity);
if (!jsonResponse.get(RFC_7662_RESPONSE_ACTIVE_FIELD).defaultTo(Boolean.FALSE).asBoolean()) {
- throw new AccessTokenException(
- "Access token returned by authorization server is not currently active");
+ throw newAccessTokenException(ERR_OAUTH2_RFC7662_TOKEN_NOT_ACTIVE.get());
}
return buildAccessTokenFromJson(jsonResponse, tokenSent);
} catch (final JsonValueException e) {
- throw new AccessTokenException("Invalid or malformed access token: " + e.getMessage(), e);
+ throw newAccessTokenException(ERR_OAUTH2_RFC7662_INVALID_JSON_TOKEN.get(e.getMessage()), e);
}
}
};
@@ -129,7 +130,7 @@
return new JsonValue(entity.getJson());
} catch (final IOException e) {
// Do not use Entity.toString(), we probably don't want to fully output the content here
- throw new AccessTokenException("Cannot read response content as JSON", e);
+ throw newAccessTokenException(ERR_OAUTH2_RFC7662_CANNOT_READ_RESPONSE.get(), e);
}
}
}
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Utils.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Utils.java
index a5cf1a8..65d1ca6 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Utils.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/authz/Utils.java
@@ -21,8 +21,10 @@
import java.io.Closeable;
import java.util.concurrent.atomic.AtomicReference;
+import org.forgerock.authz.modules.oauth2.AccessTokenException;
import org.forgerock.http.protocol.Response;
import org.forgerock.http.protocol.Status;
+import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.json.resource.ResourceException;
import org.forgerock.util.promise.NeverThrowsException;
import org.forgerock.util.promise.Promise;
@@ -32,6 +34,18 @@
private Utils() { }
+ static IllegalArgumentException newIllegalArgumentException(final LocalizableMessage message) {
+ return new IllegalArgumentException(message.toString());
+ }
+
+ static AccessTokenException newAccessTokenException(final LocalizableMessage message) {
+ return newAccessTokenException(message, null);
+ }
+
+ static AccessTokenException newAccessTokenException(final LocalizableMessage message, final Exception cause) {
+ return new AccessTokenException(message.toString(), cause);
+ }
+
static Runnable close(final AtomicReference<? extends Closeable> holder) {
return new Runnable() {
@Override
diff --git a/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap.properties b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap.properties
new file mode 100644
index 0000000..d1ea5cd
--- /dev/null
+++ b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap.properties
@@ -0,0 +1,110 @@
+#
+# The contents of this file are subject to the terms of the Common Development and
+# Distribution License (the License). You may not use this file except in compliance with the
+# License.
+#
+# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+# specific language governing permission and limitations under the License.
+#
+# When distributing Covered Software, include this CDDL Header Notice in each file and include
+# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+# Header, with the fields enclosed by brackets [] replaced by your own identifying
+# information: "Portions Copyright [year] [name of copyright owner]".
+#
+# Copyright 2016 ForgeRock AS.
+#
+
+# Configuration errors
+ERR_FAIL_PARSE_CONFIGURATION_1=Unable to start Rest2Ldap Http Application due to the configuration error: '%s'
+ERR_CONFIG_OAUTH2_UNSUPPORTED_ACCESS_TOKEN_RESOLVER_2= '%s'is not a supported access token resolver. Must be one of '%s'
+ERR_CONIFG_OAUTH2_INVALID_INTROSPECT_URL_3=The token introspection endpoint '%s' is not a valid URL: '%s'
+ERR_CONIFG_OAUTH2_CACHE_ZERO_DURATION_4=The cache expiration duration cannot be zero
+ERR_CONIFG_OAUTH2_CACHE_UNLIMITED_DURATION_5=The cache expiration duration cannot be unlimited
+ERR_CONFIG_OAUTH2_CACHE_INVALID_DURATION_6=Malformed duration value '%s' for cache expiration. \
+ The duration syntax supports all human readable notations from day ('days'', 'day'', 'd'') to nanosecond \
+ ('nanoseconds', 'nanosecond', 'nanosec', 'nanos', 'nano', 'ns')
+ERR_CONFIG_UNSUPPORTED_BIND_STRATEGY_7=Unsupported bind strategy '%s'. Must be one of '%s'
+ERR_CONFIG_INVALID_AUTHZID_TEMPLATE_8=Invalid authorization ID template: '%s'.\
+ Templates must start with one of the following elements: '%s'
+ERR_CONFIG_INVALID_AUTHENTICATION_9=Only simple authentication is supported
+ERR_CONFIG_INVALID_SECONDARY_LDAP_SERVER_10=secondaryLDAPServers configuration must contain a json array
+ERR_CONFIG_SERVER_CIRCULAR_DEPENDENCIES_11=The LDAP server configuration '%s' could not be parsed because of \
+ potential circular inheritance dependencies
+ERR_CONFIG_NAMING_STRATEGY_DN_AND_ID_NOT_DIFFERENT_12=Naming strategy DN and ID must be different
+ERR_CONFIG_NO_MAPPINGS_PROVIDED_13=No mappings provided in configuration
+ERR_CONFIG_NO_MAPPING_IN_CONFIGURATION_14=Unknown mapping. The configuration mapping must be one of '%s'
+ERR_CONFIG_UNKNOWN_WRITABILITY_15=Unknown writability '%s'. Must be one of %s
+ERR_CONFIG_UNKNOWN_NAMING_CONFIGURATION_16=Unknown naming strategy '%s'. Must be one of %s
+
+# Runtime errors
+ERR_AUTHZID_DECODER_PRINCIPAL_CANNOT_BE_DETERMINED_17=The request could not be authorized because the required \
+ security principal '%s' could not be determined
+ERR_AUTHZID_DECODER_PRINCIPAL_INVALID_DATA_TYPE_18=The request could not be authorized because the required \
+ security principal '%s' had an invalid data type
+ERR_AUTHZID_DECODER_RESPONSE_19=Invalid configuration
+ERR_RESOLVING_AUTHZID_TEMPLATE_20=Unable to resolve oauthzid template placeholders for access token '%s': '%s'
+# Runtime errors > OAuth2 > CTS Resolver
+ERR_OAUTH2_CTS_INVALID_TOKEN_TYPE_21=The token '%s' must be an access token, but it is a '%s'
+ERR_OAUTH2_CTS_TOKEN_NOT_FOUND_22=Unable to find the token '%s' in the CTS because: '%s'
+ERR_OAUTH2_CTS_TOKEN_RESOLUTION_23=Unable to resolve access token '%s' due to the following reason: '%s'
+ERR_OAUTH2_CTS_INVALID_JSON_TOKEN_24=Json of token '%s' is malformed
+# Runtime errors > OAuth2 > File Resolver
+ERR_OAUTH2_FILE_NO_TOKEN_25=Unable to find token file '%s'
+ERR_OAUTH2_FILE_INVALID_JSON_TOKEN_26=Malformed token file '%s'. Details: '%s'
+# Runtime errors > OAuth2 > RFC-7662 Resolver
+ERR_OAUTH2_RFC7662_RETURNED_ERROR_27=Authorization server returned an error: '%s'
+ERR_OAUTH2_RFC7662_TOKEN_NOT_ACTIVE_28=Access token returned by authorization server is not currently active
+ERR_OAUTH2_RFC7662_INVALID_JSON_TOKEN_29=Invalid or malformed access token: '%s'
+ERR_OAUTH2_RFC7662_CANNOT_READ_RESPONSE_30=Cannot read response content as JSON
+
+# Runtime rest to ldap processing
+ERR_CREATION_READ_ONLY_FIELD_31=The create request cannot be processed because it attempts to create the \
+ read-only field '%s'
+ERR_REMOVE_REQUIRED_FIELD_32=The %s request cannot be processed because it attempts to remove the required field '%s'
+ERR_MODIFY_READ_ONLY_FIELD_33=The %s request cannot be processed because it attempts to modify the read-only field '%s'
+ERR_PATCH_READ_ONLY_FIELD_34=The patch request cannot be processed because it attempts to patch the read-only field '%s'
+ERR_ARRAY_FOR_SINGLE_VALUED_FIELD_35=The request cannot be processed because an array of values was \
+ provided for the single valued field '%s'
+ERR_NO_ARRAY_FOR_MULTI_VALUED_FIELD_36=The request cannot be processed because an array of values was \
+ not provided for the multi-valued field '%s'
+ERR_PATCH_APPEND_IN_SINGLE_VALUED_FIELD_37=The patch request cannot be processed because it attempts to append a \
+ value to the single valued field '%s'
+ERR_PATCH_INDEXED_APPEND_TO_MULTI_VALUED_FIELD_38=The patch request cannot be processed because it attempts to perform \
+ an indexed append of an array of values to the multi-valued field '%s'
+ERR_PATCH_INDEXED_OPERATION_39=The patch request cannot be processed because it included an indexed patch \
+ operation '%s' which is not supported by this resource provider
+ERR_UNRECOGNIZED_FIELD_40=The request cannot be processed because it included an unrecognized field '%s'
+ERR_FIELD_WRONG_TYPE_41=The request cannot be processed because it included the field '%s' whose value \
+ is the wrong type: an object is expected
+ERR_PATCH_ADD_NO_VALUE_FOR_FIELD_42=The patch request cannot be processed because it included an add patch operation \
+ but no value(s) for field '%s'
+ERR_PATCH_UNSUPPORTED_OPERATION_43=The patch request cannot be processed because it included an unsupported \
+ type of patch operation '%s'
+ERR_MVCC_NOT_SUPPORTED_44=Multi-version concurrency control is not supported by this resource
+ERR_MVCC_NO_VERSION_INFORMATION_45=The resource could not be accessed because it did not contain any version \
+ information, when the version '%s' was expected
+ERR_MVCC_VERSIONS_MISMATCH_46=The resource could not be accessed because the expected version '%s' does \
+ not match the current version '%s'
+ERR_REFERENCE_FIELD_NO_PRIMARY_KEY_47=The request cannot be processed because the reference field '%s' \
+ contains a value which does not contain a primary key
+ERR_REFERENCE_FIELD_MULTIPLE_PRIMARY_KEYS_48=The request cannot be processed because the reference field \
+ '%s' contains a value which contains multiple primary keys
+ERR_REFERENCE_FIELD_DOES_NOT_EXIST_49=The request cannot be processed because the resource '%s' referenced \
+ in field '%s' does not exist
+ERR_REFERENCE_FIELD_AMBIGUOUS_50=The request cannot be processed because the resource '%s' referenced in \
+ field '%s' is ambiguous
+ERR_ILLEGAL_FILTER_ASSERTION_VALUE_51=The request cannot be processed because it contained an illegal \
+ filter assertion value '%s' for field '%s'
+ERR_ENCODING_VALUES_FOR_FIELD_52=The request cannot be processed because an error occurred while encoding \
+ the values for the field '%s': '%s'
+ERR_UNRECOGNIZED_JSON_VALUE_53=Unrecognized type of JSON value: '%s'
+ERR_CLIENT_PROVIDER_RESOURCE_ID_MISSING_54=Resources cannot be created without a client provided resource ID
+ERR_NOT_YET_IMPLEMENTED_55=Not yet implemented
+ERR_ACTION_NOT_SUPPORTED_56=The action '%s' is not supported
+ERR_PASSWORD_MODIFY_SECURE_CONNECTION_57=Password modify requires a secure connection
+ERR_PASSWORD_MODIFY_USER_AUTHENTICATED_58=Password modify requires user to be authenticated
+ERR_DECODING_CONTROL_59=Unable to decode ldap control: '%s'
+ERR_ERROR_RESPONSE_60=An error occurred while processing the request '%s': '%s' (details: '%s')
+ERR_RUNTIME_EXCEPTION_61=A runtime exception occurred wile processing the request '%s': '%s'
+ERR_PASSWORD_MODIFY_REQUEST_IS_INVALID_62=The password modify request has been rejected because it is invalid. \
+ A password modify request may contain two string valued fields 'oldPassword' and 'newPassword'
diff --git a/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_ca_ES.properties b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_ca_ES.properties
new file mode 100644
index 0000000..99be5ab
--- /dev/null
+++ b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_ca_ES.properties
@@ -0,0 +1,15 @@
+#
+# The contents of this file are subject to the terms of the Common Development and
+# Distribution License (the License). You may not use this file except in compliance with the
+# License.
+#
+# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+# specific language governing permission and limitations under the License.
+#
+# When distributing Covered Software, include this CDDL Header Notice in each file and include
+# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+# Header, with the fields enclosed by brackets [] replaced by your own identifying
+# information: "Portions Copyright [year] [name of copyright owner]".
+#
+# Copyright 2016 ForgeRock AS.
+#
diff --git a/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_de.properties b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_de.properties
new file mode 100644
index 0000000..99be5ab
--- /dev/null
+++ b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_de.properties
@@ -0,0 +1,15 @@
+#
+# The contents of this file are subject to the terms of the Common Development and
+# Distribution License (the License). You may not use this file except in compliance with the
+# License.
+#
+# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+# specific language governing permission and limitations under the License.
+#
+# When distributing Covered Software, include this CDDL Header Notice in each file and include
+# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+# Header, with the fields enclosed by brackets [] replaced by your own identifying
+# information: "Portions Copyright [year] [name of copyright owner]".
+#
+# Copyright 2016 ForgeRock AS.
+#
diff --git a/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_es.properties b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_es.properties
new file mode 100644
index 0000000..99be5ab
--- /dev/null
+++ b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_es.properties
@@ -0,0 +1,15 @@
+#
+# The contents of this file are subject to the terms of the Common Development and
+# Distribution License (the License). You may not use this file except in compliance with the
+# License.
+#
+# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+# specific language governing permission and limitations under the License.
+#
+# When distributing Covered Software, include this CDDL Header Notice in each file and include
+# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+# Header, with the fields enclosed by brackets [] replaced by your own identifying
+# information: "Portions Copyright [year] [name of copyright owner]".
+#
+# Copyright 2016 ForgeRock AS.
+#
diff --git a/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_fr.properties b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_fr.properties
new file mode 100644
index 0000000..99be5ab
--- /dev/null
+++ b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_fr.properties
@@ -0,0 +1,15 @@
+#
+# The contents of this file are subject to the terms of the Common Development and
+# Distribution License (the License). You may not use this file except in compliance with the
+# License.
+#
+# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+# specific language governing permission and limitations under the License.
+#
+# When distributing Covered Software, include this CDDL Header Notice in each file and include
+# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+# Header, with the fields enclosed by brackets [] replaced by your own identifying
+# information: "Portions Copyright [year] [name of copyright owner]".
+#
+# Copyright 2016 ForgeRock AS.
+#
diff --git a/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_ja.properties b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_ja.properties
new file mode 100644
index 0000000..99be5ab
--- /dev/null
+++ b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_ja.properties
@@ -0,0 +1,15 @@
+#
+# The contents of this file are subject to the terms of the Common Development and
+# Distribution License (the License). You may not use this file except in compliance with the
+# License.
+#
+# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+# specific language governing permission and limitations under the License.
+#
+# When distributing Covered Software, include this CDDL Header Notice in each file and include
+# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+# Header, with the fields enclosed by brackets [] replaced by your own identifying
+# information: "Portions Copyright [year] [name of copyright owner]".
+#
+# Copyright 2016 ForgeRock AS.
+#
diff --git a/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_ko.properties b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_ko.properties
new file mode 100644
index 0000000..99be5ab
--- /dev/null
+++ b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_ko.properties
@@ -0,0 +1,15 @@
+#
+# The contents of this file are subject to the terms of the Common Development and
+# Distribution License (the License). You may not use this file except in compliance with the
+# License.
+#
+# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+# specific language governing permission and limitations under the License.
+#
+# When distributing Covered Software, include this CDDL Header Notice in each file and include
+# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+# Header, with the fields enclosed by brackets [] replaced by your own identifying
+# information: "Portions Copyright [year] [name of copyright owner]".
+#
+# Copyright 2016 ForgeRock AS.
+#
diff --git a/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_pl.properties b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_pl.properties
new file mode 100644
index 0000000..99be5ab
--- /dev/null
+++ b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_pl.properties
@@ -0,0 +1,15 @@
+#
+# The contents of this file are subject to the terms of the Common Development and
+# Distribution License (the License). You may not use this file except in compliance with the
+# License.
+#
+# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+# specific language governing permission and limitations under the License.
+#
+# When distributing Covered Software, include this CDDL Header Notice in each file and include
+# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+# Header, with the fields enclosed by brackets [] replaced by your own identifying
+# information: "Portions Copyright [year] [name of copyright owner]".
+#
+# Copyright 2016 ForgeRock AS.
+#
diff --git a/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_zh_CN.properties b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_zh_CN.properties
new file mode 100644
index 0000000..99be5ab
--- /dev/null
+++ b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_zh_CN.properties
@@ -0,0 +1,15 @@
+#
+# The contents of this file are subject to the terms of the Common Development and
+# Distribution License (the License). You may not use this file except in compliance with the
+# License.
+#
+# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+# specific language governing permission and limitations under the License.
+#
+# When distributing Covered Software, include this CDDL Header Notice in each file and include
+# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+# Header, with the fields enclosed by brackets [] replaced by your own identifying
+# information: "Portions Copyright [year] [name of copyright owner]".
+#
+# Copyright 2016 ForgeRock AS.
+#
diff --git a/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_zh_TW.properties b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_zh_TW.properties
new file mode 100644
index 0000000..99be5ab
--- /dev/null
+++ b/opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap_zh_TW.properties
@@ -0,0 +1,15 @@
+#
+# The contents of this file are subject to the terms of the Common Development and
+# Distribution License (the License). You may not use this file except in compliance with the
+# License.
+#
+# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+# specific language governing permission and limitations under the License.
+#
+# When distributing Covered Software, include this CDDL Header Notice in each file and include
+# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+# Header, with the fields enclosed by brackets [] replaced by your own identifying
+# information: "Portions Copyright [year] [name of copyright owner]".
+#
+# Copyright 2016 ForgeRock AS.
+#
diff --git a/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/authz/CtsAccessTokenResolverTestCase.java b/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/authz/CtsAccessTokenResolverTestCase.java
index ee9959f..b455206 100644
--- a/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/authz/CtsAccessTokenResolverTestCase.java
+++ b/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/authz/CtsAccessTokenResolverTestCase.java
@@ -122,7 +122,7 @@
}
@Test(expectedExceptions = ExecutionException.class, expectedExceptionsMessageRegExp =
- ".*The token 'test-token' must be an access token, but it is a \"refresh_token\"")
+ ".*The token 'test-token' must be an access token, but it is a 'refresh_token'")
public void testInvalidTokenType() throws Exception {
final SearchResultEntry entry = mock(SearchResultEntry.class);
final Attribute attribute = mock(Attribute.class);
--
Gitblit v1.10.0