Update project structure to org.onap.aaf
[aaf/authz.git] / authz-service / src / main / java / org / onap / aaf / authz / service / validation / Validator.java
diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/validation/Validator.java b/authz-service/src/main/java/org/onap/aaf/authz/service/validation/Validator.java
new file mode 100644 (file)
index 0000000..6eca6ce
--- /dev/null
@@ -0,0 +1,386 @@
+/*******************************************************************************\r
+ * ============LICENSE_START====================================================\r
+ * * org.onap.aaf\r
+ * * ===========================================================================\r
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
+ * * ===========================================================================\r
+ * * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * * you may not use this file except in compliance with the License.\r
+ * * You may obtain a copy of the License at\r
+ * * \r
+ *  *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * * \r
+ *  * Unless required by applicable law or agreed to in writing, software\r
+ * * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * * See the License for the specific language governing permissions and\r
+ * * limitations under the License.\r
+ * * ============LICENSE_END====================================================\r
+ * *\r
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
+ * *\r
+ ******************************************************************************/\r
+package org.onap.aaf.authz.service.validation;\r
+\r
+import java.util.regex.Pattern;\r
+\r
+import org.onap.aaf.authz.cadi.DirectAAFLur.PermPermission;\r
+import org.onap.aaf.authz.env.AuthzTrans;\r
+import org.onap.aaf.authz.layer.Result;\r
+import org.onap.aaf.authz.org.Organization;\r
+import org.onap.aaf.dao.aaf.cass.CredDAO;\r
+import org.onap.aaf.dao.aaf.cass.DelegateDAO;\r
+import org.onap.aaf.dao.aaf.cass.Namespace;\r
+import org.onap.aaf.dao.aaf.cass.PermDAO;\r
+import org.onap.aaf.dao.aaf.cass.RoleDAO;\r
+import org.onap.aaf.dao.aaf.cass.UserRoleDAO;\r
+\r
+/**\r
+ * Validator\r
+ * Consistently apply content rules for content (incoming)\r
+ * \r
+ * Note: We restrict content for usability in URLs (because RESTful service), and avoid \r
+ * issues with Regular Expressions, and other enabling technologies. \r
+ *\r
+ */\r
+public class Validator {\r
+       // % () ,-. 0-9 =A-Z _a-z\r
+       private static final String ESSENTIAL="\\x25\\x28\\x29\\x2C-\\x2E\\x30-\\x39\\x3D\\x40-\\x5A\\x5F\\x61-\\x7A";\r
+       private static final Pattern ESSENTIAL_CHARS=Pattern.compile("["+ESSENTIAL+"]+");\r
+       \r
+       // Must be 1 or more of Alphanumeric or the following  :._-\r
+       // '*' only allowed when it is the only character, or the only element in a key separator\r
+       //  :* :hello:* :hello:*:there  etc\r
+       public static final Pattern ACTION_CHARS=Pattern.compile(\r
+                       "["+ESSENTIAL+"]+" +    // All AlphaNumeric+\r
+                       "|\\*"                                          // Just Star\r
+                       );\r
+\r
+       public static final Pattern INST_CHARS=Pattern.compile(\r
+                       "["+ESSENTIAL+"]+[\\*]*" +                              // All AlphaNumeric+ possibly ending with *\r
+                       "|\\*" +                                                                // Just Star\r
+                       "|(([:/]\\*)|([:/][!]{0,1}["+ESSENTIAL+"]+[\\*]*[:/]*))+"       // Key :asdf:*:sdf*:sdk\r
+                       );\r
+       \r
+       // Must be 1 or more of Alphanumeric or the following  ._-, and be in the form id@domain\r
+       public static final Pattern ID_CHARS=Pattern.compile("[\\w.-]+@[\\w.-]+");\r
+       // Must be 1 or more of Alphanumeric or the following  ._-\r
+       public static final Pattern NAME_CHARS=Pattern.compile("[\\w.-]+");\r
+       \r
+       private final Pattern actionChars;\r
+       private final Pattern instChars;\r
+       private StringBuilder msgs;\r
+\r
+       /**\r
+        * Default Validator does not check for non-standard Action/Inst chars\r
+        * \r
+        * \r
+        * IMPORTANT: Use ONLY when the Validator is doing something simple... NullOrBlank\r
+        */\r
+       public Validator() {\r
+               actionChars = ACTION_CHARS;\r
+               instChars = INST_CHARS;\r
+       }\r
+       \r
+       /**\r
+        * When Trans is passed in, check for non-standard Action/Inst chars\r
+        * \r
+        * This is an opportunity to change characters, if required.\r
+        * \r
+        * Use for any Object method passed (i.e. role(RoleDAO.Data d) ), to ensure fewer bugs.\r
+        * \r
+        * @param trans\r
+        */\r
+       public Validator(AuthzTrans trans) {\r
+               actionChars = ACTION_CHARS;\r
+               instChars = INST_CHARS;\r
+       }\r
+\r
+\r
+       public Validator perm(Result<PermDAO.Data> rpd) {\r
+               if(rpd.notOK()) {\r
+                       msg(rpd.details);\r
+               } else {\r
+                       perm(rpd.value);\r
+               }\r
+               return this;\r
+       }\r
+\r
+\r
+       public Validator perm(PermDAO.Data pd) {\r
+               if(pd==null) {\r
+                       msg("Perm Data is null.");\r
+               } else {\r
+                       ns(pd.ns);\r
+                       permType(pd.type,pd.ns);\r
+                       permInstance(pd.instance);\r
+                       permAction(pd.action);\r
+                       if(pd.roles!=null) { \r
+                               for(String role : pd.roles) {\r
+                                       role(role);\r
+                               }\r
+                       }\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public Validator role(Result<RoleDAO.Data> rrd) {\r
+               if(rrd.notOK()) {\r
+                       msg(rrd.details);\r
+               } else {\r
+                       role(rrd.value);\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public Validator role(RoleDAO.Data pd) {\r
+               if(pd==null) {\r
+                       msg("Role Data is null.");\r
+               } else {\r
+                       ns(pd.ns);\r
+                       role(pd.name);\r
+                       if(pd.perms!=null) {\r
+                               for(String perm : pd.perms) {\r
+                                       String[] ps = perm.split("\\|");\r
+                                       if(ps.length!=3) {\r
+                                               msg("Perm [" + perm + "] in Role [" + pd.fullName() + "] is not correctly separated with '|'");\r
+                                       } else {\r
+                                               permType(ps[0],null);\r
+                                               permInstance(ps[1]);\r
+                                               permAction(ps[2]);\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public Validator delegate(Organization org, Result<DelegateDAO.Data> rdd) {\r
+               if(rdd.notOK()) {\r
+                       msg(rdd.details);\r
+               } else {\r
+                       delegate(org, rdd.value);\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public Validator delegate(Organization org, DelegateDAO.Data dd) {\r
+               if(dd==null) {\r
+                       msg("Delegate Data is null.");\r
+               } else {\r
+                       user(org,dd.user);\r
+                       user(org,dd.delegate);\r
+               }\r
+               return this;\r
+       }\r
+\r
+\r
+       public Validator cred(Organization org, Result<CredDAO.Data> rcd, boolean isNew) {\r
+               if(rcd.notOK()) {\r
+                       msg(rcd.details);\r
+               } else {\r
+                       cred(org,rcd.value,isNew);\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public Validator cred(Organization org, CredDAO.Data cd, boolean isNew) {\r
+               if(cd==null) {\r
+                       msg("Cred Data is null.");\r
+               } else {\r
+                       if(nob(cd.id,ID_CHARS)) {\r
+                               msg("ID [" + cd.id + "] is invalid");\r
+                       }\r
+                       if(!org.isValidCred(cd.id)) {\r
+                               msg("ID [" + cd.id + "] is invalid for a cred");\r
+                       }\r
+                       String str = cd.id;\r
+                       int idx = str.indexOf('@');\r
+                       if(idx>0) {\r
+                               str = str.substring(0,idx);\r
+                       }\r
+                       \r
+                       if(cd.id.endsWith(org.getRealm())) {\r
+                               if(isNew && (str=org.isValidID(str)).length()>0) {\r
+                                       msg(cd.id,str);\r
+                               }\r
+                       }\r
+       \r
+                       if(cd.type==null) {\r
+                               msg("Credential Type must be set");\r
+                       } else {\r
+                               switch(cd.type) {\r
+                                       case CredDAO.BASIC_AUTH_SHA256:\r
+                                               // ok\r
+                                               break;\r
+                                       default:\r
+                                               msg("Credential Type [",Integer.toString(cd.type),"] is invalid");\r
+                               }\r
+                       }\r
+               }\r
+               return this;\r
+       }\r
+\r
+\r
+       public Validator user(Organization org, String user) {\r
+               if(nob(user,ID_CHARS)) {\r
+                       msg("User [",user,"] is invalid.");\r
+               }\r
+               //TODO Change when Multi-Org solution is created\r
+//             if(org instanceof ATT) {\r
+//                     if(!user.endsWith("@csp.att.com") &&\r
+//                        !org.isValidCred(user)) \r
+//                                     msg("User [",user,"] is not valid ID for Credential in ",org.getRealm());\r
+//             }\r
+               return this;\r
+       }\r
+\r
+       public Validator ns(Result<Namespace> nsd) {\r
+               notOK(nsd);\r
+               ns(nsd.value.name);\r
+               for(String s : nsd.value.admin) {\r
+                       if(nob(s,ID_CHARS)) {\r
+                               msg("Admin [" + s + "] is invalid.");           \r
+                       }\r
+                       \r
+               }\r
+               for(String s : nsd.value.owner) {\r
+                       if(nob(s,ID_CHARS)) {\r
+                               msg("Responsible [" + s + "] is invalid.");             \r
+                       }\r
+                       \r
+               }\r
+               return this;\r
+       }\r
+\r
+\r
+       public Validator ns(String ns) {\r
+               if(nob(ns,NAME_CHARS)){\r
+                       msg("NS [" + ns + "] is invalid.");\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public String errs() {\r
+               return msgs.toString();\r
+       }\r
+\r
+\r
+       public Validator permType(String type, String ns) {\r
+               // TODO check for correct Splits?  Type|Instance|Action ?\r
+               if(nob(type,NAME_CHARS)) {\r
+                       msg("Perm Type [" + (ns==null?"":ns+(type.length()==0?"":'.'))+type + "] is invalid.");\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public Validator permInstance(String instance) {\r
+               // TODO check for correct Splits?  Type|Instance|Action ?\r
+               if(nob(instance,instChars)) {\r
+                       msg("Perm Instance [" + instance + "] is invalid.");\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public Validator permAction(String action) {\r
+               // TODO check for correct Splits?  Type|Instance|Action ?\r
+               if(nob(action, actionChars)) {\r
+                       msg("Perm Action [" + action + "] is invalid.");\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public Validator role(String role) {\r
+               if(nob(role, NAME_CHARS)) {\r
+                       msg("Role [" + role + "] is invalid.");\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public Validator user_role(UserRoleDAO.Data urdd) {\r
+               if(urdd==null) {\r
+                       msg("UserRole is null");\r
+               } else {\r
+                       role(urdd.role);\r
+                       nullOrBlank("UserRole.ns",urdd.ns);\r
+                       nullOrBlank("UserRole.rname",urdd.rname);\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public Validator nullOrBlank(String name, String str) {\r
+               if(str==null) {\r
+                       msg(name + " is null.");\r
+               } else if(str.length()==0) {\r
+                       msg(name + " is blank.");\r
+               }\r
+               return this;\r
+       }\r
+       \r
+       public Validator nullOrBlank(PermDAO.Data pd) {\r
+               if(pd==null) {\r
+                       msg("Permission is null");\r
+               } else {\r
+                       nullOrBlank("NS",pd.ns).\r
+                       nullOrBlank("Type",pd.type).\r
+                       nullOrBlank("Instance",pd.instance).\r
+                       nullOrBlank("Action",pd.action);\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public Validator nullOrBlank(RoleDAO.Data rd) {\r
+               if(rd==null) {\r
+                       msg("Role is null");\r
+               } else {\r
+                       nullOrBlank("NS",rd.ns).\r
+                       nullOrBlank("Name",rd.name);\r
+               }\r
+               return this;\r
+       }\r
+\r
+       // nob = Null Or Not match Pattern\r
+       private boolean nob(String str, Pattern p) {\r
+               return str==null || !p.matcher(str).matches(); \r
+       }\r
+\r
+       private void msg(String ... strs) {\r
+               if(msgs==null) {\r
+                       msgs=new StringBuilder();\r
+               }\r
+               for(String str : strs) {\r
+                       msgs.append(str);\r
+               }\r
+               msgs.append('\n');\r
+       }\r
+       \r
+       public boolean err() {\r
+               return msgs!=null;\r
+       }\r
+\r
+\r
+       public Validator notOK(Result<?> res) {\r
+               if(res==null) {\r
+                       msgs.append("Result object is blank");\r
+               } else if(res.notOK()) {\r
+                       msgs.append(res.getClass().getSimpleName() + " is not OK");\r
+               }\r
+               return this;\r
+       }\r
+\r
+       public Validator key(String key) {\r
+               if(nob(key,NAME_CHARS)) {\r
+                       msg("NS Prop Key [" + key + "] is invalid");\r
+               }\r
+               return this;\r
+       }\r
+       \r
+       public Validator value(String value) {\r
+               if(nob(value,ESSENTIAL_CHARS)) {\r
+                       msg("NS Prop value [" + value + "] is invalid");\r
+               }\r
+               return this;\r
+       }\r
+\r
+\r
+}\r