1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.opensaml.xacml.ctx.provider;
19
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Comparator;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.TreeSet;
28 import java.util.concurrent.locks.Lock;
29 import java.util.concurrent.locks.ReentrantReadWriteLock;
30
31 import org.opensaml.xacml.ctx.DecisionType.DECISION;
32 import org.opensaml.xacml.policy.EffectType;
33 import org.opensaml.xacml.policy.ObligationType;
34 import org.opensaml.xacml.policy.ObligationsType;
35
36
37 public class ObligationService {
38
39
40 private ReentrantReadWriteLock rwLock;
41
42
43 private Set<BaseObligationHandler> obligationHandlers;
44
45
46 public ObligationService() {
47 rwLock = new ReentrantReadWriteLock(true);
48 obligationHandlers = new TreeSet<BaseObligationHandler>(new ObligationHandlerComparator());
49 }
50
51
52
53
54
55
56 public Set<BaseObligationHandler> getObligationHandlers() {
57 return Collections.unmodifiableSet(obligationHandlers);
58 }
59
60
61
62
63
64
65
66
67 public void addObligationhandler(BaseObligationHandler handler) {
68 if (handler == null) {
69 return;
70 }
71
72 Lock writeLock = rwLock.writeLock();
73 writeLock.lock();
74 try {
75 obligationHandlers.add(handler);
76 } finally {
77 writeLock.unlock();
78 }
79 }
80
81
82
83
84
85
86
87
88 public void addObligationhandler(Collection<BaseObligationHandler> handlers) {
89 if (handlers == null || handlers.isEmpty()) {
90 return;
91 }
92
93 Lock writeLock = rwLock.writeLock();
94 writeLock.lock();
95 try {
96 obligationHandlers.addAll(handlers);
97 } finally {
98 writeLock.unlock();
99 }
100 }
101
102
103
104
105
106
107
108
109 public void removeObligationHandler(BaseObligationHandler handler) {
110 if (handler == null) {
111 return;
112 }
113
114 Lock writeLock = rwLock.writeLock();
115 writeLock.lock();
116 try {
117 obligationHandlers.remove(handler);
118 } finally {
119 writeLock.unlock();
120 }
121 }
122
123
124
125
126
127
128
129
130
131
132 public void processObligations(ObligationProcessingContext context) throws ObligationProcessingException {
133 Lock readLock = rwLock.readLock();
134 readLock.lock();
135 try {
136 Iterator<BaseObligationHandler> handlerItr = obligationHandlers.iterator();
137 Map<String, ObligationType> effectiveObligations = preprocessObligations(context);
138
139 BaseObligationHandler handler;
140 while (handlerItr.hasNext()) {
141 handler = handlerItr.next();
142 if (effectiveObligations.containsKey(handler.getObligationId())) {
143 handler.evaluateObligation(context, effectiveObligations.get(handler.getObligationId()));
144 }
145 }
146 } finally {
147 readLock.unlock();
148 }
149 }
150
151
152
153
154
155
156
157
158
159
160 protected Map<String, ObligationType> preprocessObligations(ObligationProcessingContext context) {
161 HashMap<String, ObligationType> effectiveObligations = new HashMap<String, ObligationType>();
162
163 ObligationsType obligations = context.getAuthorizationDecisionResult().getObligations();
164 if (obligations == null || obligations.getObligations() == null) {
165 return effectiveObligations;
166 }
167
168 EffectType activeEffect;
169 if (context.getAuthorizationDecisionResult().getDecision().getDecision() == DECISION.Permit) {
170 activeEffect = EffectType.Permit;
171 } else {
172 activeEffect = EffectType.Deny;
173 }
174
175 for (ObligationType obligation : obligations.getObligations()) {
176 if (obligation != null && obligation.getFulfillOn() == activeEffect) {
177 effectiveObligations.put(obligation.getObligationId(), obligation);
178 }
179 }
180
181 return effectiveObligations;
182 }
183
184
185 private class ObligationHandlerComparator implements Comparator<BaseObligationHandler> {
186
187
188 public int compare(BaseObligationHandler o1, BaseObligationHandler o2) {
189 if (o1.getHandlerPrecedence() == o2.getHandlerPrecedence()) {
190
191 return o1.getObligationId().compareTo(o2.getObligationId());
192 }
193
194 if (o1.getHandlerPrecedence() < o2.getHandlerPrecedence()) {
195 return -1;
196 }
197
198 return 1;
199 }
200 }
201 }