Remove Tabs, per Jococo
[aaf/authz.git] / cadi / aaf / src / main / java / org / onap / aaf / cadi / aaf / v2_0 / AbsAAFLur.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21
22 package org.onap.aaf.cadi.aaf.v2_0;
23
24 import java.security.Principal;
25 import java.util.ArrayList;
26 import java.util.Date;
27 import java.util.List;
28
29 import org.onap.aaf.cadi.AbsUserCache;
30 import org.onap.aaf.cadi.Access.Level;
31 import org.onap.aaf.cadi.CachingLur;
32 import org.onap.aaf.cadi.Lur;
33 import org.onap.aaf.cadi.Permission;
34 import org.onap.aaf.cadi.User;
35 import org.onap.aaf.cadi.aaf.AAFPermission;
36 import org.onap.aaf.cadi.config.Config;
37 import org.onap.aaf.misc.env.APIException;
38 import org.onap.aaf.misc.env.util.Split;
39
40 public abstract class AbsAAFLur<PERM extends Permission> extends AbsUserCache<PERM> implements CachingLur<PERM> {
41     protected static final byte[] BLANK_PASSWORD = new byte[0];
42     private String[] debug = null;
43     public AAFCon<?> aaf;
44     public Lur preemptiveLur=null; // Initial Use is for OAuth2, preemptive Lur
45     private String[] supports;
46     protected boolean details;
47
48     public AbsAAFLur(AAFCon<?> con) throws APIException {
49         super(con.access, con.cleanInterval, con.highCount, con.usageRefreshTriggerCount);
50         aaf = con;
51         setLur(this);
52         supports = con.access.getProperty(Config.AAF_DOMAIN_SUPPORT, Config.AAF_DOMAIN_SUPPORT_DEF).split("\\s*:\\s*");
53     }
54
55     public AbsAAFLur(AAFCon<?> con, AbsUserCache<PERM> auc) throws APIException {
56         super(auc);
57         aaf = con;
58         setLur(this);
59         supports = con.access.getProperty(Config.AAF_DOMAIN_SUPPORT, Config.AAF_DOMAIN_SUPPORT_DEF).split("\\s*:\\s*");
60     }
61
62     @Override
63     public void setDebug(String ids) {
64         this.debug = ids==null?null:Split.split(',', ids);
65     }
66
67     public void details(boolean on) {
68         details = on;
69     }
70     
71
72     public void setPreemptiveLur(Lur preemptive) {
73         this.preemptiveLur = preemptive;
74     }
75     
76     protected abstract User<PERM> loadUser(Principal bait);
77
78     @Override
79     public final boolean handles(Principal principal) {
80         if (preemptiveLur!=null) {
81             if (preemptiveLur.handles(principal)) {
82                 return true;
83             }
84         }
85         String userName=principal.getName();
86         if (userName!=null) {
87             for (String s : supports) {
88                 if (userName.endsWith(s))
89                     return true;
90             }
91         }
92         return false;
93     }
94
95     
96     protected abstract boolean isCorrectPermType(Permission pond);
97     
98     // This is where you build AAF CLient Code.  Answer the question "Is principal "bait" in the "pond"
99     public boolean fish(Principal bait, Permission ... pond) {
100         if (preemptiveLur!=null && preemptiveLur.handles(bait)) {
101             return preemptiveLur.fish(bait, pond);
102         } else {
103             if (pond==null) {
104                 return false;
105             }
106             if (isDebug(bait)) {
107                 boolean rv = false;
108                 StringBuilder sb = new StringBuilder("Log for ");
109                 sb.append(bait);
110                 if (handles(bait)) {
111                     User<PERM> user = getUser(bait);
112                     if (user==null) {
113                         sb.append("\n\tUser is not in Cache");
114                     } else {
115                         if (user.noPerms()) {
116                             sb.append("\n\tUser has no Perms");
117                         }
118                         if (user.permExpired()) {
119                             sb.append("\n\tUser's perm expired [");
120                             sb.append(new Date(user.permExpires()));
121                             sb.append(']');
122                         } else {
123                             sb.append("\n\tUser's perm expires [");
124                             sb.append(new Date(user.permExpires()));
125                             sb.append(']');
126                         }
127                     }
128                     if (user==null || user.permsUnloaded() || user.permExpired()) {
129                         user = loadUser(bait);
130                         sb.append("\n\tloadUser called");
131                     }
132                     for (Permission p : pond) {
133                         if (user==null) {
134                             sb.append("\n\tUser was not Loaded");
135                             break;
136                         } else if (user.contains(p)) {
137                             sb.append("\n\tUser contains ");
138                             sb.append(p.getKey());
139                             rv = true;
140                         } else {
141                             sb.append("\n\tUser does not contain ");
142                             sb.append(p.getKey());
143                             List<Permission> perms = new ArrayList<>();
144                             user.copyPermsTo(perms);
145                             for (Permission perm : perms) {
146                                 sb.append("\n\t\t");
147                                 sb.append(perm.getKey());
148                             }
149                         }
150                     }
151                 } else {
152                     sb.append("AAF Lur does not support [");
153                     sb.append(bait);
154                     sb.append("]");
155                 }
156                 aaf.access.log(Level.INFO, sb);
157                 return rv;
158             } else {
159                 boolean rv = false;
160                 if (handles(bait)) {
161                     User<PERM> user = getUser(bait);
162                     if (user==null || user.permsUnloaded() || user.permExpired()) {
163                         user = loadUser(bait);
164                     }
165                     if (user==null) {
166                         return false;
167                     } else {
168                         for (Permission p : pond) {
169                             if (rv=user.contains(p)) {
170                                 break;
171                             }
172                         }
173                     }
174                 }
175                 return rv;
176             }
177         }
178     }
179
180     public void fishAll(Principal bait, List<Permission> perms) {
181         if (preemptiveLur!=null && preemptiveLur.handles(bait)) {
182             preemptiveLur.fishAll(bait, perms);
183         } else {
184             if (isDebug(bait)) {
185                 StringBuilder sb = new StringBuilder("Log for ");
186                 sb.append(bait);
187                 if (handles(bait)) {
188                     User<PERM> user = getUser(bait);
189                     if (user==null) {
190                         sb.append("\n\tUser is not in Cache");
191                     } else {
192                         if (user.noPerms()) {
193                             sb.append("\n\tUser has no Perms");
194                         }
195                         if (user.permExpired()) {
196                             sb.append("\n\tUser's perm expired [");
197                             sb.append(new Date(user.permExpires()));
198                             sb.append(']');
199                         } else {
200                             sb.append("\n\tUser's perm expires [");
201                             sb.append(new Date(user.permExpires()));
202                             sb.append(']');
203                         }
204                     }
205                     if (user==null || user.permsUnloaded() || user.permExpired()) {
206                         user = loadUser(bait);
207                         sb.append("\n\tloadUser called");
208                     }
209                     if (user==null) {
210                         sb.append("\n\tUser was not Loaded");
211                     } else {
212                         sb.append("\n\tCopying Perms ");
213                         user.copyPermsTo(perms);
214                         for (Permission p : perms) {
215                             sb.append("\n\t\t");
216                             sb.append(p.getKey());
217                         }
218                     }
219                 } else {
220                     sb.append("AAF Lur does not support [");
221                     sb.append(bait);
222                     sb.append("]");
223                 }
224                 aaf.access.log(Level.INFO, sb);
225             } else {
226                 if (handles(bait)) {
227                     User<PERM> user = getUser(bait);
228                     if (user==null || user.permsUnloaded() || user.permExpired()) {
229                         user = loadUser(bait);
230                     }
231                     if (user!=null) {
232                         user.copyPermsTo(perms);
233                     }
234                 }
235             }
236         }
237     }
238     
239     @Override
240     public void remove(String user) {
241         super.remove(user);
242     }
243
244     private boolean isDebug(Principal p) {
245         if (debug!=null) {
246             if (debug.length==1 && "all".equals(debug[0])) {
247                 return true;
248             }
249             String name = p.getName();
250             for (String s : debug) {
251                 if (s.equals(name)) {
252                     return true;
253                 }
254             }
255         }
256         return false;
257     }
258     /**
259      * This special case minimizes loops, avoids multiple Set hits, and calls all the appropriate Actions found.
260      * 
261      * @param bait
262      * @param obj
263      * @param type
264      * @param instance
265      * @param actions
266      */
267     public<A> void fishOneOf(Principal princ, A obj, String type, String instance, List<Action<A>> actions) {
268         User<PERM> user = getUser(princ);
269         if (user==null || user.permsUnloaded() || user.permExpired()) {
270             user = loadUser(princ);
271         }
272         if (user!=null) {
273             ReuseAAFPermission perm = new ReuseAAFPermission(type,instance);
274             for (Action<A> action : actions) {
275                 perm.setAction(action.getName());
276                 if (user.contains(perm)) {
277                     if (action.exec(obj))return;
278                 }
279             }
280         }
281     }
282     
283     public static interface Action<A> {
284         public String getName();
285         /**
286          *  Return false to continue, True to end now
287          * @return
288          */
289         public boolean exec(A a);
290     }
291     
292     private class ReuseAAFPermission extends AAFPermission {
293         public ReuseAAFPermission(String type, String instance) {
294             super(type,instance,null,null);
295         }
296
297         public void setAction(String s) {
298             action = s;
299         }
300         
301         /**
302          * This function understands that AAF Keys are hierarchical, :A:B:C, 
303          *  Cassandra follows a similar method, so we'll short circuit and do it more efficiently when there isn't a first hit
304          * @return
305          */
306     }
307 }