PrivilegeEvaluator.java revision fb3b3a01405c222ae1fdbbe6f5c1d4aa696195bb
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster/**
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster *
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * Copyright (c) 2009 Sun Microsystems Inc. All Rights Reserved
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster *
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * The contents of this file are subject to the terms
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * of the Common Development and Distribution License
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * (the License). You may not use this file except in
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * compliance with the License.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster *
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * You can obtain a copy of the License at
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * opensso/legal/CDDLv1.0.txt
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * See the License for the specific language governing
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * permission and limitations under the License.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster *
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * When distributing Covered Code, include this CDDL
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * Header Notice in each file and include the License file
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * at opensso/legal/CDDLv1.0.txt.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * If applicable, add the following below the CDDL Header,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * with the fields enclosed by brackets [] replaced by
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * your own identifying information:
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * "Portions Copyrighted [year] [name of copyright owner]"
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster *
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * $Id: PrivilegeEvaluator.java,v 1.2 2009/10/07 06:36:40 veiming Exp $
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster *
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * Portions copyright 2010-2014 ForgeRock, Inc.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster */
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterpackage com.sun.identity.entitlement;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport com.sun.identity.entitlement.interfaces.IThreadPool;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport com.sun.identity.shared.debug.Debug;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport java.security.Principal;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport java.util.HashSet;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport java.util.Iterator;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport java.util.LinkedList;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport java.util.List;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport java.util.Map;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport java.util.Set;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport java.util.concurrent.locks.Condition;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport java.util.concurrent.locks.Lock;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport java.util.concurrent.locks.ReentrantLock;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport javax.security.auth.Subject;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport org.forgerock.openam.entitlement.PrivilegeEvaluatorContext;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterimport org.forgerock.openam.session.util.AppTokenHandler;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster/**
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * This class evaluates entitlements of a subject for a given resource
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * and a environment parameters.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster */
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Fosterclass PrivilegeEvaluator {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private String realm = "/";
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private Subject adminSubject;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private Subject subject;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private String applicationName;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private String resourceName;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private Map<String, Set<String>> envParameters;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private ResourceSearchIndexes indexes;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private List<List<Entitlement>> resultQ = new
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster LinkedList<List<Entitlement>>();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private Application application;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private Set<String> actionNames;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private EntitlementCombiner entitlementCombiner;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private boolean recursive;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private EntitlementException eException;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private final Lock lock = new ReentrantLock();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private Condition hasResults = lock.newCondition();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private final static String PRIVILEGE_EVALUATION_CONTEXT =
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster "org.forgerock.openam.entitlement.context";
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster // Static variables
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster // TODO determine number of tasks per thread
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private static int evalThreadSize = Evaluator.DEFAULT_POLICY_EVAL_THREAD;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private static int tasksPerThread = 5;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private static IThreadPool threadPool;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private static boolean isMultiThreaded;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster static {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster EntitlementConfiguration ec = EntitlementConfiguration.getInstance(
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster PrivilegeManager.superAdminSubject, "/");
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Set<String> setPolicyEvalThread = ec.getConfiguration(
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster EntitlementConfiguration.POLICY_EVAL_THREAD_SIZE);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if ((setPolicyEvalThread != null) && !setPolicyEvalThread.isEmpty()) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster try {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster evalThreadSize = Integer.parseInt(setPolicyEvalThread.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster iterator().next());
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster } catch (NumberFormatException e) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster PrivilegeManager.debug.error(
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster "PrivilegeEvaluator.<init>: get evaluation thread pool size",
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster e);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster isMultiThreaded = (evalThreadSize > 1);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster threadPool = (isMultiThreaded) ?
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster new EntitlementThreadPool(evalThreadSize) :
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster new SequentialThreadPool();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster /**
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * Initializes the evaluator.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster *
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param adminSubject Administrator subject which is used fo evcaluation.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param subject Subject to be evaluated.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param realm Realm Name
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param applicationName Application Name.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param resourceName Rsource name.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param actions Action names.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param envParameters Environment parameters.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param recursive <code>true</code> for sub tree evaluation
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @throws com.sun.identity.entitlement.EntitlementException if
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * initialization fails.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster */
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private void init(
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Subject adminSubject,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Subject subject,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster String realm,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster String applicationName,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster String resourceName,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Set<String> actions,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Map<String, Set<String>> envParameters,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster boolean recursive
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster ) throws EntitlementException {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.adminSubject = adminSubject;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.subject = subject;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.realm = realm;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.applicationName = applicationName;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.resourceName = resourceName;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.envParameters = envParameters;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Application appl = getApplication();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.actionNames = new HashSet<String>();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if ((actions == null) || actions.isEmpty()) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.actionNames.addAll(appl.getActions().keySet());
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster } else {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.actionNames.addAll(actions);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster entitlementCombiner = appl.getEntitlementCombiner();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster entitlementCombiner.init(realm, applicationName, resourceName, this.actionNames, recursive);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.recursive = recursive;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (PrivilegeManager.debug.messageEnabled()) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Debug debug = PrivilegeManager.debug;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster debug.message("[PolicyEval] PrivilegeEvaluator:init()", null);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster debug.message("[PolicyEval] subject: " + getPrincipalId(subject), null);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster debug.message("[PolicyEval] realm: " + realm, null);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster debug.message("[PolicyEval] applicationName: " + applicationName, null);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster debug.message("[PolicyEval] resourceName: " + resourceName, null);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster debug.message("[PolicyEval] actions: " + actionNames, null);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if ((envParameters != null) && !envParameters.isEmpty()) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster debug.message("[PolicyEval] envParameters: " +
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster envParameters.toString(), null);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private static String getPrincipalId(Subject subject) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (subject == null) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster return "";
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Set<Principal> userPrincipals = subject.getPrincipals();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster return ((userPrincipals != null) && !userPrincipals.isEmpty()) ?
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster userPrincipals.iterator().next().getName() : null;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster /**
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * Returrns <code>true</code> if the subject has privilege to have the
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * given entitlement.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster *
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param adminSubject Administrator subject which is used for evaluation.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param subject Subject to be evaluated.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param applicationName Application Name.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param entitlement Entitlement to be evaluated.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param envParameters Environment parameters.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @return <code>true</code> if the subject has privilege to have the
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * given entitlement.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @throws com.sun.identity.entitlement.EntitlementException if
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * evaluation fails.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster */
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster public boolean hasEntitlement(
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster String realm,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Subject adminSubject,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Subject subject,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster String applicationName,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Entitlement entitlement,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Map<String, Set<String>> envParameters
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster ) throws EntitlementException {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster init(adminSubject, subject, realm, applicationName,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster entitlement.getResourceName(),
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster entitlement.getActionValues().keySet(), envParameters, false);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster entitlement.setApplicationName(applicationName);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster indexes = entitlement.getResourceSearchIndexes(adminSubject, realm);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster List<Entitlement> results = evaluate(realm);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Entitlement result = results.get(0);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster for (String action : entitlement.getActionValues().keySet()) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Boolean b = result.getActionValue(action);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster // TODO, use policy decision combining algorithm
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster // Default is deny overrides
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if ((b == null) || !b.booleanValue()) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster return false;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster return true;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster /**
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * Returns list of entitlements which is entitled to a subject.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster *
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param adminSubject Administrator subject which is used for evaluation.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param subject Subject to be evaluated.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param applicationName Application Name.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param resourceName Resource name.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param envParameters Environment parameters.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @param recursive <code>true</code> for sub tree evaluation.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @return <code>true</code> if the subject has privilege to have the
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * given entitlement.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * @throws com.sun.identity.entitlement.EntitlementException if
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster * evaluation fails.
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster */
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster public List<Entitlement> evaluate(
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster String realm,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Subject adminSubject,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Subject subject,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster String applicationName,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster String resourceName,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Map<String, Set<String>> envParameters,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster boolean recursive
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster ) throws EntitlementException {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster init(adminSubject, subject, realm, applicationName,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster resourceName, null, envParameters, recursive);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster indexes = getApplication().getResourceSearchIndex(resourceName, realm);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster return evaluate(realm);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private List<Entitlement> evaluate(String realm)
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster throws EntitlementException {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster // Subject index
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster SubjectAttributesManager sam = SubjectAttributesManager.getInstance(
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster adminSubject, realm);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster // Search for policies
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster PrivilegeIndexStore pis = PrivilegeIndexStore.getInstance(
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster adminSubject, realm);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Iterator<IPrivilege> i = pis.search(realm, indexes,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster sam.getSubjectSearchFilter(subject, applicationName), recursive);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster // Submit the privileges for evaluation
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster // First collect tasks to be evaluated locally
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Set<IPrivilege> localPrivileges = new HashSet<IPrivilege>(
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster 2*tasksPerThread);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Debug debug = PrivilegeManager.debug;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster int totalCount = 0;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster while (totalCount != tasksPerThread) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (i.hasNext()) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster IPrivilege p = i.next();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (debug.messageEnabled()) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster debug.message("[PolicyEval] PolicyEvaluator.evaluate", null);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster debug.message("[PolicyEval] search result: privilege=" +
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster p.getName(), null);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster localPrivileges.add(p);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster totalCount++;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster } else {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster break;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster // Submit additional privilges to be executed by worker threads
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Set<IPrivilege> privileges = null;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster boolean tasksSubmitted = false;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster PrivilegeEvaluatorContext ctx =
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster new PrivilegeEvaluatorContext(realm, resourceName, applicationName);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster Object appToken = AppTokenHandler.getAndClear();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster while (true) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (!i.hasNext()) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster break;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (privileges == null) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster privileges = new HashSet<IPrivilege>(2*tasksPerThread);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster tasksSubmitted = true;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster IPrivilege p = i.next();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (debug.messageEnabled()) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster debug.message("[PolicyEval] PolicyEvaluator.evaluate", null);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster debug.message("[PolicyEval] search result: privilege=" +
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster p.getName(), null);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster privileges.add(p);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster totalCount++;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if ((totalCount % tasksPerThread) == 0) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster threadPool.submit(new PrivilegeTask(this, privileges,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster isMultiThreaded, appToken, ctx));
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster privileges.clear();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if ((privileges != null) && !privileges.isEmpty()) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster threadPool.submit(new PrivilegeTask(this, privileges,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster isMultiThreaded, appToken, ctx));
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster // IPrivilege privileges locally
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster (new PrivilegeTask(this, localPrivileges, tasksSubmitted, appToken, ctx)).run();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster // Wait for submitted threads to complete evaluation
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (tasksSubmitted) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (isMultiThreaded) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster receiveEvalResults(totalCount);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster } else {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster boolean isDone = false;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster while (!resultQ.isEmpty() && !isDone) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster entitlementCombiner.add(resultQ.remove(0));
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster isDone = entitlementCombiner.isDone();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster } else if (eException == null) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster boolean isDone = false;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster while (!resultQ.isEmpty() && !isDone) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster entitlementCombiner.add(resultQ.remove(0));
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster isDone = entitlementCombiner.isDone();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (eException != null) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster throw eException;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster List<Entitlement> ents = entitlementCombiner.getResults();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster return ents;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private void receiveEvalResults(int totalCount) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster int counter = 0;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster lock.lock();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster boolean isDone = (eException != null);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster try {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster while (!isDone && (counter < totalCount)) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (resultQ.isEmpty()) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster hasResults.await();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster while (!resultQ.isEmpty() && !isDone) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster entitlementCombiner.add(resultQ.remove(0));
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster isDone = entitlementCombiner.isDone();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster counter++;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster } catch (InterruptedException ex) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster PrivilegeManager.debug.error("PrivilegeEvaluator.evaluate", ex);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster } finally {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster lock.unlock();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private Application getApplication()
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster throws EntitlementException {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (application == null) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster application = ApplicationManager.getApplicationForEvaluation(
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster realm, applicationName);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster // If application is still null, throw an exception
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (application == null) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster String[] params = { realm };
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster throw (new EntitlementException(248, params));
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster return application;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster class PrivilegeTask implements Runnable {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster final PrivilegeEvaluator parent;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private Set<IPrivilege> privileges;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private boolean isThreaded;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private Object context;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster private PrivilegeEvaluatorContext ctx;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster PrivilegeTask(PrivilegeEvaluator parent, Set<IPrivilege> privileges,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster boolean isThreaded, Object context, PrivilegeEvaluatorContext ctx) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.parent = parent;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.privileges = new HashSet<IPrivilege>(privileges.size() *2);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.privileges.addAll(privileges);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.isThreaded = isThreaded;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.context = context;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster this.ctx = ctx;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster public void run() {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster PrivilegeEvaluatorContext.setCurrent(ctx);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster try {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster for (final IPrivilege eval : privileges) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster List<Entitlement> entitlements = eval.evaluate(
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.adminSubject,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.realm, parent.subject,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.applicationName, parent.resourceName,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.actionNames, parent.envParameters,
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.recursive, context);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (entitlements != null) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (isThreaded) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster try {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.lock.lock();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.resultQ.add(entitlements);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.hasResults.signal();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster } finally {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.lock.unlock();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster } else {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.resultQ.add(entitlements);
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster } catch (EntitlementException ex) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster if (isThreaded) {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster try {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.lock.lock();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.eException = ex;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.hasResults.signal();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster } finally {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.lock.unlock();
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster } else {
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster parent.eException = ex;
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster }
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster}
837871e12425577ebe5d6f129d18ea78dd0e640eAllan Foster