1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\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
12 * * http://www.apache.org/licenses/LICENSE-2.0
\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
21 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
23 ******************************************************************************/
\r
24 package com.att.authz.service.validation;
\r
26 import java.util.regex.Pattern;
\r
28 import com.att.authz.cadi.DirectAAFLur.PermPermission;
\r
29 import com.att.authz.env.AuthzTrans;
\r
30 import com.att.authz.layer.Result;
\r
31 import com.att.authz.org.Organization;
\r
32 import com.att.dao.aaf.cass.CredDAO;
\r
33 import com.att.dao.aaf.cass.DelegateDAO;
\r
34 import com.att.dao.aaf.cass.Namespace;
\r
35 import com.att.dao.aaf.cass.PermDAO;
\r
36 import com.att.dao.aaf.cass.RoleDAO;
\r
37 import com.att.dao.aaf.cass.UserRoleDAO;
\r
41 * Consistently apply content rules for content (incoming)
\r
43 * Note: We restrict content for usability in URLs (because RESTful service), and avoid
\r
44 * issues with Regular Expressions, and other enabling technologies.
\r
47 public class Validator {
\r
48 // % () ,-. 0-9 =A-Z _a-z
\r
49 private static final String ESSENTIAL="\\x25\\x28\\x29\\x2C-\\x2E\\x30-\\x39\\x3D\\x40-\\x5A\\x5F\\x61-\\x7A";
\r
50 private static final Pattern ESSENTIAL_CHARS=Pattern.compile("["+ESSENTIAL+"]+");
\r
52 // Must be 1 or more of Alphanumeric or the following :._-
\r
53 // '*' only allowed when it is the only character, or the only element in a key separator
\r
54 // :* :hello:* :hello:*:there etc
\r
55 public static final Pattern ACTION_CHARS=Pattern.compile(
\r
56 "["+ESSENTIAL+"]+" + // All AlphaNumeric+
\r
60 public static final Pattern INST_CHARS=Pattern.compile(
\r
61 "["+ESSENTIAL+"]+[\\*]*" + // All AlphaNumeric+ possibly ending with *
\r
62 "|\\*" + // Just Star
\r
63 "|(([:/]\\*)|([:/][!]{0,1}["+ESSENTIAL+"]+[\\*]*[:/]*))+" // Key :asdf:*:sdf*:sdk
\r
66 // Must be 1 or more of Alphanumeric or the following ._-, and be in the form id@domain
\r
67 public static final Pattern ID_CHARS=Pattern.compile("[\\w.-]+@[\\w.-]+");
\r
68 // Must be 1 or more of Alphanumeric or the following ._-
\r
69 public static final Pattern NAME_CHARS=Pattern.compile("[\\w.-]+");
\r
71 private final Pattern actionChars;
\r
72 private final Pattern instChars;
\r
73 private StringBuilder msgs;
\r
76 * Default Validator does not check for non-standard Action/Inst chars
\r
79 * IMPORTANT: Use ONLY when the Validator is doing something simple... NullOrBlank
\r
81 public Validator() {
\r
82 actionChars = ACTION_CHARS;
\r
83 instChars = INST_CHARS;
\r
87 * When Trans is passed in, check for non-standard Action/Inst chars
\r
89 * This is an opportunity to change characters, if required.
\r
91 * Use for any Object method passed (i.e. role(RoleDAO.Data d) ), to ensure fewer bugs.
\r
95 public Validator(AuthzTrans trans) {
\r
96 actionChars = ACTION_CHARS;
\r
97 instChars = INST_CHARS;
\r
101 public Validator perm(Result<PermDAO.Data> rpd) {
\r
111 public Validator perm(PermDAO.Data pd) {
\r
113 msg("Perm Data is null.");
\r
116 permType(pd.type,pd.ns);
\r
117 permInstance(pd.instance);
\r
118 permAction(pd.action);
\r
119 if(pd.roles!=null) {
\r
120 for(String role : pd.roles) {
\r
128 public Validator role(Result<RoleDAO.Data> rrd) {
\r
137 public Validator role(RoleDAO.Data pd) {
\r
139 msg("Role Data is null.");
\r
143 if(pd.perms!=null) {
\r
144 for(String perm : pd.perms) {
\r
145 String[] ps = perm.split("\\|");
\r
147 msg("Perm [" + perm + "] in Role [" + pd.fullName() + "] is not correctly separated with '|'");
\r
149 permType(ps[0],null);
\r
150 permInstance(ps[1]);
\r
159 public Validator delegate(Organization org, Result<DelegateDAO.Data> rdd) {
\r
163 delegate(org, rdd.value);
\r
168 public Validator delegate(Organization org, DelegateDAO.Data dd) {
\r
170 msg("Delegate Data is null.");
\r
173 user(org,dd.delegate);
\r
179 public Validator cred(Organization org, Result<CredDAO.Data> rcd, boolean isNew) {
\r
183 cred(org,rcd.value,isNew);
\r
188 public Validator cred(Organization org, CredDAO.Data cd, boolean isNew) {
\r
190 msg("Cred Data is null.");
\r
192 if(nob(cd.id,ID_CHARS)) {
\r
193 msg("ID [" + cd.id + "] is invalid");
\r
195 if(!org.isValidCred(cd.id)) {
\r
196 msg("ID [" + cd.id + "] is invalid for a cred");
\r
198 String str = cd.id;
\r
199 int idx = str.indexOf('@');
\r
201 str = str.substring(0,idx);
\r
204 if(cd.id.endsWith(org.getRealm())) {
\r
205 if(isNew && (str=org.isValidID(str)).length()>0) {
\r
210 if(cd.type==null) {
\r
211 msg("Credential Type must be set");
\r
214 case CredDAO.BASIC_AUTH_SHA256:
\r
218 msg("Credential Type [",Integer.toString(cd.type),"] is invalid");
\r
226 public Validator user(Organization org, String user) {
\r
227 if(nob(user,ID_CHARS)) {
\r
228 msg("User [",user,"] is invalid.");
\r
230 //TODO Change when Multi-Org solution is created
\r
231 // if(org instanceof ATT) {
\r
232 // if(!user.endsWith("@csp.att.com") &&
\r
233 // !org.isValidCred(user))
\r
234 // msg("User [",user,"] is not valid ID for Credential in ",org.getRealm());
\r
239 public Validator ns(Result<Namespace> nsd) {
\r
241 ns(nsd.value.name);
\r
242 for(String s : nsd.value.admin) {
\r
243 if(nob(s,ID_CHARS)) {
\r
244 msg("Admin [" + s + "] is invalid.");
\r
248 for(String s : nsd.value.owner) {
\r
249 if(nob(s,ID_CHARS)) {
\r
250 msg("Responsible [" + s + "] is invalid.");
\r
258 public Validator ns(String ns) {
\r
259 if(nob(ns,NAME_CHARS)){
\r
260 msg("NS [" + ns + "] is invalid.");
\r
265 public String errs() {
\r
266 return msgs.toString();
\r
270 public Validator permType(String type, String ns) {
\r
271 // TODO check for correct Splits? Type|Instance|Action ?
\r
272 if(nob(type,NAME_CHARS)) {
\r
273 msg("Perm Type [" + (ns==null?"":ns+(type.length()==0?"":'.'))+type + "] is invalid.");
\r
278 public Validator permInstance(String instance) {
\r
279 // TODO check for correct Splits? Type|Instance|Action ?
\r
280 if(nob(instance,instChars)) {
\r
281 msg("Perm Instance [" + instance + "] is invalid.");
\r
286 public Validator permAction(String action) {
\r
287 // TODO check for correct Splits? Type|Instance|Action ?
\r
288 if(nob(action, actionChars)) {
\r
289 msg("Perm Action [" + action + "] is invalid.");
\r
294 public Validator role(String role) {
\r
295 if(nob(role, NAME_CHARS)) {
\r
296 msg("Role [" + role + "] is invalid.");
\r
301 public Validator user_role(UserRoleDAO.Data urdd) {
\r
303 msg("UserRole is null");
\r
306 nullOrBlank("UserRole.ns",urdd.ns);
\r
307 nullOrBlank("UserRole.rname",urdd.rname);
\r
312 public Validator nullOrBlank(String name, String str) {
\r
314 msg(name + " is null.");
\r
315 } else if(str.length()==0) {
\r
316 msg(name + " is blank.");
\r
321 public Validator nullOrBlank(PermDAO.Data pd) {
\r
323 msg("Permission is null");
\r
325 nullOrBlank("NS",pd.ns).
\r
326 nullOrBlank("Type",pd.type).
\r
327 nullOrBlank("Instance",pd.instance).
\r
328 nullOrBlank("Action",pd.action);
\r
333 public Validator nullOrBlank(RoleDAO.Data rd) {
\r
335 msg("Role is null");
\r
337 nullOrBlank("NS",rd.ns).
\r
338 nullOrBlank("Name",rd.name);
\r
343 // nob = Null Or Not match Pattern
\r
344 private boolean nob(String str, Pattern p) {
\r
345 return str==null || !p.matcher(str).matches();
\r
348 private void msg(String ... strs) {
\r
350 msgs=new StringBuilder();
\r
352 for(String str : strs) {
\r
358 public boolean err() {
\r
363 public Validator notOK(Result<?> res) {
\r
365 msgs.append("Result object is blank");
\r
366 } else if(res.notOK()) {
\r
367 msgs.append(res.getClass().getSimpleName() + " is not OK");
\r
372 public Validator key(String key) {
\r
373 if(nob(key,NAME_CHARS)) {
\r
374 msg("NS Prop Key [" + key + "] is invalid");
\r
379 public Validator value(String value) {
\r
380 if(nob(value,ESSENTIAL_CHARS)) {
\r
381 msg("NS Prop value [" + value + "] is invalid");
\r