protected ResourceException convertScriptException(final ScriptException scriptException) {

    ResourceException convertedError;
    try {
      throw scriptException;
    } catch (ScriptThrownException e) {
      convertedError =
          e.toResourceException(ResourceException.INTERNAL_ERROR, scriptException.getMessage());
    } catch (ScriptException e) {
      convertedError =
          new InternalServerErrorException(scriptException.getMessage(), scriptException);
    }
    if (convertedError.getDetail().isNull()) {
      convertedError.setDetail(new JsonValue(new HashMap<String, Object>()));
    }
    final JsonValue detail = convertedError.getDetail();
    if (detail.get("fileName").isNull()
        && detail.get("lineNumber").isNull()
        && detail.get("columnNumber").isNull()) {
      detail.put("fileName", scriptException.getFileName());
      detail.put("lineNumber", scriptException.getLineNumber());
      detail.put("columnNumber", scriptException.getColumnNumber());
    }

    return convertedError;
  }
 private JsonValue createClientRegistrationDeclaration(
     final JsonValue configuration, final String issuerName) {
   configuration.put("issuer", issuerName);
   return json(
       object(
           field("name", issuerName + suffix),
           field("type", "ClientRegistration"),
           field("config", configuration)));
 }
 @Override
 public Promise<ActionResponse, ResourceException> handleAction(
     final Context context, final ActionRequest request) {
   try {
     Map<String, String> params = request.getAdditionalParameters();
     switch (request.getActionAsEnum(Action.class)) {
       case updateDbCredentials:
         String newUser = params.get("user");
         String newPassword = params.get("password");
         if (newUser == null || newPassword == null) {
           return adapt(new BadRequestException("Expecting 'user' and 'password' parameters"))
               .asPromise();
         }
         synchronized (dbLock) {
           DBHelper.updateDbCredentials(dbURL, user, password, newUser, newPassword);
           JsonValue config =
               connectionFactory
                   .getConnection()
                   .read(context, Requests.newReadRequest("config", PID))
                   .getContent();
           config.put("user", newUser);
           config.put("password", newPassword);
           UpdateRequest updateRequest = Requests.newUpdateRequest("config/" + PID, config);
           connectionFactory.getConnection().update(context, updateRequest);
           return newActionResponse(new JsonValue(params)).asPromise();
         }
       case command:
         return newActionResponse(new JsonValue(command(request))).asPromise();
       default:
         return adapt(new BadRequestException("Unknown action: " + request.getAction()))
             .asPromise();
     }
   } catch (IllegalArgumentException e) {
     return adapt(new BadRequestException("Unknown action: " + request.getAction())).asPromise();
   } catch (ResourceException e) {
     return e.asPromise();
   }
 }
