Mass removal of all Tabs (Style Warnings)
[aaf/authz.git] / cadi / aaf / src / main / java / org / onap / aaf / cadi / aaf / PermEval.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;
23
24 import org.onap.aaf.misc.env.util.Split;
25
26
27 public class PermEval {
28     public static final char START_REGEX_CHAR = '!';
29     public static final char START_INST_KEY_CHAR=':';
30     public static final char ALT_START_INST_KEY_CHAR='/';
31
32     public static final char LIST_SEP = ',';
33     public static final String INST_KEY_REGEX = new StringBuilder().append(START_INST_KEY_CHAR).toString();
34     public static final String ASTERIX = "*";
35
36     /**
37      * Evaluate Instance
38      *
39      * Instance can be more complex.  It can be a string, a Regular Expression, or a ":" separated Key
40      * who's parts can also be a String, Regular Expression.
41      *
42      * sInst = Server's Instance
43      * In order to prevent false matches, keys must be the same length to count as equal
44      * Changing this will break existing users, like Cassandra.  Jonathan 9-4-2015
45      */
46     public static boolean evalInstance(String sInst, String pInst) {
47         if(sInst == null || pInst == null) {
48             return false;
49         }
50         if (sInst == "" || pInst == "") {
51             return false;
52         }
53         if(ASTERIX.equals(sInst)) {
54             return true;            // If Server's String is "*", then it accepts every Instance
55         }
56         char firstChar = pInst.charAt(0);
57         char startChar = firstChar==ALT_START_INST_KEY_CHAR?ALT_START_INST_KEY_CHAR:START_INST_KEY_CHAR;
58         switch(pInst.charAt(0)) {                          // First char
59             case START_REGEX_CHAR:                            // Evaluate as Regular Expression
60                 String pItem = pInst.substring(1);
61                 String first = Split.split(LIST_SEP,sInst)[0];         // allow for "," definition in Action
62                 return first.matches(pItem);
63
64             case START_INST_KEY_CHAR:                        // Evaluate a special Key field, i.e.:xyz:*:!df.*
65             case ALT_START_INST_KEY_CHAR:                    // Also allow '/' as special Key Field, i.e. /xyz/*/!.*
66                 if(sInst.charAt(0)==startChar) {  // To compare key-to-key, both strings must be keys
67                     String[] skeys=Split.split(startChar,sInst);
68                     String[] pkeys=Split.split(startChar,pInst);
69                     if(skeys.length!=pkeys.length) return false;
70
71                     boolean pass = true;
72                     for(int i=1;pass && i<skeys.length;++i) {                  // We start at 1, because the first one, being ":" is always ""
73                         if(ASTERIX.equals(skeys[i]))continue;               // Server data accepts all for this key spot
74                         pass = false;
75                         for(String sItem : Split.split(LIST_SEP,skeys[i])) {        // allow for "," definition in Action
76                             if(pkeys[i].length()==0) {
77                                 if(pass=sItem.length()==0) {
78                                     break;                                  // Both Empty, keep checking
79                                 }
80                             } else if(sItem.charAt(0)==START_REGEX_CHAR) { // Check Server side when wildcarding like *
81                                 if(pass=pkeys[i].matches(sItem.substring(1))) {
82                                     break;                                  // Matches, keep checking
83                                 }
84                             } else if(skeys[i].endsWith(ASTERIX)) {
85                                 if(pass=endAsterixCompare(skeys[i],pkeys[i])) {
86                                     break;
87                                 }
88                             } else if(pass=sItem.equals(pkeys[i])) {
89                                 break;                                   // Equal, keep checking
90                             }
91                         }
92                     }
93                     return pass;                                             // return whether passed all key checks
94                 }
95                 return false;                                 // if first chars aren't the same, further String compare not necessary
96             default:                                        // Evaluate as String Compare
97                 for(String sItem : Split.split(LIST_SEP,sInst)) {    // allow for "," separator //TODO is this only for actions?
98                     if((sItem.endsWith(ASTERIX)) && (endAsterixCompare(sInst, pInst))) {
99                         return true;
100                     } else if(sItem.equals(pInst)) {
101                         return true;
102                     }
103                 }
104                 return false;
105         }
106     }
107
108      private static boolean endAsterixCompare(String sInst, String pInst) {
109         final int len = sInst.length()-1;
110         if(pInst.length()<len) {
111             return false;
112         }
113         for(int j=0;j<len;++j) {
114             if(pInst.charAt(j)!=sInst.charAt(j)) {
115                 return false;
116             }
117         }
118         return true;
119     }
120
121     /**
122      * Evaluate Action
123      *
124      * sAction = Stored Action...
125      * pAction = Present Action... the Permission to validate against.
126      * Action is not quite as complex.  But we write it in this function so it can be consistent
127      */
128     public static boolean evalAction(String sAction,String pAction) {
129         if(ASTERIX.equals(sAction))return true;               // If Server's String is "*", then it accepts every Action
130         if(pAction == "") return false;
131         for(String sItem : Split.split(LIST_SEP,sAction)) {         // allow for "," definition in Action
132             if (pAction.charAt(0)==START_REGEX_CHAR?       // First char
133                     sItem.matches(pAction.substring(1)):   // Evaluate as Regular Expression
134                     sItem.equals(pAction))                 // Evaluate as String Compare
135                 return true;
136         }
137         return false;
138     }
139
140 }