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(); } }
/** 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(); } } }
/** * 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(); } }
/** * 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; }