[AAF-21] Initial code import
[aaf/cadi.git] / aaf / src / main / java / com / att / cadi / aaf / PermEval.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aai\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * Copyright © 2017 Amdocs\r
7  * * ===========================================================================\r
8  * * Licensed under the Apache License, Version 2.0 (the "License");\r
9  * * you may not use this file except in compliance with the License.\r
10  * * You may obtain a copy of the License at\r
11  * * \r
12  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
13  * * \r
14  *  * Unless required by applicable law or agreed to in writing, software\r
15  * * distributed under the License is distributed on an "AS IS" BASIS,\r
16  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
17  * * See the License for the specific language governing permissions and\r
18  * * limitations under the License.\r
19  * * ============LICENSE_END====================================================\r
20  * *\r
21  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
22  * *\r
23  ******************************************************************************/\r
24 package com.att.cadi.aaf;\r
25 \r
26 import com.att.inno.env.util.Split;\r
27 \r
28 \r
29 public class PermEval {\r
30         public static final char START_REGEX_CHAR = '!';\r
31         public static final char START_INST_KEY_CHAR=':';\r
32         public static final char ALT_START_INST_KEY_CHAR='/';\r
33         \r
34         public static final char LIST_SEP = ',';\r
35         public static final String INST_KEY_REGEX = new StringBuilder().append(START_INST_KEY_CHAR).toString();\r
36         public static final String ASTERIX = "*";\r
37         \r
38         /**\r
39          * Evaluate Instance\r
40          * \r
41          * Instance can be more complex.  It can be a string, a Regular Expression, or a ":" separated Key \r
42          * who's parts can also be a String, Regular Expression.\r
43          * \r
44          * sInst = Server's Instance\r
45          * In order to prevent false matches, keys must be the same length to count as equal\r
46          * Changing this will break existing users, like Cassandra.  9-4-2015\r
47          */\r
48          public static boolean evalInstance(String sInst, String pInst) {\r
49                  if(sInst==null || pInst == null) {\r
50                          return false;\r
51                  }\r
52                   if(ASTERIX.equals(sInst)) {\r
53                           return true;                  // If Server's String is "*", then it accepts every Instance\r
54                   }\r
55                   char firstChar = pInst.charAt(0);\r
56                   char startChar = firstChar==ALT_START_INST_KEY_CHAR?ALT_START_INST_KEY_CHAR:START_INST_KEY_CHAR;\r
57                   switch(pInst.charAt(0)) {                                             // First char\r
58                         case START_REGEX_CHAR:                                                  // Evaluate as Regular Expression\r
59                                 String pItem = pInst.substring(1);\r
60                             for(String sItem : Split.split(LIST_SEP,sInst)) {           // allow for "," definition in Action\r
61                                 return sItem.matches(pItem);\r
62                             }\r
63                          \r
64                         case START_INST_KEY_CHAR:                                               // Evaluate a special Key field, i.e.:xyz:*:!df.*\r
65                         case ALT_START_INST_KEY_CHAR:                                   // Also allow '/' as special Key Field, i.e. /xyz/*/!.*\r
66                                 if(sInst.charAt(0)==startChar) {  // To compare key-to-key, both strings must be keys\r
67                                         String[] skeys=Split.split(startChar,sInst);\r
68                                         String[] pkeys=Split.split(startChar,pInst);\r
69                                         if(skeys.length!=pkeys.length) return false;\r
70                                         \r
71                                         boolean pass = true;\r
72                                         for(int i=1;pass && i<skeys.length;++i) {                               // We start at 1, because the first one, being ":" is always ""\r
73                                                 if(ASTERIX.equals(skeys[i]))continue;                           // Server data accepts all for this key spot\r
74                                                 pass = false;\r
75                                             for(String sItem : Split.split(LIST_SEP,skeys[i])) {                // allow for "," definition in Action\r
76                                                         if(pkeys[i].length()==0) {\r
77                                                                 if(pass=sItem.length()==0) {\r
78                                                                         break;                                                                  // Both Empty, keep checking\r
79                                                                 }\r
80 //                                                      } else if(pkeys[i].charAt(0)==START_REGEX_CHAR) { \r
81 //                                                              if(pass=sItem.matches(pkeys[i].substring(1))) {\r
82 //                                                                      break;                                                                  // Matches, keep checking\r
83 //                                                              }\r
84                                                         } else if(sItem.charAt(0)==START_REGEX_CHAR) { // Check Server side when wildcarding like *\r
85                                                                 if(pass=pkeys[i].matches(sItem.substring(1))) {\r
86                                                                         break;                                                                  // Matches, keep checking\r
87                                                                 }\r
88                                                         } else if(skeys[i].endsWith(ASTERIX)) {\r
89                                                                 if(pass=endAsterixCompare(skeys[i],pkeys[i])) {\r
90                                                                         break;\r
91                                                                 }\r
92                                                         } else {\r
93                                                                 if(pass=sItem.equals(pkeys[i]))\r
94                                                                         break;                                                                  // Equal, keep checking\r
95                                                         }\r
96                                             }\r
97                                         }\r
98                                         return pass;                                                                                    // return whether passed all key checks\r
99                                 }\r
100                                 return false;                                                           // if first chars aren't the same, further String compare not necessary\r
101                         default:                                                                                // Evaluate as String Compare\r
102                             for(String sItem : Split.split(LIST_SEP,sInst)) {   // allow for "," separator //TODO is this only for actions?\r
103                                 if(sItem.endsWith(ASTERIX)) {\r
104                                         if(endAsterixCompare(sInst, pInst));\r
105                                 } else if(sItem.equals(pInst)) {\r
106                                         return true;\r
107                                 }\r
108                             }\r
109                             return false;\r
110                   }\r
111          }\r
112          \r
113          private static boolean endAsterixCompare(String sInst, String pInst) {\r
114                         final int len = sInst.length()-1;\r
115                         if(pInst.length()<len) {\r
116                                 return false;\r
117                         }\r
118                         for(int j=0;j<len;++j) {\r
119                                 if(pInst.charAt(j)!=sInst.charAt(j)) {\r
120                                         return false;\r
121                                 }\r
122                         }\r
123                         return true;\r
124         }\r
125 \r
126         /**\r
127           * Evaluate Action\r
128           * \r
129           * sAction = Stored Action...\r
130           * pAction = Present Action... the Permission to validate against.\r
131           * Action is not quite as complex.  But we write it in this function so it can be consistent\r
132           */\r
133           public static boolean evalAction(String sAction,String pAction) {\r
134                   if(ASTERIX.equals(sAction))return true;                    // If Server's String is "*", then it accepts every Action\r
135                   for(String sItem : Split.split(LIST_SEP,sAction)) {            // allow for "," definition in Action\r
136                           if (pAction.charAt(0)==START_REGEX_CHAR?       // First char\r
137                                       sItem.matches(pAction.substring(1)):   // Evaluate as Regular Expression\r
138                                       sItem.equals(pAction))                 // Evaluate as String Compare\r
139                                                 return true;\r
140                   }             \r
141                   return false;\r
142           }\r
143          \r
144           /**\r
145            * Split.split by Char\r
146            * \r
147            * Note: I read the String Split.split and Pattern Split.split code, and we can do this more efficiently for a single Character\r
148            */\r
149 \r
150 }\r