/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2008 Sun Microsystems Inc. All Rights Reserved * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * https://opensso.dev.java.net/public/CDDLv1.0.html or * opensso/legal/CDDLv1.0.txt * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at opensso/legal/CDDLv1.0.txt. * If applicable, addReferral the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * $Id: PolicyPrivilegeManager.java,v 1.9 2010/01/26 20:10:15 dillidorai Exp $ * * Portions Copyrighted 2014-2016 ForgeRock AS. */ package com.sun.identity.entitlement.opensso; import static org.forgerock.json.JsonValue.field; import static org.forgerock.json.JsonValue.json; import static org.forgerock.json.JsonValue.object; import static org.forgerock.openam.utils.Time.newDate; import java.security.AccessController; import java.security.Principal; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.inject.Inject; import javax.security.auth.Subject; import org.forgerock.json.JsonValue; import org.forgerock.openam.entitlement.constraints.ConstraintValidator; import org.forgerock.openam.entitlement.service.ApplicationServiceFactory; import org.forgerock.openam.entitlement.service.ResourceTypeService; import org.forgerock.openam.notifications.NotificationBroker; import org.forgerock.openam.notifications.NotificationsConfig; import org.forgerock.openam.notifications.Topic; import org.forgerock.util.Reject; import com.iplanet.sso.SSOToken; import com.sun.identity.entitlement.ApplicationPrivilege; import com.sun.identity.entitlement.ApplicationPrivilegeManager; import com.sun.identity.entitlement.EntitlementException; import com.sun.identity.entitlement.PolicyDataStore; import com.sun.identity.entitlement.PolicyEventType; import com.sun.identity.entitlement.Privilege; import com.sun.identity.entitlement.PrivilegeChangeNotifier; import com.sun.identity.entitlement.PrivilegeIndexStore; import com.sun.identity.entitlement.PrivilegeManager; import com.sun.identity.security.AdminTokenAction; /** * Implementation of PrivilegeManager that saves privileges as com.sun.identity.policy objects */ public class PolicyPrivilegeManager extends PrivilegeManager { private String realm = "/"; private static Subject dsameUserSubject; private final NotificationBroker broker; private final NotificationsConfig notificationsConfig; static { SSOToken adminToken = AccessController.doPrivileged(AdminTokenAction.getInstance()); dsameUserSubject = SubjectUtils.createSubject(adminToken); try { if (PrivilegeManager.debug.messageEnabled()) { PrivilegeManager.debug.message( "PolicyPrivilegeManager.static initializer, getting instance of PolicyCache"); } } catch (Exception e) { PrivilegeManager.debug.error("PolicyPrivilegeManager.static initializer failed to create PolicyCache", e); } } /** * Creates instance of PolicyPrivilegeManager */ @Inject public PolicyPrivilegeManager(ApplicationServiceFactory applicationServiceFactory, ResourceTypeService resourceTypeService, ConstraintValidator constraintValidator, NotificationBroker broker, NotificationsConfig notificationsConfig) { super(applicationServiceFactory, resourceTypeService, constraintValidator); this.broker = broker; this.notificationsConfig = notificationsConfig; } /** * Initializes the object * * @param subject subject that would be used for privilege management * operations */ @Override public void initialize(String realm, Subject subject) { super.initialize(realm, subject); this.realm = realm; SSOToken ssoToken = SubjectUtils.getSSOToken(subject); } /** * Finds a privilege by its unique name. * * @param name name of the privilege to be returned * @throws com.sun.identity.entitlement.EntitlementException if privilege is not found. */ @Override public Privilege findByName(String name) throws EntitlementException { return findByName(name, getAdminSubject()); } @Override public Privilege findByName(String privilegeName, Subject adminSubject) throws EntitlementException { if (privilegeName == null) { throw new EntitlementException(12); } Privilege privilege = null; PrivilegeIndexStore pis = PrivilegeIndexStore.getInstance(adminSubject, getRealm()); privilege = (Privilege) pis.getPrivilege(privilegeName); if (privilege == null) { throw new EntitlementException(EntitlementException.NO_SUCH_POLICY, new Object[] {privilegeName}); } if (adminSubject != PrivilegeManager.superAdminSubject) { if (privilege != null) { // Delegation to applications is currently not configurable, passing super admin (see AME-4959) ApplicationPrivilegeManager applPrivilegeMgr = ApplicationPrivilegeManager.getInstance(realm, PrivilegeManager.superAdminSubject); if (applPrivilegeMgr == null) { return null; } if (!applPrivilegeMgr.hasPrivilege(privilege, ApplicationPrivilege.Action.READ)) { throw new EntitlementException(326); } } } return privilege; } @Override public List findAllPolicies() throws EntitlementException { PrivilegeIndexStore indexStore = PrivilegeIndexStore.getInstance(getAdminSubject(), getRealm()); if (indexStore == null) { throw new NullPointerException("Policy index store not initialised"); } return indexStore.findAllPolicies(); } @Override public List findAllPoliciesByApplication(String application) throws EntitlementException { PrivilegeIndexStore indexStore = PrivilegeIndexStore.getInstance(getAdminSubject(), getRealm()); if (indexStore == null) { throw new NullPointerException("Policy index store not initialised"); } return indexStore.findAllPoliciesByApplication(application); } @Override public List findAllPoliciesByIdentityUid(String uid) throws EntitlementException { Reject.ifNull(uid); PrivilegeIndexStore indexStore = PrivilegeIndexStore.getInstance(getAdminSubject(), getRealm()); Reject.ifNull(indexStore, "Policy index store not initialised"); return indexStore.findAllPoliciesByIdentityUid(uid); } /** * Add a privilege. * * @param privilege privilege to add. * @throws EntitlementException if privilege cannot be added. */ @Override public void add(Privilege privilege) throws EntitlementException { super.add(privilege); PolicyDataStore pdb = PolicyDataStore.getInstance(); String currentRealm = getRealm(); pdb.addPolicy(getAdminSubject(), currentRealm, privilege); notifyPrivilegeChanged(currentRealm, null, privilege, PolicyEventType.CREATE); } /** * Remove a privilege. * * @param name name of the privilege to be removed. * @throws EntitlementException if privilege cannot be removed. */ @Override public void remove(String name) throws EntitlementException { if (name == null) { throw new EntitlementException(12); } Privilege privilege = findByName(name); if (privilege != null) { String currentRealm = getRealm(); Subject adminSubject = getAdminSubject(); PolicyDataStore pdb = PolicyDataStore.getInstance(); pdb.removePrivilege(adminSubject, currentRealm, privilege); notifyPrivilegeChanged(currentRealm, null, privilege, PolicyEventType.DELETE); } } private void updateMetaInfo(String existingName, Privilege privilege) throws EntitlementException { Privilege origPrivilege = findByName(existingName, PrivilegeManager.superAdminSubject); if (origPrivilege != null) { privilege.setCreatedBy(origPrivilege.getCreatedBy()); privilege.setCreationDate(origPrivilege.getCreationDate()); } Date date = newDate(); privilege.setLastModifiedDate(date.getTime()); Set principals = getAdminSubject().getPrincipals(); if ((principals != null) && !principals.isEmpty()) { privilege.setLastModifiedBy(principals.iterator().next().getName()); } } /** * Modify a privilege. * * @param existingName the name with which the privilege is currently stored * @param privilege the privilege to be modified * @throws com.sun.identity.entitlement.EntitlementException if privilege cannot be modified. */ @Override public void modify(String existingName, Privilege privilege) throws EntitlementException { validate(privilege); updateMetaInfo(existingName, privilege); PolicyDataStore pdb = PolicyDataStore.getInstance(); Privilege oldP = findByName(existingName, getAdminSubject()); String currentRealm = getRealm(); pdb.removePrivilege(getAdminSubject(), currentRealm, oldP); pdb.addPolicy(getAdminSubject(), currentRealm, privilege); notifyPrivilegeChanged(currentRealm, oldP, privilege, PolicyEventType.UPDATE); } /** * Modify a privilege. * * @param privilege the privilege to be modified * @throws com.sun.identity.entitlement.EntitlementException if privilege cannot be modified. */ @Override public void modify(Privilege privilege) throws EntitlementException { modify(privilege.getName(), privilege); } @Override protected void notifyPrivilegeChanged(String realm, Privilege previous, Privilege current, PolicyEventType eventType) throws EntitlementException { Set resourceNames = new HashSet(); if (previous != null) { Set r = previous.getEntitlement().getResourceNames(); if (r != null) { resourceNames.addAll(r); } } Set r = current.getEntitlement().getResourceNames(); if (r != null) { resourceNames.addAll(r); } String applicationName = current.getEntitlement().getApplicationName(); if (PrivilegeManager.debug.messageEnabled()) { PrivilegeManager.debug.message("PolicyPrivilegeManager.notifyPrivilegeChanged():" + "applicationName=" + applicationName + ", resources=" + resourceNames); } if (notificationsConfig.isAgentsEnabled()) { JsonValue json = json(object( field("realm", realm), field("policy", current.getName()), field("policySet", applicationName), field("eventType", eventType) )); broker.publish(Topic.of("/agent/policy"), json); } PrivilegeChangeNotifier.getInstance().notify(getAdminSubject(), realm, applicationName, current.getName(), resourceNames); } }