Example #4
0
 /** Retrieves the cookie domains set on the server. */
 private Promise<ResourceResponse, ResourceException> getCookieDomains() {
   JsonValue result = new JsonValue(new LinkedHashMap<String, Object>(1));
   Set<String> cookieDomains;
   ResourceResponse resource;
   int rev;
   try {
     cookieDomains = AuthClientUtils.getCookieDomains();
     rev = cookieDomains.hashCode();
     result.put("domains", cookieDomains);
     resource = newResourceResponse(COOKIE_DOMAINS, Integer.toString(rev), result);
     if (debug.messageEnabled()) {
       debug.message(
           "ServerInfoResource.getCookieDomains ::"
               + " Added resource to response: "
               + COOKIE_DOMAINS);
     }
     return newResultPromise(resource);
   } catch (Exception e) {
     debug.error("ServerInfoResource.getCookieDomains : Cannot retrieve cookie domains.", e);
     return new NotFoundException(e.getMessage()).asPromise();
   }
 }
 public Promise<ActionResponse, ResourceException> handleAction(
     final Context context, final ActionRequest request) {
   EventEntry measure =
       Publisher.start(
           Name.get(
               "openidm/internal/script/" + this.getScriptEntry().getName().getName() + "/action"),
           null,
           null);
   try {
     final ScriptEntry _scriptEntry = getScriptEntry();
     if (!_scriptEntry.isActive()) {
       throw new ServiceUnavailableException("Inactive script: " + _scriptEntry.getName());
     }
     final Script script = _scriptEntry.getScript(context);
     script.setBindings(script.createBindings());
     customizer.handleAction(context, request, script.getBindings());
     Object result = script.eval();
     if (null == result) {
       return newActionResponse(new JsonValue(null)).asPromise();
     } else if (result instanceof JsonValue) {
       return newActionResponse((JsonValue) result).asPromise();
     } else if (result instanceof Map) {
       return newActionResponse(new JsonValue(result)).asPromise();
     } else {
       JsonValue resource = new JsonValue(new HashMap<String, Object>(1));
       resource.put("result", result);
       return newActionResponse(new JsonValue(result)).asPromise();
     }
   } catch (ScriptException e) {
     return convertScriptException(e).asPromise();
   } catch (ResourceException e) {
     return e.asPromise();
   } catch (Exception e) {
     return new InternalServerErrorException(e.getMessage(), e).asPromise();
   } finally {
     measure.end();
   }
 }
 /**
  * Set "extraInfo" audit log field.
  *
  * @param values String sequence of values that should be stored in the 'extraInfo' audit log
  *     field.
  */
 static void putExtraInfo(JsonValue jsonValue, String... values) {
   jsonValue.put(EXTRA_INFO, json(array(values)));
 }
 /**
  * Set "contexts" audit log field.
  *
  * @param value Map "contexts" value.
  */
 static void putContexts(JsonValue jsonValue, Map<String, String> value) {
   jsonValue.put(CONTEXTS, value == null ? new HashMap<String, String>() : value);
 }
 /**
  * Set "component" audit log field.
  *
  * @param value String "component" value.
  */
 static void putComponent(JsonValue jsonValue, String value) {
   jsonValue.put(COMPONENT, value == null ? "" : value);
 }
  /**
   * Updates the specified object in the object set.
   *
   * <p>This implementation does not require MVCC and uses the current revision if no revision is
   * specified in the request.
   *
   * <p>If successful, this method updates metadata properties within the passed object, including:
   * a new {@code _rev} value for the revised object's version
   *
   * @param request the contents of the object to update
   * @throws ConflictException if version is required but is {@code null}.
   * @throws ForbiddenException if access to the object is forbidden.
   * @throws NotFoundException if the specified object could not be found.
   * @throws PreconditionFailedException if version did not match the existing object in the set.
   * @throws BadRequestException if the passed identifier is invalid
   */
  @Override
  public ResourceResponse update(UpdateRequest request) throws ResourceException {
    if (request.getResourcePathObject().size() < 2) {
      throw new NotFoundException(
          "The object identifier did not include sufficient information to determine the object type and identifier of the object to update: "
              + request.getResourcePath());
    }

    final String type = request.getResourcePathObject().parent().toString();
    final String localId = request.getResourcePathObject().leaf();

    String orientClassName = typeToOrientClassName(type);
    JsonValue obj = request.getContent();

    if (request.getRevision() != null && !"".equals(request.getRevision())) {
      obj.put(DocumentUtil.TAG_REV, request.getRevision());
    }

    ODatabaseDocumentTx db = getConnection();
    try {
      ODocument existingDoc = predefinedQueries.getByID(localId, type, db);
      if (existingDoc == null) {
        throw new NotFoundException(
            "Update on object " + request.getResourcePath() + " could not find existing object.");
      }
      ODocument updatedDoc = DocumentUtil.toDocument(obj, existingDoc, db, orientClassName);
      logger.trace("Updated doc for id {} to save {}", request.getResourcePath(), updatedDoc);

      updatedDoc.save();

      obj.put(DocumentUtil.TAG_REV, Integer.toString(updatedDoc.getVersion()));
      // Set ID to return to caller
      obj.put(DocumentUtil.TAG_ID, updatedDoc.field(DocumentUtil.ORIENTDB_PRIMARY_KEY));
      logger.debug(
          "Committed update for id: {} revision: {}",
          request.getResourcePath(),
          updatedDoc.getVersion());
      logger.trace("Update payload for id: {} doc: {}", request.getResourcePath(), updatedDoc);
      return newResourceResponse(
          obj.get(DocumentUtil.TAG_ID).asString(), obj.get(DocumentUtil.TAG_REV).asString(), obj);
    } catch (ODatabaseException ex) {
      // Without transaction the concurrent modification exception gets nested instead
      if (isCauseConcurrentModificationException(ex, 10)) {
        throw new PreconditionFailedException(
            "Update rejected as current Object revision is different than expected by caller, the object has changed since retrieval: "
                + ex.getMessage(),
            ex);
      } else {
        throw ex;
      }
    } catch (OConcurrentModificationException ex) {
      throw new PreconditionFailedException(
          "Update rejected as current Object revision is different than expected by caller, the object has changed since retrieval: "
              + ex.getMessage(),
          ex);
    } catch (RuntimeException e) {
      throw e;
    } finally {
      if (db != null) {
        db.close();
      }
    }
  }
  /**
   * Creates a new object in the object set.
   *
   * <p>This method sets the {@code _id} property to the assigned identifier for the object, and the
   * {@code _rev} property to the revised object version (For optimistic concurrency)
   *
   * @param request the contents of the object to create in the object set.
   * @throws NotFoundException if the specified id could not be resolved.
   * @throws ForbiddenException if access to the object or object set is forbidden.
   * @throws ConflictException if an object with the same ID already exists.
   */
  @Override
  public ResourceResponse create(CreateRequest request) throws ResourceException {
    if (request.getResourcePathObject().isEmpty()) {
      throw new NotFoundException(
          "The object identifier did not include sufficient information to determine the object type: "
              + request.getResourcePath());
    }

    final String type = request.getResourcePath();
    // TODO: should CREST support server side generation of ID itself?
    final String localId =
        (request.getNewResourceId() == null || "".equals(request.getNewResourceId()))
            ? UUID.randomUUID().toString() // Generate ID server side.
            : request.getNewResourceId();

    // Used currently for logging
    String fullId = request.getResourcePathObject().child(localId).toString();

    String orientClassName = typeToOrientClassName(type);
    JsonValue obj = request.getContent();

    obj.put(DocumentUtil.TAG_ID, localId);

    ODatabaseDocumentTx db = getConnection();
    try {
      // Rather than using MVCC for insert, rely on primary key uniqueness constraints to detect
      // duplicate create
      ODocument newDoc = DocumentUtil.toDocument(obj, null, db, orientClassName);
      logger.trace("Created doc for id: {} to save {}", fullId, newDoc);
      newDoc.save();

      obj.put(DocumentUtil.TAG_REV, Integer.toString(newDoc.getVersion()));
      logger.debug("Completed create for id: {} revision: {}", fullId, newDoc.getVersion());
      logger.trace("Create payload for id: {} doc: {}", fullId, newDoc);
      return newResourceResponse(
          obj.get(DocumentUtil.TAG_ID).asString(), obj.get(DocumentUtil.TAG_REV).asString(), obj);
    } catch (ORecordDuplicatedException ex) {
      // Because the OpenIDM ID is defined as unique, duplicate inserts must fail
      throw new PreconditionFailedException(
          "Create rejected as Object with same ID already exists. " + ex.getMessage(), ex);
    } catch (OIndexException ex) {
      // Because the OpenIDM ID is defined as unique, duplicate inserts must fail
      throw new PreconditionFailedException(
          "Create rejected as Object with same ID already exists. " + ex.getMessage(), ex);
    } catch (ODatabaseException ex) {
      // Because the OpenIDM ID is defined as unique, duplicate inserts must fail.
      // OrientDB may wrap the IndexException root cause.
      if (isCauseIndexException(ex, 10) || isCauseRecordDuplicatedException(ex, 10)) {
        throw new PreconditionFailedException(
            "Create rejected as Object with same ID already exists and was detected. "
                + ex.getMessage(),
            ex);
      } else {
        throw ex;
      }
    } catch (RuntimeException e) {
      throw e;
    } finally {
      if (db != null) {
        db.close();
      }
    }
  }
