Configuration and Auto-Certificates
[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 }