6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey/*
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * The contents of this file are subject to the terms of the Common Development and
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * Distribution License (the License). You may not use this file except in compliance with the
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * License.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey *
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * specific language governing permission and limitations under the License.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey *
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * When distributing Covered Software, include this CDDL Header Notice in each file and include
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * Header, with the fields enclosed by brackets [] replaced by your own identifying
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * information: "Portions copyright [year] [name of copyright owner]".
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey *
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * Copyright 2015 ForgeRock AS.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey */
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseypackage org.forgerock.openam.uma.rest;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport javax.inject.Inject;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport javax.security.auth.Subject;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport java.security.AccessController;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport java.util.Collections;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport java.util.HashMap;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport java.util.Map;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport com.iplanet.sso.SSOException;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport com.iplanet.sso.SSOToken;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport com.iplanet.sso.SSOTokenManager;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport com.sun.identity.entitlement.Application;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport com.sun.identity.entitlement.EntitlementException;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport com.sun.identity.entitlement.opensso.SubjectUtils;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport com.sun.identity.security.AdminTokenAction;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport com.sun.identity.shared.debug.Debug;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport com.sun.identity.xacml.context.ContextFactory;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.http.routing.UriRouterContext;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.oauth2.core.OAuth2Request;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.oauth2.core.exceptions.ServerException;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.oauth2.resources.ResourceSetDescription;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.oauth2.restlet.resources.ResourceSetRegistrationHook;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.openam.entitlement.ResourceType;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.openam.entitlement.service.ResourceTypeService;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.openam.entitlement.rest.wrappers.ApplicationManagerWrapper;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.openam.rest.RealmContext;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.openam.rest.resource.AdminSubjectContext;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.openam.rest.resource.SubjectContext;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.openam.session.SessionCache;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.openam.uma.UmaConstants;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.openam.uma.UmaPolicyService;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.services.context.AbstractContext;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.services.context.Context;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.services.context.RootContext;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseyimport org.forgerock.util.Reject;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey/**
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * Hook implementation for creating a ResourceType for each Resource Set registration.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey *
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * @since 13.0.0
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey */
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumseypublic class UmaResourceSetRegistrationHook implements ResourceSetRegistrationHook {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey private final Debug logger = Debug.getInstance("UmaProvider");
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey private final ResourceTypeService resourceTypeService;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey private final ApplicationManagerWrapper applicationManager;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey private final UmaPolicyService policyService;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey private final SessionCache sessionCache;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey /**
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * Creates a new UmaResourceSetRegistrationHook instance.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * @param resourceTypeService An instance of the {@code ResourceTypeService}.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * @param applicationManager An instance of the {@code ApplicationManagerWrapper}.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * @param policyService An instance of the {@code UmaPolicyService}.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * @param sessionCache An instance of the {@code SessionCache}.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey */
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey @Inject
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey public UmaResourceSetRegistrationHook(ResourceTypeService resourceTypeService,
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey ApplicationManagerWrapper applicationManager, UmaPolicyService policyService, SessionCache sessionCache)
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey throws EntitlementException{
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey this.resourceTypeService = resourceTypeService;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey this.applicationManager = applicationManager;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey this.policyService = policyService;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey this.sessionCache = sessionCache;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey }
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey /**
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * Creates a ResourceType for the Resource Set and adds it to the Resource Server's policy Application.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey *
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * @param realm {@inheritDoc}
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * @param resourceSet {@inheritDoc}
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey */
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey @Override
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey public void resourceSetCreated(String realm, ResourceSetDescription resourceSet)
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey throws ServerException
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey Map<String, Boolean> resourceTypeActions = new HashMap<String, Boolean>();
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey for (String umaScope : resourceSet.getScopes()) {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey resourceTypeActions.put(umaScope, Boolean.TRUE);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey }
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey ResourceType resourceType = ResourceType.builder()
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey .setName(resourceSet.getName() + " - " + resourceSet.getId())
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey .setUUID(resourceSet.getId())
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey .setDescription("Dynamically created resource type for the UMA resource set. " +
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey "Used to find all Policy Engine Policies that make up an UMA Policy")
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey .setActions(resourceTypeActions)
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey .addPattern(UmaConstants.UMA_POLICY_SCHEME_PATTERN).build();
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey Subject adminSubject = SubjectUtils.createSuperAdminSubject();
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey try {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey resourceTypeService.saveResourceType(adminSubject, realm, resourceType);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey } catch (EntitlementException e) {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey logger.error("Failed to create resource type for resource set, {}", resourceSet, e);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey throw new ServerException(e);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey }
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey try {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey Application application = applicationManager.getApplication(adminSubject, realm,
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey resourceSet.getClientId().toLowerCase());
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey application.addResourceTypeUuid(resourceType.getUUID());
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey applicationManager.saveApplication(adminSubject, realm, application);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey } catch (EntitlementException e) {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey logger.error("Failed to add Resource Type, " + resourceType.getUUID() + " to application, "
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey + resourceSet.getClientId(), e);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey throw new ServerException(e);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey }
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey }
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey /**
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * Removes the ResourceType from the Resource Server's policy application, deletes all related policies,
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * then deletes the ResourceSet.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey *
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * @param realm {@inheritDoc}
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * @param resourceSet {@inheritDoc}
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey */
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey @Override
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey public void resourceSetDeleted(String realm, ResourceSetDescription resourceSet) throws ServerException {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey Subject adminSubject = SubjectUtils.createSuperAdminSubject();
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey String resourceTypeUUID = resourceSet.getId();
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey try {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey Application application = applicationManager.getApplication(adminSubject, realm,
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey resourceSet.getClientId().toLowerCase());
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey application.removeResourceTypeUuid(resourceTypeUUID);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey applicationManager.saveApplication(adminSubject, realm, application);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey } catch (EntitlementException e) {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey logger.error("Failed to remove Resource Type, " + resourceTypeUUID + " from application, "
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey + resourceSet.getClientId(), e);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey throw new ServerException(e);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey }
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey policyService.deletePolicy(createAdminContext(realm, resourceSet.getResourceOwnerId()), resourceSet.getId());
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey try {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey resourceTypeService.deleteResourceType(adminSubject, realm, resourceTypeUUID);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey } catch (EntitlementException e) {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey logger.error("Failed to delete Resource Type " + resourceTypeUUID, e);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey throw new ServerException(e);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey }
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey }
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey /**
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * Used to create a context for deleting policies. If this is being called, we know that the user has the right
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * to delete the policies.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * @param realm The realm to delete the policies in.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * @param resourceOwnerId The owner of the ResourceSet that the policies are for.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey * @return The generated context.
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey */
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey private Context createAdminContext(String realm, String resourceOwnerId) {
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey RealmContext realmContext = new RealmContext(new RootContext());
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey realmContext.setSubRealm(realm, realm);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey SubjectContext subjectContext = new AdminSubjectContext(logger, sessionCache,realmContext);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey Map<String, String> templateVariables = new HashMap<>();
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey templateVariables.put("user", resourceOwnerId);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey UriRouterContext routerContext = new UriRouterContext(subjectContext, "", "", templateVariables);
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey return routerContext;
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey }
6d056488bd101f34dc12cb4b179d8991f9d3448aTom Rumsey}