Example #11
0
  /**
   * Retrieves all server info set on the server.
   *
   * @param context Current Server Context.
   * @param realm realm in whose security context we use.
   */
  private Promise<ResourceResponse, ResourceException> getAllServerInfo(
      Context context, String realm) {
    JsonValue result = new JsonValue(new LinkedHashMap<String, Object>(1));
    Set<String> cookieDomains;
    ResourceResponse resource;

    // added for the XUI to be able to understand its locale to request the appropriate translations
    // to cache
    ISLocaleContext localeContext = new ISLocaleContext();
    HttpContext httpContext = context.asContext(HttpContext.class);
    localeContext.setLocale(
        httpContext); // we have nothing else to go on at this point other than their request

    SelfServiceInfo selfServiceInfo = configHandler.getConfig(realm, SelfServiceInfoBuilder.class);
    RestSecurity restSecurity = restSecurityProvider.get(realm);
    Set<String> protectedUserAttributes = new HashSet<>();
    protectedUserAttributes.addAll(selfServiceInfo.getProtectedUserAttributes());
    protectedUserAttributes.addAll(restSecurity.getProtectedUserAttributes());

    try {
      cookieDomains = AuthClientUtils.getCookieDomains();
      result.put("domains", cookieDomains);
      result.put("protectedUserAttributes", protectedUserAttributes);
      result.put(
          "cookieName", SystemProperties.get(Constants.AM_COOKIE_NAME, "iPlanetDirectoryPro"));
      result.put("secureCookie", CookieUtils.isCookieSecure());
      result.put("forgotPassword", String.valueOf(selfServiceInfo.isForgottenPasswordEnabled()));
      result.put("forgotUsername", String.valueOf(selfServiceInfo.isForgottenUsernameEnabled()));
      result.put("kbaEnabled", String.valueOf(selfServiceInfo.isKbaEnabled()));
      result.put("selfRegistration", String.valueOf(selfServiceInfo.isUserRegistrationEnabled()));
      result.put("lang", getJsLocale(localeContext.getLocale()));
      result.put("successfulUserRegistrationDestination", "default");
      result.put("socialImplementations", getSocialAuthnImplementations(realm));
      result.put("referralsEnabled", Boolean.FALSE.toString());
      result.put("zeroPageLogin", AuthUtils.getZeroPageLoginConfig(realm));
      result.put("realm", realm);
      result.put(
          "xuiUserSessionValidationEnabled",
          SystemProperties.getAsBoolean(Constants.XUI_USER_SESSION_VALIDATION_ENABLED, true));

      if (debug.messageEnabled()) {
        debug.message(
            "ServerInfoResource.getAllServerInfo ::"
                + " Added resource to response: "
                + ALL_SERVER_INFO);
      }

      resource =
          newResourceResponse(ALL_SERVER_INFO, Integer.toString(result.asMap().hashCode()), result);

      return newResultPromise(resource);
    } catch (Exception e) {
      debug.error(
          "ServerInfoResource.getAllServerInfo : Cannot retrieve all server info domains.", e);
      return new NotFoundException(e.getMessage()).asPromise();
    }
  }
