Coverage Report - org.openpermis.audit.AuditPolicyDecisionPoint
 
Classes in this File Line Coverage Branch Coverage Complexity
AuditPolicyDecisionPoint
56%
14/25
37%
3/8
3.5
 
 1  
 /*
 2  
  * Copyright (c) 2009, Ergon Informatik AG (http://www.ergon.ch)
 3  
  * All rights reserved.
 4  
  * 
 5  
  * Licensed under the Open Permis License which accompanies this distribution, 
 6  
  * and is available at http://www.openpermis.org/BSDlicenceKent.txt
 7  
  */
 8  
 package org.openpermis.audit;
 9  
 
 10  
 import java.net.URI;
 11  
 import java.util.ArrayList;
 12  
 import java.util.Collections;
 13  
 import java.util.List;
 14  
 
 15  
 import org.openpermis.PolicyDecisionException;
 16  
 import org.openpermis.PolicyDecisionPoint;
 17  
 import org.openpermis.Subject;
 18  
 import org.openpermis.policy.AccessDecision;
 19  
 import org.openpermis.policy.TimeStamp;
 20  
 
 21  
 
 22  
 /**
 23  
  * Policy decision point delegate that supports {@link VetoableAccessDecisionListener}s.
 24  
  * <p>The audit policy decision point wraps an existing {@link PolicyDecisionPoint} and adds
 25  
  * auditing functionality.</p>
 26  
  * @since 0.3.0
 27  
  */
 28  
 public class AuditPolicyDecisionPoint
 29  
         implements PolicyDecisionPoint
 30  
 {
 31  
 
 32  
         //---- State
 33  
         
 34  
         /**
 35  
          * The actual PDP to delegate access decisions to.
 36  
          * @since 0.3.0
 37  
          */
 38  
         private final PolicyDecisionPoint delegate;
 39  
         
 40  
         /**
 41  
          * List of access decision listeners.
 42  
          * @since 0.3.0
 43  
          */
 44  
         private final List<VetoableAccessDecisionListener> listeners;
 45  
         
 46  
         //---- Constructors
 47  
         
 48  
         /**
 49  
          * Creates a new policy decision point with audit support.
 50  
          * @param delegate the actual PDP to delegate access decision to, must not be {@code null}.
 51  
          * @param listeners a list of listeners to notify when a decision is calculated.
 52  
          * @since 0.3.0
 53  
          */
 54  
         public AuditPolicyDecisionPoint (
 55  
                 PolicyDecisionPoint delegate, List<VetoableAccessDecisionListener> listeners
 56  1
         ) {
 57  1
                 this.delegate = delegate;
 58  1
                 this.listeners = Collections.unmodifiableList(
 59  
                         new ArrayList<VetoableAccessDecisionListener>(listeners)
 60  
                 );
 61  1
         }
 62  
         
 63  
         //---- Methods
 64  
         
 65  
         /**
 66  
          * Notifies all listeners of an access decision failure.
 67  
          * @param request the request.
 68  
          * @param exception the failure.
 69  
          * @since 0.3.0
 70  
          */
 71  
         private void notifyAccessDecisionFailure (
 72  
                 AccessDecisionRequest request, PolicyDecisionException exception
 73  
         ) {
 74  0
                 if (this.listeners == null) {
 75  0
                         return;
 76  
                 }
 77  0
                 for (VetoableAccessDecisionListener listener : this.listeners) {
 78  0
                         listener.accessDecisionFailure(request, exception);
 79  
                 }
 80  0
         }
 81  
         
 82  
         /**
 83  
          * Notifies all listeners of a vetoable access decision.
 84  
          * @param request the request.
 85  
          * @param decision the decision.
 86  
          * @throws AccessDecisionVetoException in case of a veto.
 87  
          * @since 0.3.0
 88  
          */
 89  
         private void notifyVetoableAccessDecision (
 90  
                 AccessDecisionRequest request, AccessDecision decision
 91  
         )
 92  
                 throws AccessDecisionVetoException
 93  
         {
 94  1
                 if (this.listeners == null) {
 95  0
                         return;
 96  
                 }
 97  1
                 for (VetoableAccessDecisionListener listener : this.listeners) {
 98  1
                         listener.vetoableAccessDecision(request, decision);
 99  
                 }
 100  1
         }
 101  
         
 102  
         //---- PolicyDecisionPoint
 103  
 
 104  
         /**
 105  
          * @since 0.3.0
 106  
          */
 107  
         public AccessDecision getAccessDecision (
 108  
                 Subject subject, URI resource, String actionName, List<?> arguments, TimeStamp timeStamp
 109  
         )
 110  
                 throws PolicyDecisionException
 111  
         {
 112  1
                 final AccessDecisionRequest request = new AccessDecisionRequest(
 113  
                         subject, resource, actionName, arguments, timeStamp
 114  
                 );
 115  
                 final AccessDecision decision;
 116  
                 try {
 117  1
                         decision = this.delegate.getAccessDecision(
 118  
                                 subject, resource, actionName, arguments, timeStamp
 119  
                         );
 120  0
                 } catch (PolicyDecisionException e) {
 121  
                         // Notify and rethrow, only catching to notify before rethrowing.
 122  0
                         notifyAccessDecisionFailure(request, e);
 123  0
                         throw e;
 124  1
                 }
 125  
                 try {
 126  1
                         notifyVetoableAccessDecision(request, decision);
 127  0
                 } catch (AccessDecisionVetoException e) {
 128  
                         // Throw veto as a wrapped policy decision exception.
 129  0
                         throw new PolicyDecisionException(e);
 130  1
                 }
 131  1
                 return decision;
 132  
         }
 133  
 
 134  
 }