/**
   * Validates the request by checking for the presence of a pre-configured attribute in the
   * ServletRequest.
   *
   * @param messageInfo {@inheritDoc}
   * @param clientSubject {@inheritDoc}
   * @param serviceSubject {@inheritDoc}
   * @return {@inheritDoc}
   */
  @Override
  public Promise<AuthStatus, AuthenticationException> validateRequest(
      MessageInfoContext messageInfo, Subject clientSubject, Subject serviceSubject) {

    SecurityContextMapper securityContextMapper =
        SecurityContextMapper.fromMessageInfo(messageInfo);
    final JsonValue attributes =
        json(messageInfo.asContext(AttributesContext.class).getAttributes());

    if (attributes.isDefined(authenticationIdAttribute)
        && attributes.get(authenticationIdAttribute).isString()) {
      final String authenticationId = attributes.get(authenticationIdAttribute).asString();
      securityContextMapper.setAuthenticationId(authenticationId);
      clientSubject
          .getPrincipals()
          .add(
              new Principal() {
                public String getName() {
                  return authenticationId;
                }
              });
      return newResultPromise(SUCCESS);
    } else {
      return newResultPromise(SEND_FAILURE);
    }
  }
  private ResourceResponse getResourceResponse(
      Context context, String clientId, Iterable<JsonValue> tokens)
      throws NotFoundException, InvalidClientException, ServerException,
          InternalServerErrorException {
    String realm = getAttributeValue(tokens.iterator().next(), REALM.getOAuthField());
    OAuth2ProviderSettings oAuth2ProviderSettings = oAuth2ProviderSettingsFactory.get(context);

    ClientRegistration clientRegistration = clientRegistrationStore.get(clientId, realm, context);
    Map<String, String> scopeDescriptions =
        clientRegistration.getScopeDescriptions(getLocale(context));
    Map<String, String> scopes = new HashMap<>();
    for (JsonValue token : tokens) {
      for (String scope : token.get(SCOPE.getOAuthField()).asSet(String.class)) {
        if (scopeDescriptions.containsKey(scope)) {
          scopes.put(scope, scopeDescriptions.get(scope));
        } else {
          scopes.put(scope, scope);
        }
      }
    }

    String displayName = clientRegistration.getDisplayName(getLocale(context));
    String expiryDateTime = calculateExpiryDateTime(tokens, oAuth2ProviderSettings);

    JsonValue content =
        json(
            object(
                field("_id", clientId),
                field("name", displayName),
                field("scopes", scopes),
                field("expiryDateTime", expiryDateTime)));

    return Responses.newResourceResponse(
        clientId, String.valueOf(content.getObject().hashCode()), content);
  }
  /**
   * Initialize the instance with the given configuration.
   *
   * <p>This can configure managed (DS/SCR) instances, as well as explicitly instantiated
   * (bootstrap) instances.
   *
   * @param config the configuration
   */
  void init(JsonValue config) {
    synchronized (dbLock) {
      try {
        dbURL = getDBUrl(config);
        logger.info("Use DB at dbURL: {}", dbURL);

        user = config.get(CONFIG_USER).defaultTo("admin").asString();
        password = config.get(CONFIG_PASSWORD).defaultTo("admin").asString();
        poolMinSize = config.get(CONFIG_POOL_MIN_SIZE).defaultTo(DEFAULT_POOL_MIN_SIZE).asInteger();
        poolMaxSize = config.get(CONFIG_POOL_MAX_SIZE).defaultTo(DEFAULT_POOL_MAX_SIZE).asInteger();

        Map<String, String> queryMap =
            config.get(CONFIG_QUERIES).defaultTo(new HashMap<String, String>()).asMap(String.class);
        queries.setConfiguredQueries(queryMap);
        Map<String, String> commandMap =
            config
                .get(CONFIG_COMMANDS)
                .defaultTo(new HashMap<String, String>())
                .asMap(String.class);
        commands.setConfiguredQueries(commandMap);
      } catch (RuntimeException ex) {
        logger.warn("Configuration invalid, can not start OrientDB repository", ex);
        throw ex;
      }

      try {
        pool = DBHelper.getPool(dbURL, user, password, poolMinSize, poolMaxSize, config, true);
        logger.debug("Obtained pool {}", pool);
      } catch (RuntimeException ex) {
        logger.warn("Initializing database pool failed", ex);
        throw ex;
      }
    }
  }