Example #12
0
  /**
   * Will validate the Map representation of the service configuration against the serviceSchema and
   * return a corresponding JSON representation
   *
   * @param attributeValuePairs The schema attribute values.
   * @param realm The realm, or null if global.
   * @return Json representation of attributeValuePairs
   */
  public JsonValue toJson(String realm, Map<String, Set<String>> attributeValuePairs) {
    if (!initialised) {
      init();
    }
    final boolean validAttributes;
    try {
      if (realm == null) {
        validAttributes = schema.validateAttributes(attributeValuePairs);
      } else {
        validAttributes = schema.validateAttributes(attributeValuePairs, realm);
      }
    } catch (SMSException e) {
      debug.error(
          "schema validation threw an exception while validating the attributes: realm="
              + realm
              + " attributes: "
              + attributeValuePairs,
          e);
      throw new JsonException("Unable to validate attributes", e);
    }

    JsonValue parentJson = json(new HashMap<String, Object>());

    if (validAttributes) {
      for (String attributeName : attributeValuePairs.keySet()) {
        String jsonResourceName = attributeNameToResourceName.get(attributeName);

        String name;
        if (jsonResourceName != null) {
          name = jsonResourceName;
        } else {
          name = attributeName;
        }

        AttributeSchema attributeSchema = schema.getAttributeSchema(attributeName);

        if (shouldBeIgnored(attributeName)) {
          continue;
        }

        AttributeSchema.Type type = attributeSchema.getType();
        final Set<String> object = attributeValuePairs.get(attributeName);

        Object jsonAttributeValue = null;

        if (type == null) {
          throw new JsonException("Type not defined.");
        }

        AttributeSchemaConverter attributeSchemaConverter = attributeSchemaConverters.get(name);

        if (isASingleValue(type)) {
          if (!object.isEmpty()) {
            jsonAttributeValue = attributeSchemaConverter.toJson(object.iterator().next());
          }
        } else if (containsMultipleValues(type)) {
          if (isAMap(attributeSchema.getUIType())) {
            Map<String, Object> map = new HashMap<String, Object>();

            Iterator<String> itr = object.iterator();
            while (itr.hasNext()) {
              Pair<String, String> entry = nameValueParser.parse(itr.next());
              map.put(entry.getFirst(), attributeSchemaConverter.toJson(entry.getSecond()));
            }
            jsonAttributeValue = map;
          } else {
            List<Object> list = new ArrayList<Object>();

            Iterator<String> itr = object.iterator();
            while (itr.hasNext()) {
              list.add(attributeSchemaConverter.toJson(itr.next()));
            }
            jsonAttributeValue = list;
          }
        }

        String sectionName = attributeNameToSection.get(attributeName);
        if (sectionName != null) {
          parentJson.putPermissive(
              new JsonPointer("/" + sectionName + "/" + name), jsonAttributeValue);
        } else {
          parentJson.put(name, jsonAttributeValue);
        }
      }
    } else {
      throw new JsonException("Invalid attributes");
    }
    return parentJson;
  }