Search in sources :

Example 1 with PatchOperation

use of org.forgerock.json.resource.PatchOperation in project OpenAM by OpenRock.

the class IdentityResourceV3 method patchInstance.

/**
     * Patch the user's password and only the password.  No other value may be patched.  The old value of the
     * password does not have to be known.  Admin only.  The only patch operation supported is "replace", i.e. not
     * "add" or "move", etc.
     *
     * @param context The context
     * @param resourceId The username we're patching
     * @param request The patch request
     */
@Override
public Promise<ResourceResponse, ResourceException> patchInstance(final Context context, final String resourceId, final PatchRequest request) {
    if (!objectType.equals(IdentityRestUtils.USER_TYPE)) {
        return new BadRequestException("Cannot patch object type " + objectType).asPromise();
    }
    RealmContext realmContext = context.asContext(RealmContext.class);
    final String realm = realmContext.getResolvedRealm();
    try {
        if (!isAdmin(context)) {
            return new ForbiddenException("Only admin can patch user values").asPromise();
        }
        SSOToken ssoToken = getSSOToken(RestUtils.getToken().getTokenID().toString());
        IdentityServicesImpl identityServices = getIdentityServices();
        IdentityDetails identityDetails = identityServices.read(resourceId, getIdentityServicesAttributes(realm, objectType), ssoToken);
        Attribute[] existingAttributes = identityDetails.getAttributes();
        Map<String, Set<String>> existingAttributeMap = attributesToMap(existingAttributes);
        Map<String, Set<String>> newAttributeMap = new HashMap<>();
        if (existingAttributeMap.containsKey(IdentityRestUtils.UNIVERSAL_ID)) {
            Set<String> values = existingAttributeMap.get(IdentityRestUtils.UNIVERSAL_ID);
            if (isNotEmpty(values) && !isUserActive(values.iterator().next())) {
                return new ForbiddenException("User " + resourceId + " is not active: Request is forbidden").asPromise();
            }
        }
        boolean updateNeeded = false;
        for (PatchOperation patchOperation : request.getPatchOperations()) {
            switch(patchOperation.getOperation()) {
                case PatchOperation.OPERATION_REPLACE:
                    {
                        String name = getFieldName(patchOperation.getField());
                        if (!patchableAttributes.contains(name)) {
                            return new BadRequestException("For the object type " + IdentityRestUtils.USER_TYPE + ", field \"" + name + "\" cannot be altered by PATCH").asPromise();
                        }
                        JsonValue value = patchOperation.getValue();
                        newAttributeMap.put(name, identityAttributeJsonToSet(value));
                        updateNeeded = true;
                        break;
                    }
                default:
                    return new BadRequestException("PATCH of " + IdentityRestUtils.USER_TYPE + " does not support operation " + patchOperation.getOperation()).asPromise();
            }
        }
        if (updateNeeded) {
            identityDetails.setAttributes(mapToAttributes(newAttributeMap));
            identityServices.update(identityDetails, ssoToken);
            // re-read the altered identity details from the repo.
            identityDetails = identityServices.read(resourceId, getIdentityServicesAttributes(realm, objectType), ssoToken);
        }
        return newResultPromise(newResourceResponse("result", "1", identityDetailsToJsonValue(identityDetails)));
    } catch (final ObjectNotFound notFound) {
        logger.error("IdentityResourceV3.patchInstance cannot find resource " + resourceId, notFound);
        return new NotFoundException("Resource cannot be found.", notFound).asPromise();
    } catch (final TokenExpired tokenExpired) {
        logger.error("IdentityResourceV3.patchInstance, token expired", tokenExpired);
        return new PermanentException(401, "Unauthorized", null).asPromise();
    } catch (final AccessDenied accessDenied) {
        logger.error("IdentityResourceV3.patchInstance, access denied", accessDenied);
        return new ForbiddenException(accessDenied.getMessage(), accessDenied).asPromise();
    } catch (final GeneralFailure generalFailure) {
        logger.error("IdentityResourceV3.patchInstance, general failure " + generalFailure.getMessage());
        return new BadRequestException(generalFailure.getMessage(), generalFailure).asPromise();
    } catch (ForbiddenException fex) {
        logger.warning("IdentityResourceV3.patchInstance, insufficient privileges.", fex);
        return fex.asPromise();
    } catch (NotFoundException notFound) {
        logger.warning("IdentityResourceV3.patchInstance " + resourceId + " not found", notFound);
        return new NotFoundException("Resource " + resourceId + " cannot be found.", notFound).asPromise();
    } catch (ResourceException resourceException) {
        logger.warning("IdentityResourceV3.patchInstance caught ResourceException", resourceException);
        return resourceException.asPromise();
    } catch (Exception exception) {
        logger.error("IdentityResourceV3.patchInstance caught exception", exception);
        return new InternalServerErrorException(exception.getMessage(), exception).asPromise();
    }
}
Also used : SSOToken(com.iplanet.sso.SSOToken) Set(java.util.Set) HashSet(java.util.HashSet) Attribute(com.sun.identity.idsvcs.Attribute) HashMap(java.util.HashMap) NotFoundException(org.forgerock.json.resource.NotFoundException) IdentityServicesImpl(com.sun.identity.idsvcs.opensso.IdentityServicesImpl) ObjectNotFound(com.sun.identity.idsvcs.ObjectNotFound) PermanentException(org.forgerock.json.resource.PermanentException) PatchOperation(org.forgerock.json.resource.PatchOperation) TokenExpired(com.sun.identity.idsvcs.TokenExpired) ResourceException(org.forgerock.json.resource.ResourceException) ForbiddenException(org.forgerock.json.resource.ForbiddenException) RealmContext(org.forgerock.openam.rest.RealmContext) JsonValue(org.forgerock.json.JsonValue) AccessDenied(com.sun.identity.idsvcs.AccessDenied) PermanentException(org.forgerock.json.resource.PermanentException) InternalServerErrorException(org.forgerock.json.resource.InternalServerErrorException) ForbiddenException(org.forgerock.json.resource.ForbiddenException) NotFoundException(org.forgerock.json.resource.NotFoundException) BadRequestException(org.forgerock.json.resource.BadRequestException) ResourceException(org.forgerock.json.resource.ResourceException) GeneralFailure(com.sun.identity.idsvcs.GeneralFailure) BadRequestException(org.forgerock.json.resource.BadRequestException) IdentityDetails(com.sun.identity.idsvcs.IdentityDetails) InternalServerErrorException(org.forgerock.json.resource.InternalServerErrorException)

Aggregations

SSOToken (com.iplanet.sso.SSOToken)1 AccessDenied (com.sun.identity.idsvcs.AccessDenied)1 Attribute (com.sun.identity.idsvcs.Attribute)1 GeneralFailure (com.sun.identity.idsvcs.GeneralFailure)1 IdentityDetails (com.sun.identity.idsvcs.IdentityDetails)1 ObjectNotFound (com.sun.identity.idsvcs.ObjectNotFound)1 TokenExpired (com.sun.identity.idsvcs.TokenExpired)1 IdentityServicesImpl (com.sun.identity.idsvcs.opensso.IdentityServicesImpl)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 JsonValue (org.forgerock.json.JsonValue)1 BadRequestException (org.forgerock.json.resource.BadRequestException)1 ForbiddenException (org.forgerock.json.resource.ForbiddenException)1 InternalServerErrorException (org.forgerock.json.resource.InternalServerErrorException)1 NotFoundException (org.forgerock.json.resource.NotFoundException)1 PatchOperation (org.forgerock.json.resource.PatchOperation)1 PermanentException (org.forgerock.json.resource.PermanentException)1 ResourceException (org.forgerock.json.resource.ResourceException)1 RealmContext (org.forgerock.openam.rest.RealmContext)1