001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: PolicyEvaluator.java,v 1.7 2009/10/21 23:50:46 dillidorai Exp $
026 *
027 * Portions Copyrighted 2013-2014 ForgeRock AS.
028 */
029package com.sun.identity.policy.client;
030
031import com.sun.identity.shared.debug.Debug;
032import com.iplanet.dpro.session.SessionException;
033import com.iplanet.sso.SSOException;
034import com.iplanet.sso.SSOToken;
035import com.iplanet.sso.SSOTokenManager; 
036import com.sun.identity.policy.ActionDecision;
037import com.sun.identity.policy.PolicyDecision;
038import com.sun.identity.policy.ResBundleUtils;
039import com.sun.identity.policy.PolicyException;
040import com.sun.identity.policy.PolicyUtils;
041import com.sun.identity.policy.remote.PolicyEvaluationException;
042import com.sun.identity.security.AdminTokenAction;
043import com.sun.identity.security.AppSSOTokenProvider;
044import com.sun.identity.log.Logger;
045import com.sun.identity.log.LogRecord;
046import com.sun.identity.policy.interfaces.ResourceName;
047import org.forgerock.util.thread.listener.ShutdownListener;
048import org.forgerock.util.thread.listener.ShutdownManager;
049
050import java.util.HashSet;
051import java.util.Iterator;
052import java.util.Map;
053import java.util.Set;
054import java.util.logging.Level;
055import java.security.AccessController;
056
057/**
058 * This class provides methods to get policy decisions 
059 * for clients of policy service.
060 * This class uses XML/HTTP protocol to 
061 * communicate with the Policy Service.
062 * Policy client API implementation caches policy decision locally.
063 * The cache is updated through policy change notifications and/or
064 * polling.
065 *
066 * @supported.api
067 */
068public class PolicyEvaluator {
069
070    static Debug debug = Debug.getInstance("amRemotePolicy");
071    private PolicyProperties policyProperties;
072    private String serviceName;
073    private SSOTokenManager ssoTokenManager;
074
075    /**
076     * Reference to singleton ResourceResultCache instance
077     */
078    private ResourceResultCache resourceResultCache;
079
080    AppSSOTokenProvider appSSOTokenProvider;
081
082    /**
083     * Logger object for access messages
084     */
085    static Logger accessLogger;
086
087    /**
088     * Logger object for error messages
089     */
090    static Logger errorLogger;
091
092    private static final String GET_RESPONSE_ATTRIBUTES 
093            = "Get_Response_Attributes";
094
095    private SSOToken appSSOToken;
096
097    /*
098     * Number of attempts to make to server if policy decision received
099     * from server has expired ttl
100     */
101    private final static int RETRY_COUNT = 3;
102
103    private String logActions;
104
105    /**
106     * Creates an instance of client policy evaluator 
107     *
108     * @param serviceName name of the service for which to create 
109     * policy evaluator
110     *
111     * @throws PolicyException if required properties cannot be retrieved.
112     * @throws SSOException if application single sign on token is invalid.
113     *
114     * @supported.api
115     */
116    public PolicyEvaluator(String serviceName)
117                        throws PolicyException, SSOException {
118        if (debug.messageEnabled()) {
119            debug.message("PolicyEvaluator():Creating PolicyEvaluator:" 
120                    + "serviceName=" + serviceName );
121        }
122        init(serviceName, null); //null appSSOTokenProvider
123    }
124
125    /**
126     * Creates an instance of client policy evaluator 
127     *
128     * @param serviceName name of the service for which to create 
129     *        policy evaluator.
130     * @param appSSOTokenProvider an object where application single sign on
131     *        token can be obtained.
132     * @throws PolicyException if required properties cannot be retrieved.
133     * @throws SSOException if application single sign on token is invalid.
134     */
135    PolicyEvaluator(String serviceName, 
136            AppSSOTokenProvider appSSOTokenProvider)
137            throws PolicyException, SSOException {
138        if (debug.messageEnabled()) {
139            debug.message("PolicyEvaluator():Creating PolicyEvaluator:" 
140                    + "serviceName="+ serviceName 
141                    + ":appSSOTokenProvider=" + appSSOTokenProvider);
142        }
143        if (serviceName == null) {
144            if (debug.warningEnabled()) {
145                debug.warning("PolicyEvaluator():"
146                        + "serviceName is null");
147            }
148            return;
149        } //else do the following
150
151        init(serviceName, appSSOTokenProvider);
152    }
153
154    /**
155     * Initializes an instance of client policy evaluator object
156     *
157     * @param serviceName name of the service for which to create 
158     *        policy evaluator
159     * @param appSSOTokenProvider an object where application single sign on
160     *        token can be obtained.
161     *
162     * @throws PolicyException if required properties cannot be retrieved.
163     * @throws SSOException if application single sign on token is invalid.
164     *
165     */
166    private void init(final String serviceName,
167                      AppSSOTokenProvider appSSOTokenProvider)
168            throws PolicyException, SSOException {
169        this.ssoTokenManager = SSOTokenManager.getInstance();
170        this.serviceName = serviceName;
171        this.appSSOTokenProvider = appSSOTokenProvider;
172        this.policyProperties = new PolicyProperties();
173        this.logActions = policyProperties.getLogActions();
174        this.resourceResultCache 
175                = ResourceResultCache.getInstance(policyProperties);
176        appSSOToken = getNewAppSSOToken();
177
178        if (PolicyProperties.previouslyNotificationEnabled()) {
179            if (policyProperties.useRESTProtocol()) {
180                resourceResultCache.removeRESTRemotePolicyListener(appSSOToken,
181                        serviceName, PolicyProperties.getPreviousNotificationURL());
182            } else {
183                resourceResultCache.removeRemotePolicyListener(appSSOToken,
184                        serviceName, PolicyProperties.getPreviousNotificationURL());
185            }
186        }
187
188        if (policyProperties.notificationEnabled()) {
189
190            // register remote policy listener policy service
191            if (debug.messageEnabled()) {
192                debug.message( "PolicyEvaluator.init():"
193                        + "adding remote policy listener with policy "
194                        + "service " + serviceName);
195
196            }
197            if (policyProperties.useRESTProtocol()) {
198                resourceResultCache.addRESTRemotePolicyListener(appSSOToken,
199                        serviceName, policyProperties.getRESTNotificationURL());
200            } else {
201                resourceResultCache.addRemotePolicyListener(appSSOToken,
202                        serviceName, policyProperties.getNotificationURL());
203            }
204            // Add a hook to remove our listener on shutdown.
205            ShutdownManager shutdownMan = com.sun.identity.common.ShutdownManager.getInstance();
206
207            shutdownMan.addShutdownListener(new ShutdownListener() {
208                @Override
209                public void shutdown() {
210                    if (policyProperties.useRESTProtocol()) {
211                        resourceResultCache.removeRESTRemotePolicyListener(appSSOToken,
212                                serviceName, policyProperties.getRESTNotificationURL());
213                        if (debug.messageEnabled()) {
214                            debug.message("PolicyEvaluator: called removeRESTRemotePolicyListener, service "
215                                    + serviceName + ", URL " + policyProperties.getRESTNotificationURL());
216                        }
217                    } else {
218                        resourceResultCache.removeRemotePolicyListener(appSSOToken,
219                                serviceName, policyProperties.getNotificationURL());
220                        if (debug.messageEnabled()) {
221                            debug.message("PolicyEvaluator: called removeRemotePolicyListener, service "
222                                    + serviceName + ", URL " + policyProperties.getNotificationURL());
223                        }
224                    }
225                }
226            });
227
228        }
229
230        ActionDecision.setClientClockSkew(policyProperties.getClientClockSkew());
231
232        if (debug.messageEnabled()) {
233            debug.message("PolicyEvaluator:"
234                    + "initialized PolicyEvaluator");
235        }
236    }
237
238    /**
239     * Evaluates a simple privilege of boolean type. The privilege indicates
240     * if the user can perform specified action on the specified resource.
241     *
242     * @param token single sign on token of the user evaluating policies
243     * @param resourceName name of the resource the user is trying to access
244     * @param actionName name of the action the user is trying to perform on
245     * the resource
246     *
247     * @return the result of the evaluation as a boolean value
248     * @throws PolicyException if result could not be computed for any
249     *         reason other than single sign on token problem.
250     * @throws SSOException if single sign on token is not valid 
251     *
252     */
253    public boolean isAllowed(SSOToken token, String resourceName,
254                             String actionName) throws PolicyException,
255                             SSOException {
256        return isAllowed(token, resourceName, actionName, null); //null env Map
257    }
258
259    /**
260     * Evaluates simple privileges of boolean type. The privilege indicates
261     * if the user can perform specified action on the specified resource.
262     * The evaluation also depends on user's application environment parameters.
263     *
264     * @param token single sign on token of the user evaluating policies.
265     * @param resourceName name of the resource the user is trying to access
266     * @param actionName name of the action the user is trying to perform on
267     * the resource
268     * @param envParameters run time environment parameters
269     *
270     * @return the result of the evaluation as a boolean value
271     *
272     * @throws PolicyException if result could not be computed for
273     *         reason other than single sign on token problem.
274     * @throws SSOException if single sign on token is not valid
275     *
276     * @supported.api
277     */
278    public boolean isAllowed(SSOToken token, String resourceName,
279                             String actionName,
280                             Map envParameters) throws PolicyException,
281                             SSOException {
282        if (debug.messageEnabled()) {
283            debug.message("PolicyEvaluator:isAllowed():"
284                    + "token=" + token.getPrincipal().getName() 
285                    + ":resourceName="+ resourceName 
286                    + ":actionName=" + actionName 
287                    + ":envParameters) : entering");
288        }
289
290        boolean actionAllowed = false;
291        Set actionNames = new HashSet(1);
292        actionNames.add(actionName);
293        PolicyDecision policyDecision = getPolicyDecision(token, resourceName,
294                                   actionNames, envParameters);
295        ActionDecision actionDecision = 
296                (ActionDecision) policyDecision.getActionDecisions()
297                .get(actionName);
298        String  trueValue = policyProperties.getTrueValue(serviceName,
299                actionName);
300        String  falseValue = policyProperties.getFalseValue(serviceName,
301                actionName);
302
303        if ( (actionDecision != null) && (trueValue != null) 
304                    && (falseValue != null)  ) {
305            Set set = (Set) actionDecision.getValues();
306            if ( (set != null) ) {
307                if ( set.contains(falseValue) ) {
308                    actionAllowed = false;
309                } else if ( set.contains(trueValue) ) {
310                    actionAllowed = true;
311                }
312            }
313        }
314
315        String result = actionAllowed ? "ALLOW" : "DENY";
316        String[] objs = {resourceName, actionName, result};
317        if (PolicyProperties.ALLOW.equals(logActions) && actionAllowed) {
318            logAccessMessage(Level.INFO,
319                             ResBundleUtils.getString(
320                             "policy_eval_allow", objs),token);
321        } else if (PolicyProperties.DENY.equals(logActions) && !actionAllowed) {
322            logAccessMessage(Level.INFO,
323                             ResBundleUtils.getString(
324                             "policy_eval_deny", objs),token);
325        } else if (PolicyProperties.BOTH.equals(logActions)
326                || PolicyProperties.DECISION.equals(logActions)) {
327            logAccessMessage(Level.INFO,
328                             ResBundleUtils.getString(
329                             "policy_eval_result", objs),token);
330        } //else nothing to log
331
332        if (debug.messageEnabled()) {
333            debug.message("PolicyEvaluator.isAllowed():"
334                    + "token=" + token.getPrincipal().getName() 
335                    + ":resourceName=" + resourceName 
336                    + ":actionName=" + actionName 
337                    + ":returning: " + actionAllowed);
338        }
339        return actionAllowed;
340    }
341
342    /**
343     * Evaluates privileges of the user to perform the specified actions
344     * on the specified resource. 
345     *
346     * @param token single sign on token of the user evaluating policies.
347     * @param resourceName name of the resource the user is trying to access.
348     * @param actionNames Set of action names the user is trying to perform on
349     * the resource.
350     *
351     * @return policy decision
352     * @throws PolicyException if result could not be computed for any
353     *         reason other than single sign on token problem.
354     * @throws SSOException if single sign on token is not valid
355     */
356    public PolicyDecision getPolicyDecision(SSOToken token,
357                                            String resourceName,
358                                            Set actionNames)
359        throws PolicyException, SSOException {
360        return getPolicyDecision(token, resourceName, actionNames, null);
361    }
362
363    /**
364     * Evaluates privileges of the user to perform the specified actions
365     * on the specified resource. The evaluation also depends on user's
366     * run time environment parameters.
367     *
368     * @param token single sign on token of the user evaluating policies.
369     * @param resourceName name of the resource the user is trying to access
370     * @param actionNames Set of action names the user is trying to perform on
371     *        the resource.
372     * @param envParameters run-time environment parameters
373     * @return policy decision
374     * @throws PolicyException if result could not be computed for any
375     *         reason other than single sign on token problem.
376     * @throws SSOException if single sign on token is invalid or expired.
377     *
378     * @supported.api
379     */
380    public PolicyDecision getPolicyDecision(SSOToken token,
381                                            String resourceName,
382                                            Set actionNames,
383                                            Map envParameters)
384                throws PolicyException, SSOException {
385
386        //validate the token 
387        ssoTokenManager.validateToken(token);
388
389        if (debug.messageEnabled()) {
390            debug.message("PolicyEvaluator:getPolicyDecision():"
391                    + "token=" + token.getPrincipal().getName() 
392                    + ":resourceName=" + resourceName 
393                    + ":actionName=" + actionNames + ":entering");
394        }
395
396        //We need to normalize the resourcename before sending off the policy request to ensure the policy is evaluated
397        //for the correct resource.
398        ResourceName resourceComparator = policyProperties.getResourceComparator(serviceName);
399        resourceName = resourceComparator.canonicalize(resourceName);
400
401        PolicyDecision pd = null;
402        try {
403            pd = resourceResultCache.getPolicyDecision(
404                        appSSOToken, serviceName, token, resourceName, 
405                        actionNames, envParameters, RETRY_COUNT);
406        } catch (InvalidAppSSOTokenException e) {
407            if (debug.warningEnabled()) {
408                debug.warning("PolicyEvaluator.getPolicyDecision():"
409                        + "InvalidAppSSOTokenException occured:"
410                        + "getting new appssotoken");
411            }
412            appSSOToken = getNewAppSSOToken();
413            if (policyProperties.notificationEnabled()) {
414                if (debug.warningEnabled()) {
415                    debug.warning("PolicyEvaluator.getPolicyDecision():"
416                            + "InvalidAppSSOTokenException occured:"
417                            + "reRegistering remote policy listener");
418                }
419                reRegisterRemotePolicyListener(appSSOToken);
420            }
421            pd = resourceResultCache.getPolicyDecision(
422                    appSSOToken, serviceName, token, resourceName, 
423                    actionNames, envParameters, RETRY_COUNT);
424
425        }
426
427        if (debug.messageEnabled()) {
428            debug.message("PolicyEvaluator:getPolicyDecision():"
429                    + "token=" + token.getPrincipal().getName() 
430                    + ":resourceName=" + resourceName 
431                    + ":actionNames=" + actionNames 
432                    + ":returning policyDecision:" + pd.toXML());
433        }
434
435        Object[] objs = {resourceName, actionNames, pd.toXML()};
436        if (PolicyProperties.DECISION.equals(logActions)) {
437                logAccessMessage(Level.INFO,
438                                 ResBundleUtils.getString(
439                                 "policy_eval_decision", objs),token);
440        } //else nothing to log
441
442        return pd;
443    }
444
445    /**
446     * Returns the application single sign on token, this token will be
447     * passed while initializing the <code>PolicyEvaluator</code> or 
448     * if the application session token currently being used by 
449     * this <code>PolicyEvaluator</code>  has expired
450     *
451     * @return a valid application single sign on token.
452     */
453    private SSOToken getNewAppSSOToken() throws PolicyException {
454        SSOToken token = null;
455        if (debug.messageEnabled()) {
456            debug.message("PolicyEvaluator.getNewAppSSOToken():"
457                        + "entering");
458        }
459        if (appSSOTokenProvider != null) {
460            token = appSSOTokenProvider.getAppSSOToken();
461            try {
462                ssoTokenManager.refreshSession(token);
463                if (!ssoTokenManager.isValidToken(token)) {
464                    if (debug.messageEnabled()) {
465                        debug.message("PolicyEvaluator.getNewAppSSOToken():"
466                                    + "AdminTokenAction returned "
467                                    + " expired token, trying again");
468                    }
469                    token = appSSOTokenProvider.getAppSSOToken();
470                }
471            } catch (SSOException e) {
472                if (debug.warningEnabled()) {
473                    debug.warning("PolicyEvaluator.getNewAppSSOToken():"
474                            + "could not refresh session:", e);
475                }
476                token = appSSOTokenProvider.getAppSSOToken();
477            }
478        } else {
479            token = (SSOToken) AccessController.doPrivileged(
480                AdminTokenAction.getInstance());
481            try {
482                ssoTokenManager.refreshSession(token);
483                if (!ssoTokenManager.isValidToken(token)) {
484                    if (debug.messageEnabled()) {
485                        debug.message("PolicyEvaluator.getNewAppSSOToken():"
486                                    + "AdminTokenAction returned "
487                                    + " expired token, trying again");
488                    }
489                    token = (SSOToken) AccessController.doPrivileged(
490                            AdminTokenAction.getInstance());
491                }
492            } catch (SSOException e) {
493                if (debug.warningEnabled()) {
494                    debug.warning("PolicyEvaluator.getNewAppSSOToken():"
495                            + "could not refresh session:", e);
496                }
497                token = (SSOToken) AccessController.doPrivileged(
498                        AdminTokenAction.getInstance());
499            }
500        }
501        if (token == null) {
502            debug.error("PolicyEvaluator.getNewAppSSOToken():, "
503                        + "cannot obtain application SSO token");
504            throw new PolicyException(ResBundleUtils.rbName,
505                "can_not_create_app_sso_token", null, null);
506        }
507        if (debug.messageEnabled()) {
508            debug.message("PolicyEvaluator.getNewAppSSOToken():"
509                        + "returning token");
510        }
511        return token;
512    }
513
514    /**
515     * Logs an access message from policy client api 
516     * @param level logging level
517     * @param message message string
518     * @param token single sign on token of user
519     */
520    private void logAccessMessage(Level level, String message,
521                                        SSOToken token) {
522
523        try { 
524            if (accessLogger == null) {
525                accessLogger = (com.sun.identity.log.Logger)
526                                Logger.getLogger("amRemotePolicy.access");
527                if (accessLogger == null) {
528                    if (debug.warningEnabled()) {       
529                        debug.warning("PolicyEvaluator.logAccessMessage:"
530                            + "Failed to create Logger");
531                    }
532                    return;
533                }
534            }
535            LogRecord lr = new LogRecord(level, message, token);
536            accessLogger.log(lr, appSSOToken);
537        } catch (Throwable ex) {
538            if (debug.warningEnabled()) {       
539                debug.warning("PolicyEvaluator.logAccessMessage:Error"
540                        + " writing access logs");
541            }
542        }
543
544    }
545
546    /**
547     * Returns application single sign on token provider 
548     *
549     * @return <code>AppSSOTokenProvider</code> Object.
550     */
551    AppSSOTokenProvider getAppSSOTokenProvider() {
552        return appSSOTokenProvider;
553    }
554
555    /**
556     * Gets names of policy advices that could be handled by OpenSSO
557     * if PEP redirects user agent to OpenSSO. If the server reports
558     * an error indicating the app sso token provided was invalid,
559     * new app sso token is obtained from app 
560     * sso token  provider and another attempt is made to get policy advices
561     * 
562     * @param refetchFromServer indicates whether to get the values fresh 
563     *      from OpenSSO or return the values from local cache
564     * @return names of policy advices that could be handled by OpenSSO
565     *         Enterprise if PEP redirects user agent to OpenSSO.
566     * @throws InvalidAppSSOTokenException if the server reported that the
567     *         app sso token provided was invalid 
568     * @throws PolicyEvaluationException if the server reported any other error
569     * @throws PolicyException if there are problems in policy module
570     *         while getting the result
571     * @throws SSOException if there are problems with sso token
572     *         while getting the result
573     */
574    public Set getAdvicesHandleableByAM(boolean refetchFromServer) 
575            throws InvalidAppSSOTokenException, PolicyEvaluationException,
576            PolicyException, SSOException {
577        Set advicesHandleableByAM = null;
578        if (debug.messageEnabled()) {   
579            debug.message("PolicyEvaluator.getAdvicesHandleableByAM(): Entering"
580                    + "refetchFromServer=" + refetchFromServer);
581        }
582        try {
583            advicesHandleableByAM 
584                    = resourceResultCache.getAdvicesHandleableByAM(
585                    appSSOToken, refetchFromServer);
586        } catch (InvalidAppSSOTokenException e) {
587            //retry with new app sso token
588            if (debug.warningEnabled()) {
589                debug.warning("PolicyEvaluator.getAdvicesHandleableByAM():"
590                        + "got InvalidAppSSOTokenException, "
591                        + " retrying with new app token");
592            }
593            advicesHandleableByAM 
594                    = resourceResultCache.getAdvicesHandleableByAM(
595                    getNewAppSSOToken(), refetchFromServer);
596        } catch (PolicyException pe) {
597            Throwable nestedException = pe.getNestedException();
598            if ((nestedException != null) 
599                        && (nestedException instanceof SessionException)) {
600                //retry with new app sso token
601                if (debug.warningEnabled()) {
602                    debug.warning("PolicyEvaluator.getAdvicesHandleableByAM():"
603                            + "got SessionException, "
604                            + " retrying with new app token");
605                }
606                advicesHandleableByAM 
607                        = resourceResultCache.getAdvicesHandleableByAM(
608                        getNewAppSSOToken(), refetchFromServer);
609
610            } else {
611                throw pe;
612            }
613        }
614        if (debug.messageEnabled()) {   
615            debug.message("PolicyEvaluator.getAdvicesHandleableByAM():"
616                    + " Returning advicesHandleableByAM=" 
617                    + advicesHandleableByAM);
618        }
619        return advicesHandleableByAM;
620    }
621
622    /**
623     *  Returns XML string representation of advice map contained in the
624     *  actionDecision. This is a convenience method for use by PEP.
625     *
626     *  @param actionDecision actionDecision that contains the 
627     *        advices
628     *  @return XML string representation of advice map contained in the
629     *      actionDecision subject to the following rule. If the 
630     *      actionDecision is null, the return value would be null. 
631     *      Otherwise, if the actionDecision does not contain any advice, 
632     *      the return value would be null. Otherwise, actionDecision contains
633     *      advices. In this case, if the advices contains at least one advice
634     *      name that could be handled by AM, the complete advices element is 
635     *      serialized to XML and the XML string is returned. Otherwise, null
636     *      is returned.
637     *  @throws PolicyException for any abnormal condition encountered in
638     *      policy module
639     *  @throws SSOException for any abnormal condition encountered in
640     *      session module
641     */
642    public String getCompositeAdvice(ActionDecision actionDecision )
643            throws PolicyException, SSOException {
644
645        if(debug.messageEnabled()) {
646            debug.message("PolicyEvaluator.getCompositeAdvice():"
647                    + " entering, actionDecision = " + actionDecision.toXML());
648        }
649
650        String compositeAdvice = null;
651        boolean matchFound = false;
652        Map advices = null;
653        if (actionDecision != null) {
654            advices = actionDecision.getAdvices();
655        }
656
657        //false : use cached value
658        Set handleableAdvices = getAdvicesHandleableByAM(false); 
659
660        if(debug.messageEnabled()) {
661            debug.message("PolicyEvaluator.getCompositeAdvice():"
662                    + " handleableAdvices = " + handleableAdvices);
663        }
664
665        if  ((advices != null) && !advices.isEmpty() 
666                && (handleableAdvices !=null) 
667                && (!handleableAdvices.isEmpty()) ) {
668            Set adviceKeys = advices.keySet();
669
670            if(debug.messageEnabled()) {
671                debug.message("PolicyEvaluator.getCompositeAdvice():"
672                        + " adviceKeys = " + adviceKeys);
673            }
674
675            Iterator keyIter = adviceKeys.iterator();
676            while (keyIter.hasNext()) {
677                Object adviceKey = keyIter.next();
678                if (handleableAdvices.contains(adviceKey)) {
679                    matchFound = true;
680                    if(debug.messageEnabled()) {
681                        debug.message("PolicyEvaluator.getCompositeAdvice():"
682                                + " matchFound = " + matchFound);
683                        debug.message("PolicyEvaluator.getCompositeAdvice():"
684                                + " common key = " + adviceKey);
685                    }
686                    break;
687                }
688            }
689        }
690
691        if (matchFound) {
692            compositeAdvice = PolicyUtils.advicesToXMLString(advices);
693        }
694
695        if(debug.messageEnabled()) {
696            debug.message("PolicyEvaluator.getCompositeAdvice():"
697                    + " returning, compositeAdvcie = " + compositeAdvice);
698        }
699
700        return compositeAdvice;
701    }
702
703    /**
704     * Registers this client again with policy service to get policy 
705     * change notifications 
706     *
707     * @param appToken application sso token to use while registering with
708     * policy service to get notifications
709     *
710     */
711    void reRegisterRemotePolicyListener(SSOToken appToken)
712            throws PolicyException {
713        if (debug.messageEnabled()) {
714            debug.message("PolicyEvaluator.reRegisterRemotePolicyListener():"
715                    + "entering");
716        } 
717        resourceResultCache.addRemotePolicyListener(appSSOToken,
718                serviceName, policyProperties.getNotificationURL(),
719                true); //reRegister
720
721        //clear policy decision cache
722        resourceResultCache.clearCachedDecisionsForService(serviceName);
723
724        if (debug.messageEnabled()) {
725            debug.message("PolicyEvaluator.reRegisterRemotePolicyListener():"
726                    + "returning");
727        } 
728    }
729
730}




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.