Exemple #4
0
 /**
  * Gets the specified parameter from the JsonValue.
  *
  * @param paramName The parameter name.
  * @return A {@code Set} of the parameter values.
  */
 private Set<String> getParameter(String paramName) {
   final JsonValue param = get(paramName);
   if (param != null) {
     return (Set<String>) param.getObject();
   }
   return null;
 }
 /**
  * Helper function to retrieve a field from the provided request's JSON POST data. This exists for
  * the new-style interfaces, and takes the parameter name as an argument also.
  *
  * @param input JsonValue containing the key "goto" and a paired URL.
  * @param paramName The key whose value to attempt to read.
  * @return The String representation fo the "goto" key's value, or null.
  */
 public String getValueFromJson(JsonValue input, String paramName) {
   if (input == null || !input.isDefined(paramName)) {
     return null;
   } else {
     return input.get(paramName).asString();
   }
 }
 /**
  * Takes a list of results (in json value wrapped form) and calls the handleResource for each on
  * the handler.
  *
  * @param resultList the list of results, possibly with id and rev entries
  * @param handler the handle to set the results on
  */
 private void handleQueryResultList(JsonValue resultList, QueryResourceHandler handler) {
   for (JsonValue entry : resultList) {
     // These can end up null
     String id = null;
     String rev = null;
     if (entry.isMap()) {
       id = entry.get(ResourceResponse.FIELD_ID).asString();
       rev = entry.get(ResourceResponse.FIELD_REVISION).asString();
     }
     handler.handleResource(newResourceResponse(id, rev, entry));
   }
 }
  /**
   * Initialises the TrustedServletFilterAuthModule.
   *
   * @param requestPolicy {@inheritDoc}
   * @param responsePolicy {@inheritDoc}
   * @param handler {@inheritDoc}
   * @param options {@inheritDoc}
   * @return {@inheritDoc}
   */
  @Override
  public Promise<Void, AuthenticationException> initialize(
      MessagePolicy requestPolicy,
      MessagePolicy responsePolicy,
      CallbackHandler handler,
      Map<String, Object> options) {

    JsonValue properties = json(options);
    authenticationIdAttribute = properties.get(AUTHENTICATION_ID).required().asString();

    return newResultPromise(null);
  }
  private String generateKid(JsonValue jwkSet, String algorithm) {

    final JwsAlgorithm jwsAlgorithm = JwsAlgorithm.valueOf(algorithm);
    if (JwsAlgorithmType.RSA.equals(jwsAlgorithm.getAlgorithmType())) {
      JsonValue jwks = jwkSet.get(OAuth2Constants.JWTTokenParams.KEYS);
      if (!jwks.isNull() && !jwks.asList().isEmpty()) {
        return jwks.get(0).get(OAuth2Constants.JWTTokenParams.KEY_ID).asString();
      }
    }

    return null;
  }
 private Promise<ResourceResponse, ResourceException> evaluate(
     final Request request, final Script script) throws ScriptException {
   Object result = script.eval();
   ResourcePath resourcePath = request.getResourcePathObject();
   if (null == result) {
     return new NotFoundException("script returned null").asPromise();
   }
   JsonValue resultJson =
       (result instanceof JsonValue) ? (JsonValue) result : new JsonValue(result);
   // If the resultJson isn't able to provide an ID, then we default to the resourcePath.
   String id = resultJson.get(ResourceResponse.FIELD_CONTENT_ID).defaultTo("").asString();
   if (id.isEmpty() && resourcePath.size() > 0) {
     id = resourcePath.leaf();
   }
   return newResourceResponse(id, null, resultJson).asPromise();
 }
 private String getAttributeValue(JsonValue token, String attributeName) {
   Set<String> value = token.get(attributeName).asSet(String.class);
   if (CollectionUtils.isNotEmpty(value)) {
     return value.iterator().next();
   }
   return null;
 }
  @Override
  protected Map<String, String> getContextsForAccessAttempt(Request request) {
    try {
      String jsonString = request.getEntity().getString();
      if (isNotEmpty(jsonString)) {
        JsonValue jsonValue = toJsonValue(jsonString);
        if (jsonValue.isDefined(AUTH_ID)) {
          populateContextFromAuthId(jsonValue.get(AUTH_ID).asString());
        }
      }
    } catch (IOException e) {
      // Do nothing
    }

    return super.getContextsForAccessAttempt(request);
  }
  @Test
  public void crestUpdateIsAllowed() throws SSOException, DelegationException {
    // Given...
    final Set<String> actions = new HashSet<>(Arrays.asList("MODIFY"));
    final DelegationPermission permission =
        new DelegationPermission(
            "/abc", "rest", "1.0", "policies", "modify", actions, EXTENSIONS, DUMB_FUNC);
    given(factory.newInstance("/abc", "rest", "1.0", "policies", "modify", actions, EXTENSIONS))
        .willReturn(permission);

    given(subjectContext.getCallerSSOToken()).willReturn(token);
    given(evaluator.isAllowed(eq(token), eq(permission), eq(ENVIRONMENT))).willReturn(true);

    JsonValue jsonValue = json(object(field("someKey", "someValue")));
    Promise<ResourceResponse, ResourceException> promise =
        Promises.newResultPromise(Responses.newResourceResponse("1", "1.0", jsonValue));
    given(provider.updateInstance(isA(Context.class), eq("123"), isA(UpdateRequest.class)))
        .willReturn(promise);

    // When...
    final FilterChain chain = AuthorizationFilters.createAuthorizationFilter(provider, module);
    final Router router = new Router();
    router.addRoute(RoutingMode.STARTS_WITH, Router.uriTemplate("/policies"), chain);

    final RealmContext context = new RealmContext(subjectContext);
    context.setSubRealm("abc", "abc");
    final UpdateRequest request =
        Requests.newUpdateRequest("/policies/123", JsonValue.json(new Object()));
    Promise<ResourceResponse, ResourceException> result = router.handleUpdate(context, request);

    // Then...
    assertThat(result).succeeded().withContent().stringAt("someKey").isEqualTo("someValue");
  }
  JsonValue performDynamicClientRegistration(
      final Context context,
      final JsonValue clientRegistrationConfiguration,
      final URI registrationEndpoint)
      throws RegistrationException {
    final Request request = new Request();
    request.setMethod("POST");
    request.setUri(registrationEndpoint);
    request.setEntity(clientRegistrationConfiguration.asMap());

    final Response response;
    try {
      response = blockingCall(registrationHandler, context, request);
    } catch (InterruptedException e) {
      throw new RegistrationException(
          format("Interrupted while waiting for '%s' response", request.getUri()), e);
    }
    if (!CREATED.equals(response.getStatus())) {
      throw new RegistrationException(
          "Cannot perform dynamic registration: this can be caused "
              + "by the distant server(busy, offline...) "
              + "or a malformed registration response.");
    }
    try {
      return getJsonContent(response);
    } catch (OAuth2ErrorException e) {
      throw new RegistrationException(
          "Cannot perform dynamic registration: invalid response JSON content.");
    }
  }
  @Test
  public void crestRequestNotAllowed() throws SSOException, DelegationException {
    // Given...
    final Set<String> actions = new HashSet<>(Arrays.asList("MODIFY"));
    final DelegationPermission permission =
        new DelegationPermission(
            "/abc", "rest", "1.0", "policies", "modify", actions, EXTENSIONS, DUMB_FUNC);
    given(factory.newInstance("/abc", "rest", "1.0", "policies", "modify", actions, EXTENSIONS))
        .willReturn(permission);

    given(subjectContext.getCallerSSOToken()).willReturn(token);
    given(evaluator.isAllowed(eq(token), eq(permission), eq(ENVIRONMENT))).willReturn(false);

    // When...
    final FilterChain chain = AuthorizationFilters.createAuthorizationFilter(provider, module);
    final Router router = new Router();
    router.addRoute(RoutingMode.STARTS_WITH, Router.uriTemplate("/policies"), chain);

    final RealmContext context = new RealmContext(subjectContext);
    context.setSubRealm("abc", "abc");
    final CreateRequest request =
        Requests.newCreateRequest("/policies", JsonValue.json(new Object()));
    Promise<ResourceResponse, ResourceException> promise = router.handleCreate(context, request);

    // Then...
    assertThat(promise).failedWithException().isInstanceOf(ForbiddenException.class);
  }
 @Override
 public byte[] convertFrom(JsonValue jsonValue) {
   try {
     return mapper.writeValueAsBytes(jsonValue.getObject());
   } catch (IOException e) {
     throw new IllegalArgumentException("Could not convert input to JSON", e);
   }
 }
  @Override
  public void handleRead(final Context context, final ReadRequest request, final Bindings handler)
      throws ResourceException {
    super.handleRead(context, request, handler);

    handler.put("request", request);
    handler.put("resources", configuration.get("resources").copy().getObject());
  }
  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)));
 }
 private String getDBUrl(JsonValue config) {
   File dbFolder = IdentityServer.getFileForWorkingPath("db/openidm");
   String orientDbFolder = dbFolder.getAbsolutePath();
   orientDbFolder = orientDbFolder.replace('\\', '/'); // OrientDB does not handle backslashes well
   return config
       .get(OrientDBRepoService.CONFIG_DB_URL)
       .defaultTo("local:" + orientDbFolder)
       .asString();
 }
  @Override
  public DeviceCode readDeviceCode(String userCode, OAuth2Request request)
      throws ServerException, NotFoundException, InvalidGrantException {
    try {
      JsonValue token = tokenStore.query(equalTo(CoreTokenField.STRING_FOURTEEN, userCode));

      if (token.size() != 1) {
        throw new InvalidGrantException();
      }

      DeviceCode deviceCode = new DeviceCode(json(token.asSet().iterator().next()));
      request.setToken(DeviceCode.class, deviceCode);
      return deviceCode;
    } catch (CoreTokenException e) {
      logger.error("Unable to read device code corresponding to id: " + userCode, e);
      throw new ServerException("Could not read token in CTS: " + e.getMessage());
    }
  }
  /**
   * Persist the supplied {@link JsonValue} {@code value} as the new state of this singleton
   * relationship on {@code resourceId}.
   *
   * <p><em>This is currently the only means of creating an instance of this singleton</em>
   *
   * @param context The context of this request
   * @param resourceId Id of the resource relation fields in value are to be memebers of
   * @param value A {@link JsonValue} map of relationship fields and their values
   * @return The persisted instance of {@code value}
   */
  @Override
  public Promise<JsonValue, ResourceException> setRelationshipValueForResource(
      Context context, String resourceId, JsonValue value) {
    if (value.isNotNull()) {
      try {
        final JsonValue id = value.get(FIELD_ID);

        // Update if we got an id, otherwise replace
        if (id != null && id.isNotNull()) {
          final UpdateRequest updateRequest = Requests.newUpdateRequest("", value);
          updateRequest.setAdditionalParameter(PARAM_FIRST_ID, resourceId);
          return updateInstance(context, value.get(FIELD_ID).asString(), updateRequest)
              .then(
                  new Function<ResourceResponse, JsonValue, ResourceException>() {
                    @Override
                    public JsonValue apply(ResourceResponse resourceResponse)
                        throws ResourceException {
                      return resourceResponse.getContent();
                    }
                  });
        } else { // no id, replace current instance
          clear(context, resourceId);

          final CreateRequest createRequest = Requests.newCreateRequest("", value);
          createRequest.setAdditionalParameter(PARAM_FIRST_ID, resourceId);
          return createInstance(context, createRequest)
              .then(
                  new Function<ResourceResponse, JsonValue, ResourceException>() {
                    @Override
                    public JsonValue apply(ResourceResponse resourceResponse)
                        throws ResourceException {
                      return resourceResponse.getContent();
                    }
                  });
        }
      } catch (ResourceException e) {
        return e.asPromise();
      }

    } else {
      clear(context, resourceId);
      return newResultPromise(json(null));
    }
  }
  /**
   * Performs the calculation of roles based on the userRoles property in the configuration and the
   * retrieved user object.
   *
   * @param principal The principal.
   * @param securityContextMapper The message info instance.
   * @param resource the retrieved resource for the principal.
   * @return A SecurityContextMapper instance containing the authentication context information.
   */
  public void calculateRoles(
      String principal, SecurityContextMapper securityContextMapper, ResourceResponse resource) {

    // Set roles from retrieved object:
    if (resource != null) {
      final JsonValue userDetail = resource.getContent();

      // support reading roles from property in object
      if (userRoles != null && !userDetail.get(userRoles).isNull()) {
        if (userDetail.get(userRoles).isString()) {
          for (String role : userDetail.get(userRoles).asString().split(",")) {
            securityContextMapper.addRole(role);
          }
        } else if (userDetail.get(userRoles).isList()) {
          for (JsonValue role : userDetail.get(userRoles)) {
            if (RelationshipUtil.isRelationship(role)) {
              // Role is specified as a relationship Object
              JsonPointer roleId =
                  new JsonPointer(role.get(RelationshipUtil.REFERENCE_ID).asString());
              securityContextMapper.addRole(roleId.leaf());
            } else {
              // Role is specified as a String
              securityContextMapper.addRole(role.asString());
            }
          }
        } else {
          logger.warn(
              "Unknown roles type retrieved from user query, expected collection: {} type: {}",
              userRoles,
              userDetail.get(userRoles).getObject().getClass());
        }
      }

      // Roles are now set.
      // Note: roles can be further augmented with a script if more complex behavior is desired

      logger.debug(
          "Used {}object property to update context for {} with userid : {}, roles : {}",
          userRoles != null ? (userRoles + " ") : "",
          securityContextMapper.getAuthenticationId(),
          securityContextMapper.getUserId(),
          securityContextMapper.getRoles());
    }
  }
  @SuppressWarnings("rawtypes")
  @Test(priority = 3)
  public void testCreateNew() throws Exception {
    config.put("property1", "value1");
    config.put("property2", "value2");

    configObjectService.create(rname, id, json(config), false).getOrThrow();

    ConfigObjectService.ParsedId parsedId = configObjectService.getParsedId(rname, id);
    Configuration config = configObjectService.findExistingConfiguration(parsedId);
    assertNotNull(config);
    assertNotNull(config.getProperties());

    Dictionary properties = config.getProperties();
    EnhancedConfig enhancedConfig = new JSONEnhancedConfig();
    JsonValue value = enhancedConfig.getConfiguration(properties, rname.toString(), false);
    assertTrue(value.keys().contains("property1"));
    Assert.assertEquals(value.get("property1").asString(), "value1");
  }
  /**
   * Calls buildAuditEvent() and invokes the request to the audit path.
   *
   * @param connectionFactory factory used to make crest call to audit service.
   */
  public final Promise<ResourceResponse, ResourceException> log(
      ConfigAuditState configAuditState,
      Request request,
      Context context,
      ConnectionFactory connectionFactory) {
    try {

      JsonValue before = configAuditState.getBefore();
      JsonValue after = configAuditState.getAfter();

      // Get authenticationId from security context, if it exists.
      String authenticationId =
          (context.containsContext(SecurityContext.class))
              ? context.asContext(SecurityContext.class).getAuthenticationId()
              : null;

      // Build the event utilizing the config builder.
      AuditEvent auditEvent =
          ConfigAuditEventBuilder.configEvent()
              .resourceOperationFromRequest(request)
              .authenticationFromSecurityContext(context)
              .runAs(authenticationId)
              .transactionIdFromRootContext(context)
              .revision(configAuditState.getRevision())
              .timestamp(System.currentTimeMillis())
              .eventName(CONFIG_AUDIT_EVENT_NAME)
              .before(null != before ? before.toString() : "")
              .after(null != after ? after.toString() : "")
              .changedFields(getChangedFields(before, after))
              .toEvent();

      return connectionFactory
          .getConnection()
          .create(context, Requests.newCreateRequest(AUDIT_CONFIG_REST_PATH, auditEvent.getValue()))
          .asPromise();
    } catch (ResourceException e) {
      LOGGER.error("had trouble logging audit event for config changes.", e);
      return e.asPromise();
    } catch (Exception e) {
      LOGGER.error("had trouble logging audit event for config changes.", e);
      return new InternalServerErrorException(e.getMessage(), e).asPromise();
    }
  }
 public static UsernameTokenState fromJson(JsonValue jsonValue) throws TokenMarshalException {
   try {
     return UsernameTokenState.builder()
         .password(
             jsonValue
                 .get(AMSTSConstants.USERNAME_TOKEN_PASSWORD)
                 .asString()
                 .getBytes(AMSTSConstants.UTF_8_CHARSET_ID))
         .username(
             jsonValue
                 .get(AMSTSConstants.USERNAME_TOKEN_USERNAME)
                 .asString()
                 .getBytes(AMSTSConstants.UTF_8_CHARSET_ID))
         .build();
   } catch (UnsupportedEncodingException e) {
     throw new TokenMarshalException(
         ResourceException.BAD_REQUEST, "Unsupported charset marshalling fromJson: " + e);
   }
 }
  @SuppressWarnings("rawtypes")
  @Test(priority = 6)
  public void testUpdate() throws Exception {
    config.put("property1", "newvalue1");
    config.put("property2", "newvalue2");

    when(enhancedConfig.getConfiguration(any(Dictionary.class), any(String.class), eq(false)))
        .thenReturn(json(config));

    configObjectService.update(rname, id, json(config)).getOrThrow();

    ConfigObjectService.ParsedId parsedId = configObjectService.getParsedId(rname, id);
    Configuration config = configObjectService.findExistingConfiguration(parsedId);
    assertNotNull(config);
    assertNotNull(config.getProperties());

    Dictionary properties = config.getProperties();
    JSONEnhancedConfig enhancedConfig = new JSONEnhancedConfig();
    JsonValue value = enhancedConfig.getConfiguration(properties, rname.toString(), false);
    assertTrue(value.keys().contains("property1"));
    Assert.assertEquals(value.get("property1").asString(), "newvalue1");
  }
 /** 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();
   }
 }
  /**
   * Handle an existing activated service getting changed; e.g. configuration changes or dependency
   * changes
   *
   * @param compContext THe OSGI component context
   * @throws Exception if handling the modified event failed
   */
  @Modified
  void modified(ComponentContext compContext) throws Exception {
    logger.debug("Handle repository service modified notification");
    JsonValue newConfig = null;
    try {
      newConfig = enhancedConfig.getConfigurationAsJson(compContext);
    } catch (RuntimeException ex) {
      logger.warn(
          "Configuration invalid and could not be parsed, can not start OrientDB repository", ex);
      throw ex;
    }
    if (existingConfig != null
        && !existingConfig.get("embeddedServer").equals(newConfig.get("embeddedServer"))) {
      // The embedded server configuration has changed so re-initialize it.
      embeddedServer.modified(newConfig);
    }
    if (existingConfig != null
        && user.equals(getUser(newConfig))
        && password.equals(getPassword(newConfig))
        && dbURL.equals(getDBUrl(newConfig))
        && poolMinSize == getPoolMinSize(newConfig)
        && poolMaxSize == getPoolMaxSize(newConfig)) {
      // If the DB pool settings don't change keep the existing pool
      logger.info("(Re-)initialize repository with latest configuration.");
    } else {
      // If the DB pool settings changed do a more complete re-initialization
      logger.info(
          "Re-initialize repository with latest configuration - including DB pool setting changes.");
      DBHelper.closePool(dbURL, pool);
    }
    init(newConfig);

    if (bootRepo != null) {
      bootRepo.init(newConfig);
    }

    existingConfig = newConfig;
    logger.debug("Repository service modified");
  }
  @Override
  public Object create() throws HeapException {
    JsonValue urlString = config.get("url").required();
    URL url = evaluateJsonStaticExpression(urlString).asURL();
    String password = evaluate(config.get("password"));
    String type = config.get("type").defaultTo(KeyStore.getDefaultType()).asString().toUpperCase();

    KeyStore keyStore = null;
    InputStream keyInput = null;
    try {
      keyStore = KeyStore.getInstance(type);
      keyInput = url.openStream();
      char[] credentials = (password == null) ? null : password.toCharArray();
      keyStore.load(keyInput, credentials);
    } catch (Exception e) {
      throw new HeapException(
          format("Cannot load %S KeyStore from %s", type, urlString.asString()), e);
    } finally {
      closeSilently(keyInput);
    }
    return keyStore;
  }
 private void init(JsonValue configuration) {
   JsonValue additionalPolicies = configuration.get("additionalFiles");
   if (!additionalPolicies.isNull()) {
     configuration.remove("additionalFiles");
     List<String> list = new ArrayList<String>();
     for (JsonValue policy : additionalPolicies) {
       try {
         list.add(FileUtil.readFile(IdentityServer.getFileForProjectPath(policy.asString())));
       } catch (Exception e) {
         logger.error("Error loading additional policy script " + policy.asString(), e);
       }
     }
     configuration.add("additionalPolicies", list);
   }
 }