Mass removal of all Tabs (Style Warnings)
[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
47     public AbsAAFLur(AAFCon<?> con) throws APIException {
48         super(con.access, con.cleanInterval, con.highCount, con.usageRefreshTriggerCount);
49         aaf = con;
50         setLur(this);
51         supports = con.access.getProperty(Config.AAF_DOMAIN_SUPPORT, Config.AAF_DOMAIN_SUPPORT_DEF).split("\\s*:\\s*");
52     }
53
54     public AbsAAFLur(AAFCon<?> con, AbsUserCache<PERM> auc) throws APIException {
55         super(auc);
56         aaf = con;
57         setLur(this);
58         supports = con.access.getProperty(Config.AAF_DOMAIN_SUPPORT, Config.AAF_DOMAIN_SUPPORT_DEF).split("\\s*:\\s*");
59     }
60
61     @Override
62     public void setDebug(String ids) {
63         this.debug = ids==null?null:Split.split(',', ids);
64     }
65     
66     public void setPreemptiveLur(Lur preemptive) {
67         this.preemptiveLur = preemptive;
68     }
69     
70     protected abstract User<PERM> loadUser(Principal bait);
71
72     @Override
73     public final boolean handles(Principal principal) {
74         if(preemptiveLur!=null) {
75             if(preemptiveLur.handles(principal)) {
76                 return true;
77             }
78         }
79         String userName=principal.getName();
80         if(userName!=null) {
81             for(String s : supports) {
82                 if(userName.endsWith(s))
83                     return true;
84             }
85         }
86         return false;
87     }
88
89     
90     protected abstract boolean isCorrectPermType(Permission pond);
91     
92     // This is where you build AAF CLient Code.  Answer the question "Is principal "bait" in the "pond"
93     public boolean fish(Principal bait, Permission ... pond) {
94         if(preemptiveLur!=null && preemptiveLur.handles(bait)) {
95             return preemptiveLur.fish(bait, pond);
96         } else {
97             if(pond==null) {
98                 return false;
99             }
100             if(isDebug(bait)) {
101                 boolean rv = false;
102                 StringBuilder sb = new StringBuilder("Log for ");
103                 sb.append(bait);
104                 if(handles(bait)) {
105                     User<PERM> user = getUser(bait);
106                     if(user==null) {
107                         sb.append("\n\tUser is not in Cache");
108                     } else {
109                         if(user.noPerms()) {
110                             sb.append("\n\tUser has no Perms");
111                         }
112                         if(user.permExpired()) {
113                             sb.append("\n\tUser's perm expired [");
114                             sb.append(new Date(user.permExpires()));
115                             sb.append(']');
116                         } else {
117                             sb.append("\n\tUser's perm expires [");
118                             sb.append(new Date(user.permExpires()));
119                             sb.append(']');
120                         }
121                     }
122                     if(user==null || user.permsUnloaded() || user.permExpired()) {
123                         user = loadUser(bait);
124                         sb.append("\n\tloadUser called");
125                     }
126                     for (Permission p : pond) {
127                         if(user==null) {
128                             sb.append("\n\tUser was not Loaded");
129                             break;
130                         } else if(user.contains(p)) {
131                             sb.append("\n\tUser contains ");
132                             sb.append(p.getKey());
133                             rv = true;
134                         } else {
135                             sb.append("\n\tUser does not contain ");
136                             sb.append(p.getKey());
137                             List<Permission> perms = new ArrayList<>();
138                             user.copyPermsTo(perms);
139                             for(Permission perm : perms) {
140                                 sb.append("\n\t\t");
141                                 sb.append(perm.getKey());
142                             }
143                         }
144                     }
145                 } else {
146                     sb.append("AAF Lur does not support [");
147                     sb.append(bait);
148                     sb.append("]");
149                 }
150                 aaf.access.log(Level.INFO, sb);
151                 return rv;
152             } else {
153                 boolean rv = false;
154                 if(handles(bait)) {
155                     User<PERM> user = getUser(bait);
156                     if(user==null || user.permsUnloaded() || user.permExpired()) {
157                         user = loadUser(bait);
158                     }
159                     if(user==null) {
160                         return false;
161                     } else {
162                         for(Permission p : pond) {
163                             if(rv=user.contains(p)) {
164                                 break;
165                             }
166                         }
167                     }
168                 }
169                 return rv;
170             }
171         }
172     }
173
174     public void fishAll(Principal bait, List<Permission> perms) {
175         if(preemptiveLur!=null && preemptiveLur.handles(bait)) {
176             preemptiveLur.fishAll(bait, perms);
177         } else {
178             if(isDebug(bait)) {
179                 StringBuilder sb = new StringBuilder("Log for ");
180                 sb.append(bait);
181                 if(handles(bait)) {
182                     User<PERM> user = getUser(bait);
183                     if(user==null) {
184                         sb.append("\n\tUser is not in Cache");
185                     } else {
186                         if(user.noPerms()) {
187                             sb.append("\n\tUser has no Perms");
188                         }
189                         if(user.permExpired()) {
190                             sb.append("\n\tUser's perm expired [");
191                             sb.append(new Date(user.permExpires()));
192                             sb.append(']');
193                         } else {
194                             sb.append("\n\tUser's perm expires [");
195                             sb.append(new Date(user.permExpires()));
196                             sb.append(']');
197                         }
198                     }
199                     if(user==null || user.permsUnloaded() || user.permExpired()) {
200                         user = loadUser(bait);
201                         sb.append("\n\tloadUser called");
202                     }
203                     if(user==null) {
204                         sb.append("\n\tUser was not Loaded");
205                     } else {
206                         sb.append("\n\tCopying Perms ");
207                         user.copyPermsTo(perms);
208                         for(Permission p : perms) {
209                             sb.append("\n\t\t");
210                             sb.append(p.getKey());
211                         }
212                     }
213                 } else {
214                     sb.append("AAF Lur does not support [");
215                     sb.append(bait);
216                     sb.append("]");
217                 }
218                 aaf.access.log(Level.INFO, sb);
219             } else {
220                 if(handles(bait)) {
221                     User<PERM> user = getUser(bait);
222                     if(user==null || user.permsUnloaded() || user.permExpired()) {
223                         user = loadUser(bait);
224                     }
225                     if(user!=null) {
226                         user.copyPermsTo(perms);
227                     }
228                 }
229             }
230         }
231     }
232     
233     @Override
234     public void remove(String user) {
235         super.remove(user);
236     }
237
238     private boolean isDebug(Principal p) {
239         if(debug!=null) {
240             if(debug.length==1 && "all".equals(debug[0])) {
241                 return true;
242             }
243             String name = p.getName();
244             for(String s : debug) {
245                 if(s.equals(name)) {
246                     return true;
247                 }
248             }
249         }
250         return false;
251     }
252     /**
253      * This special case minimizes loops, avoids multiple Set hits, and calls all the appropriate Actions found.
254      * 
255      * @param bait
256      * @param obj
257      * @param type
258      * @param instance
259      * @param actions
260      */
261     public<A> void fishOneOf(Principal princ, A obj, String type, String instance, List<Action<A>> actions) {
262         User<PERM> user = getUser(princ);
263         if(user==null || user.permsUnloaded() || user.permExpired()) {
264             user = loadUser(princ);
265         }
266         if(user!=null) {
267             ReuseAAFPermission perm = new ReuseAAFPermission(type,instance);
268             for(Action<A> action : actions) {
269                 perm.setAction(action.getName());
270                 if(user.contains(perm)) {
271                     if(action.exec(obj))return;
272                 }
273             }
274         }
275     }
276     
277     public static interface Action<A> {
278         public String getName();
279         /**
280          *  Return false to continue, True to end now
281          * @return
282          */
283         public boolean exec(A a);
284     }
285     
286     private class ReuseAAFPermission extends AAFPermission {
287         public ReuseAAFPermission(String type, String instance) {
288             super(type,instance,null,null);
289         }
290
291         public void setAction(String s) {
292             action = s;
293         }
294         
295         /**
296          * This function understands that AAF Keys are hierarchical, :A:B:C, 
297          *  Cassandra follows a similar method, so we'll short circuit and do it more efficiently when there isn't a first hit
298          * @return
299          */
300     }
301 }