AT&T 2.0.19 Code drop, stage 4
[aaf/authz.git] / authz-service / src / main / java / org / onap / aaf / authz / service / validation / Validator.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aaf\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * ===========================================================================\r
7  * * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * * you may not use this file except in compliance with the License.\r
9  * * You may obtain a copy of the License at\r
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \r
13  *  * Unless required by applicable law or agreed to in writing, software\r
14  * * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * * See the License for the specific language governing permissions and\r
17  * * limitations under the License.\r
18  * * ============LICENSE_END====================================================\r
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 package org.onap.aaf.authz.service.validation;\r
24 \r
25 import java.util.regex.Pattern;\r
26 \r
27 import org.onap.aaf.authz.cadi.DirectAAFLur.PermPermission;\r
28 import org.onap.aaf.authz.env.AuthzTrans;\r
29 import org.onap.aaf.authz.layer.Result;\r
30 import org.onap.aaf.authz.org.Organization;\r
31 import org.onap.aaf.dao.aaf.cass.CredDAO;\r
32 import org.onap.aaf.dao.aaf.cass.DelegateDAO;\r
33 import org.onap.aaf.dao.aaf.cass.Namespace;\r
34 import org.onap.aaf.dao.aaf.cass.PermDAO;\r
35 import org.onap.aaf.dao.aaf.cass.RoleDAO;\r
36 import org.onap.aaf.dao.aaf.cass.UserRoleDAO;\r
37 \r
38 /**\r
39  * Validator\r
40  * Consistently apply content rules for content (incoming)\r
41  * \r
42  * Note: We restrict content for usability in URLs (because RESTful service), and avoid \r
43  * issues with Regular Expressions, and other enabling technologies. \r
44  *\r
45  */\r
46 public class Validator {\r
47         // % () ,-. 0-9 =A-Z _a-z\r
48         private static final String ESSENTIAL="\\x25\\x28\\x29\\x2C-\\x2E\\x30-\\x39\\x3D\\x40-\\x5A\\x5F\\x61-\\x7A";\r
49         private static final Pattern ESSENTIAL_CHARS=Pattern.compile("["+ESSENTIAL+"]+");\r
50         \r
51         // Must be 1 or more of Alphanumeric or the following  :._-\r
52         // '*' only allowed when it is the only character, or the only element in a key separator\r
53         //  :* :hello:* :hello:*:there  etc\r
54         public static final Pattern ACTION_CHARS=Pattern.compile(\r
55                         "["+ESSENTIAL+"]+" +    // All AlphaNumeric+\r
56                         "|\\*"                                          // Just Star\r
57                         );\r
58 \r
59         public static final Pattern INST_CHARS=Pattern.compile(\r
60                         "["+ESSENTIAL+"]+[\\*]*" +                              // All AlphaNumeric+ possibly ending with *\r
61                         "|\\*" +                                                                // Just Star\r
62                         "|(([:/]\\*)|([:/][!]{0,1}["+ESSENTIAL+"]+[\\*]*[:/]*))+"       // Key :asdf:*:sdf*:sdk\r
63                         );\r
64         \r
65         // Must be 1 or more of Alphanumeric or the following  ._-, and be in the form id@domain\r
66         public static final Pattern ID_CHARS=Pattern.compile("[\\w.-]+@[\\w.-]+");\r
67         // Must be 1 or more of Alphanumeric or the following  ._-\r
68         public static final Pattern NAME_CHARS=Pattern.compile("[\\w.-]+");\r
69         \r
70         private final Pattern actionChars;\r
71         private final Pattern instChars;\r
72         private StringBuilder msgs;\r
73 \r
74         /**\r
75          * Default Validator does not check for non-standard Action/Inst chars\r
76          * \r
77          * \r
78          * IMPORTANT: Use ONLY when the Validator is doing something simple... NullOrBlank\r
79          */\r
80         public Validator() {\r
81                 actionChars = ACTION_CHARS;\r
82                 instChars = INST_CHARS;\r
83         }\r
84         \r
85         /**\r
86          * When Trans is passed in, check for non-standard Action/Inst chars\r
87          * \r
88          * This is an opportunity to change characters, if required.\r
89          * \r
90          * Use for any Object method passed (i.e. role(RoleDAO.Data d) ), to ensure fewer bugs.\r
91          * \r
92          * @param trans\r
93          */\r
94         public Validator(AuthzTrans trans) {\r
95                 actionChars = ACTION_CHARS;\r
96                 instChars = INST_CHARS;\r
97         }\r
98 \r
99 \r
100         public Validator perm(Result<PermDAO.Data> rpd) {\r
101                 if(rpd.notOK()) {\r
102                         msg(rpd.details);\r
103                 } else {\r
104                         perm(rpd.value);\r
105                 }\r
106                 return this;\r
107         }\r
108 \r
109 \r
110         public Validator perm(PermDAO.Data pd) {\r
111                 if(pd==null) {\r
112                         msg("Perm Data is null.");\r
113                 } else {\r
114                         ns(pd.ns);\r
115                         permType(pd.type,pd.ns);\r
116                         permInstance(pd.instance);\r
117                         permAction(pd.action);\r
118                         if(pd.roles!=null) { \r
119                                 for(String role : pd.roles) {\r
120                                         role(role);\r
121                                 }\r
122                         }\r
123                 }\r
124                 return this;\r
125         }\r
126 \r
127         public Validator role(Result<RoleDAO.Data> rrd) {\r
128                 if(rrd.notOK()) {\r
129                         msg(rrd.details);\r
130                 } else {\r
131                         role(rrd.value);\r
132                 }\r
133                 return this;\r
134         }\r
135 \r
136         public Validator role(RoleDAO.Data pd) {\r
137                 if(pd==null) {\r
138                         msg("Role Data is null.");\r
139                 } else {\r
140                         ns(pd.ns);\r
141                         role(pd.name);\r
142                         if(pd.perms!=null) {\r
143                                 for(String perm : pd.perms) {\r
144                                         String[] ps = perm.split("\\|");\r
145                                         if(ps.length!=3) {\r
146                                                 msg("Perm [" + perm + "] in Role [" + pd.fullName() + "] is not correctly separated with '|'");\r
147                                         } else {\r
148                                                 permType(ps[0],null);\r
149                                                 permInstance(ps[1]);\r
150                                                 permAction(ps[2]);\r
151                                         }\r
152                                 }\r
153                         }\r
154                 }\r
155                 return this;\r
156         }\r
157 \r
158         public Validator delegate(Organization org, Result<DelegateDAO.Data> rdd) {\r
159                 if(rdd.notOK()) {\r
160                         msg(rdd.details);\r
161                 } else {\r
162                         delegate(org, rdd.value);\r
163                 }\r
164                 return this;\r
165         }\r
166 \r
167         public Validator delegate(Organization org, DelegateDAO.Data dd) {\r
168                 if(dd==null) {\r
169                         msg("Delegate Data is null.");\r
170                 } else {\r
171                         user(org,dd.user);\r
172                         user(org,dd.delegate);\r
173                 }\r
174                 return this;\r
175         }\r
176 \r
177 \r
178         public Validator cred(Organization org, Result<CredDAO.Data> rcd, boolean isNew) {\r
179                 if(rcd.notOK()) {\r
180                         msg(rcd.details);\r
181                 } else {\r
182                         cred(org,rcd.value,isNew);\r
183                 }\r
184                 return this;\r
185         }\r
186 \r
187         public Validator cred(Organization org, CredDAO.Data cd, boolean isNew) {\r
188                 if(cd==null) {\r
189                         msg("Cred Data is null.");\r
190                 } else {\r
191                         if(nob(cd.id,ID_CHARS)) {\r
192                                 msg("ID [" + cd.id + "] is invalid");\r
193                         }\r
194                         if(!org.isValidCred(cd.id)) {\r
195                                 msg("ID [" + cd.id + "] is invalid for a cred");\r
196                         }\r
197                         String str = cd.id;\r
198                         int idx = str.indexOf('@');\r
199                         if(idx>0) {\r
200                                 str = str.substring(0,idx);\r
201                         }\r
202                         \r
203                         if(cd.id.endsWith(org.getRealm())) {\r
204                                 if(isNew && (str=org.isValidID(str)).length()>0) {\r
205                                         msg(cd.id,str);\r
206                                 }\r
207                         }\r
208         \r
209                         if(cd.type==null) {\r
210                                 msg("Credential Type must be set");\r
211                         } else {\r
212                                 switch(cd.type) {\r
213                                         case CredDAO.BASIC_AUTH_SHA256:\r
214                                                 // ok\r
215                                                 break;\r
216                                         default:\r
217                                                 msg("Credential Type [",Integer.toString(cd.type),"] is invalid");\r
218                                 }\r
219                         }\r
220                 }\r
221                 return this;\r
222         }\r
223 \r
224 \r
225         public Validator user(Organization org, String user) {\r
226                 if(nob(user,ID_CHARS)) {\r
227                         msg("User [",user,"] is invalid.");\r
228                 }\r
229                 //TODO Change when Multi-Org solution is created\r
230 //              if(org instanceof ATT) {\r
231 //                      if(!user.endsWith("@csp.att.com") &&\r
232 //                         !org.isValidCred(user)) \r
233 //                                      msg("User [",user,"] is not valid ID for Credential in ",org.getRealm());\r
234 //              }\r
235                 return this;\r
236         }\r
237 \r
238         public Validator ns(Result<Namespace> nsd) {\r
239                 notOK(nsd);\r
240                 ns(nsd.value.name);\r
241                 for(String s : nsd.value.admin) {\r
242                         if(nob(s,ID_CHARS)) {\r
243                                 msg("Admin [" + s + "] is invalid.");           \r
244                         }\r
245                         \r
246                 }\r
247                 for(String s : nsd.value.owner) {\r
248                         if(nob(s,ID_CHARS)) {\r
249                                 msg("Responsible [" + s + "] is invalid.");             \r
250                         }\r
251                         \r
252                 }\r
253                 return this;\r
254         }\r
255 \r
256 \r
257         public Validator ns(String ns) {\r
258                 if(nob(ns,NAME_CHARS)){\r
259                         msg("NS [" + ns + "] is invalid.");\r
260                 }\r
261                 return this;\r
262         }\r
263 \r
264         public String errs() {\r
265                 return msgs.toString();\r
266         }\r
267 \r
268 \r
269         public Validator permType(String type, String ns) {\r
270                 // TODO check for correct Splits?  Type|Instance|Action ?\r
271                 if(nob(type,NAME_CHARS)) {\r
272                         msg("Perm Type [" + (ns==null?"":ns+(type.length()==0?"":'.'))+type + "] is invalid.");\r
273                 }\r
274                 return this;\r
275         }\r
276 \r
277         public Validator permInstance(String instance) {\r
278                 // TODO check for correct Splits?  Type|Instance|Action ?\r
279                 if(nob(instance,instChars)) {\r
280                         msg("Perm Instance [" + instance + "] is invalid.");\r
281                 }\r
282                 return this;\r
283         }\r
284 \r
285         public Validator permAction(String action) {\r
286                 // TODO check for correct Splits?  Type|Instance|Action ?\r
287                 if(nob(action, actionChars)) {\r
288                         msg("Perm Action [" + action + "] is invalid.");\r
289                 }\r
290                 return this;\r
291         }\r
292 \r
293         public Validator role(String role) {\r
294                 if(nob(role, NAME_CHARS)) {\r
295                         msg("Role [" + role + "] is invalid.");\r
296                 }\r
297                 return this;\r
298         }\r
299 \r
300         public Validator user_role(UserRoleDAO.Data urdd) {\r
301                 if(urdd==null) {\r
302                         msg("UserRole is null");\r
303                 } else {\r
304                         role(urdd.role);\r
305                         nullOrBlank("UserRole.ns",urdd.ns);\r
306                         nullOrBlank("UserRole.rname",urdd.rname);\r
307                 }\r
308                 return this;\r
309         }\r
310 \r
311         public Validator nullOrBlank(String name, String str) {\r
312                 if(str==null) {\r
313                         msg(name + " is null.");\r
314                 } else if(str.length()==0) {\r
315                         msg(name + " is blank.");\r
316                 }\r
317                 return this;\r
318         }\r
319         \r
320         public Validator nullOrBlank(PermDAO.Data pd) {\r
321                 if(pd==null) {\r
322                         msg("Permission is null");\r
323                 } else {\r
324                         nullOrBlank("NS",pd.ns).\r
325                         nullOrBlank("Type",pd.type).\r
326                         nullOrBlank("Instance",pd.instance).\r
327                         nullOrBlank("Action",pd.action);\r
328                 }\r
329                 return this;\r
330         }\r
331 \r
332         public Validator nullOrBlank(RoleDAO.Data rd) {\r
333                 if(rd==null) {\r
334                         msg("Role is null");\r
335                 } else {\r
336                         nullOrBlank("NS",rd.ns).\r
337                         nullOrBlank("Name",rd.name);\r
338                 }\r
339                 return this;\r
340         }\r
341 \r
342         // nob = Null Or Not match Pattern\r
343         private boolean nob(String str, Pattern p) {\r
344                 return str==null || !p.matcher(str).matches(); \r
345         }\r
346 \r
347         private void msg(String ... strs) {\r
348                 if(msgs==null) {\r
349                         msgs=new StringBuilder();\r
350                 }\r
351                 for(String str : strs) {\r
352                         msgs.append(str);\r
353                 }\r
354                 msgs.append('\n');\r
355         }\r
356         \r
357         public boolean err() {\r
358                 return msgs!=null;\r
359         }\r
360 \r
361 \r
362         public Validator notOK(Result<?> res) {\r
363                 if(res==null) {\r
364                         msgs.append("Result object is blank");\r
365                 } else if(res.notOK()) {\r
366                         msgs.append(res.getClass().getSimpleName() + " is not OK");\r
367                 }\r
368                 return this;\r
369         }\r
370 \r
371         public Validator key(String key) {\r
372                 if(nob(key,NAME_CHARS)) {\r
373                         msg("NS Prop Key [" + key + "] is invalid");\r
374                 }\r
375                 return this;\r
376         }\r
377         \r
378         public Validator value(String value) {\r
379                 if(nob(value,ESSENTIAL_CHARS)) {\r
380                         msg("NS Prop value [" + value + "] is invalid");\r
381                 }\r
382                 return this;\r
383         }\r
384 \r
385 \r
386 }\r