1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\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
11 * * http://www.apache.org/licenses/LICENSE-2.0
\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
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
23 package com.att.cadi.aaf;
\r
25 import com.att.inno.env.util.Split;
\r
28 public class PermEval {
\r
29 public static final char START_REGEX_CHAR = '!';
\r
30 public static final char START_INST_KEY_CHAR=':';
\r
31 public static final char ALT_START_INST_KEY_CHAR='/';
\r
33 public static final char LIST_SEP = ',';
\r
34 public static final String INST_KEY_REGEX = new StringBuilder().append(START_INST_KEY_CHAR).toString();
\r
35 public static final String ASTERIX = "*";
\r
40 * Instance can be more complex. It can be a string, a Regular Expression, or a ":" separated Key
\r
41 * who's parts can also be a String, Regular Expression.
\r
43 * sInst = Server's Instance
\r
44 * In order to prevent false matches, keys must be the same length to count as equal
\r
45 * Changing this will break existing users, like Cassandra. 9-4-2015
\r
47 public static boolean evalInstance(String sInst, String pInst) {
\r
48 if(sInst==null || pInst == null) {
\r
51 if(ASTERIX.equals(sInst)) {
\r
52 return true; // If Server's String is "*", then it accepts every Instance
\r
54 char firstChar = pInst.charAt(0);
\r
55 char startChar = firstChar==ALT_START_INST_KEY_CHAR?ALT_START_INST_KEY_CHAR:START_INST_KEY_CHAR;
\r
56 switch(pInst.charAt(0)) { // First char
\r
57 case START_REGEX_CHAR: // Evaluate as Regular Expression
\r
58 String pItem = pInst.substring(1);
\r
59 for(String sItem : Split.split(LIST_SEP,sInst)) { // allow for "," definition in Action
\r
60 return sItem.matches(pItem);
\r
63 case START_INST_KEY_CHAR: // Evaluate a special Key field, i.e.:xyz:*:!df.*
\r
64 case ALT_START_INST_KEY_CHAR: // Also allow '/' as special Key Field, i.e. /xyz/*/!.*
\r
65 if(sInst.charAt(0)==startChar) { // To compare key-to-key, both strings must be keys
\r
66 String[] skeys=Split.split(startChar,sInst);
\r
67 String[] pkeys=Split.split(startChar,pInst);
\r
68 if(skeys.length!=pkeys.length) return false;
\r
70 boolean pass = true;
\r
71 for(int i=1;pass && i<skeys.length;++i) { // We start at 1, because the first one, being ":" is always ""
\r
72 if(ASTERIX.equals(skeys[i]))continue; // Server data accepts all for this key spot
\r
74 for(String sItem : Split.split(LIST_SEP,skeys[i])) { // allow for "," definition in Action
\r
75 if(pkeys[i].length()==0) {
\r
76 if(pass=sItem.length()==0) {
\r
77 break; // Both Empty, keep checking
\r
79 // } else if(pkeys[i].charAt(0)==START_REGEX_CHAR) {
\r
80 // if(pass=sItem.matches(pkeys[i].substring(1))) {
\r
81 // break; // Matches, keep checking
\r
83 } else if(sItem.charAt(0)==START_REGEX_CHAR) { // Check Server side when wildcarding like *
\r
84 if(pass=pkeys[i].matches(sItem.substring(1))) {
\r
85 break; // Matches, keep checking
\r
87 } else if(skeys[i].endsWith(ASTERIX)) {
\r
88 if(pass=endAsterixCompare(skeys[i],pkeys[i])) {
\r
92 if(pass=sItem.equals(pkeys[i]))
\r
93 break; // Equal, keep checking
\r
97 return pass; // return whether passed all key checks
\r
99 return false; // if first chars aren't the same, further String compare not necessary
\r
100 default: // Evaluate as String Compare
\r
101 for(String sItem : Split.split(LIST_SEP,sInst)) { // allow for "," separator //TODO is this only for actions?
\r
102 if(sItem.endsWith(ASTERIX)) {
\r
103 if(endAsterixCompare(sInst, pInst));
\r
104 } else if(sItem.equals(pInst)) {
\r
112 private static boolean endAsterixCompare(String sInst, String pInst) {
\r
113 final int len = sInst.length()-1;
\r
114 if(pInst.length()<len) {
\r
117 for(int j=0;j<len;++j) {
\r
118 if(pInst.charAt(j)!=sInst.charAt(j)) {
\r
128 * sAction = Stored Action...
\r
129 * pAction = Present Action... the Permission to validate against.
\r
130 * Action is not quite as complex. But we write it in this function so it can be consistent
\r
132 public static boolean evalAction(String sAction,String pAction) {
\r
133 if(ASTERIX.equals(sAction))return true; // If Server's String is "*", then it accepts every Action
\r
134 for(String sItem : Split.split(LIST_SEP,sAction)) { // allow for "," definition in Action
\r
135 if (pAction.charAt(0)==START_REGEX_CHAR? // First char
\r
136 sItem.matches(pAction.substring(1)): // Evaluate as Regular Expression
\r
137 sItem.equals(pAction)) // Evaluate as String Compare
\r
144 * Split.split by Char
\r
146 * Note: I read the String Split.split and Pattern Split.split code, and we can do this more efficiently for a single Character
\r