diff options
Diffstat (limited to 'auth/auth-cass')
13 files changed, 151 insertions, 59 deletions
diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java index 7831815f..72c0e98b 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java @@ -90,9 +90,9 @@ public class FutureDAO extends CassDAOImpl<AuthzTrans,FutureDAO.Data> { data.memo = row.getString(2); data.start = row.getTimestamp(3); data.expires = row.getTimestamp(4); - data.construct = row.getBytes(5); - data.target_key = row.getString(6); - data.target_date = row.getTimestamp(7); + data.target_key = row.getString(5); + data.target_date = row.getTimestamp(6); + data.construct = row.getBytes(7); return data; } @@ -109,9 +109,9 @@ public class FutureDAO extends CassDAOImpl<AuthzTrans,FutureDAO.Data> { obj[++idx] = data.memo; obj[++idx] = data.start; obj[++idx] = data.expires; - obj[++idx] = data.construct; obj[++idx] = data.target_key; obj[++idx] = data.target_date; + obj[++idx] = data.construct; } } diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/NsDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/NsDAO.java index f769e38c..10e7844c 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/NsDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/NsDAO.java @@ -64,6 +64,7 @@ public class NsDAO extends CassDAOImpl<AuthzTrans,NsDAO.Data> { public static final String TABLE = "ns"; public static final String TABLE_ATTRIB = "ns_attrib"; public static final int CACHE_SEG = 0x40; // yields segment 0x0-0x3F + public static final int USER = 0; public static final int ROOT = 1; public static final int COMPANY=2; public static final int APP = 3; diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/PermDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/PermDAO.java index 6e1057b8..0033f8a1 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/PermDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/PermDAO.java @@ -93,11 +93,31 @@ public class PermDAO extends CassDAOImpl<AuthzTrans,PermDAO.Data> { } public String fullType() { - return ns + '.' + type; + StringBuilder sb = new StringBuilder(); + if(ns==null) { + sb.append('.'); + } else { + sb.append(ns); + sb.append(ns.indexOf('@')<0?'.':':'); + } + sb.append(type); + return sb.toString(); } public String fullPerm() { - return ns + '.' + type + '|' + instance + '|' + action; + StringBuilder sb = new StringBuilder(); + if(ns==null) { + sb.append("null."); + } else { + sb.append(ns); + sb.append(ns.indexOf('@')<0?'.':':'); + } + sb.append(type); + sb.append('|'); + sb.append(instance); + sb.append('|'); + sb.append(action); + return sb.toString(); } public String encode() { @@ -193,17 +213,26 @@ public class PermDAO extends CassDAOImpl<AuthzTrans,PermDAO.Data> { Data rv = new PermDAO.Data(); if (rdns.isOKhasData()) { switch(s.length) { + case 4: + rv.ns=s[0]; + rv.type=s[1]; + rv.instance=s[2]; + rv.action=s[3]; + break; case 3: + rv.ns=s[0]; rv.type=s[1]; rv.instance=s[2]; rv.action=s[3]; break; case 2: + rv.ns=s[0]; rv.type=s[1]; rv.instance=s[2]; rv.action=STAR; break; default: + rv.ns=s[0]; rv.type=s[1]; rv.instance = STAR; rv.action = STAR; diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/RoleDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/RoleDAO.java index 127dd4e2..a5fa7a77 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/RoleDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/RoleDAO.java @@ -106,7 +106,15 @@ public class RoleDAO extends CassDAOImpl<AuthzTrans,RoleDAO.Data> { } public String fullName() { - return ns + '.' + name; + StringBuilder sb = new StringBuilder(); + if(ns==null) { + sb.append('.'); + } else { + sb.append(ns); + sb.append(ns.indexOf('@')<0?'.':':'); + } + sb.append(name); + return sb.toString(); } public String encode() { @@ -122,19 +130,29 @@ public class RoleDAO extends CassDAOImpl<AuthzTrans,RoleDAO.Data> { * @return */ public static Result<Data> decode(AuthzTrans trans, Question q, String r) { - String[] ss = Split.splitTrim('|', r,2); Data data = new Data(); - if (ss[1]==null) { // older 1 part encoding must be evaluated for NS - Result<NsSplit> nss = q.deriveNsSplit(trans, ss[0]); - if (nss.notOK()) { - return Result.err(nss); - } - data.ns=nss.value.ns; - data.name=nss.value.name; - } else { // new 4 part encoding - data.ns=ss[0]; - data.name=ss[1]; - } + if(r.indexOf('@')>=0) { + int colon = r.indexOf(':'); + if(colon<0) { + return Result.err(Result.ERR_BadData, "%s is not a valid Role",r); + } else { + data.ns=r.substring(0, colon); + data.name=r.substring(++colon); + } + } else { + String[] ss = Split.splitTrim('|', r,2); + if (ss[1]==null) { // older 1 part encoding must be evaluated for NS + Result<NsSplit> nss = q.deriveNsSplit(trans, ss[0]); + if (nss.notOK()) { + return Result.err(nss); + } + data.ns=nss.value.ns; + data.name=nss.value.name; + } else { // new 4 part encoding + data.ns=ss[0]; + data.name=ss[1]; + } + } return Result.ok(data); } diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java index 43e121ac..c59312c0 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java @@ -1060,8 +1060,8 @@ public class Function { } else if (!fullperm.roles.isEmpty()) { return Result .err(Status.ERR_DependencyExists, - "Permission [%s.%s|%s|%s] cannot be deleted as it is attached to 1 or more roles.", - fullperm.ns, fullperm.type, fullperm.instance, fullperm.action); + "Permission [%s] cannot be deleted as it is attached to 1 or more roles.", + fullperm.fullPerm()); } } diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java index 2c98a9bc..ae6f371b 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java @@ -187,6 +187,7 @@ public class Question { private final CacheInfoDAO cacheInfoDAO; private final int cldays; + private final boolean alwaysSpecial; public Question(AuthzTrans trans, Cluster cluster, String keyspace) throws APIException, IOException { PERMS = trans.slot("USER_PERMS"); @@ -220,6 +221,8 @@ public class Question { AbsCassDAO.primePSIs(trans); cldays = Integer.parseInt(trans.getProperty(Config.AAF_CRED_WARN_DAYS, Config.AAF_CRED_WARN_DAYS_DFT)); + + alwaysSpecial = Boolean.parseBoolean(trans.getProperty("aaf_always_special", Boolean.FALSE.toString())); } public void startTimers(AuthzEnv env) { @@ -322,13 +325,22 @@ public class Question { return permDAO.readByType(trans, nss.value.ns, nss.value.name); } - public Result<List<PermDAO.Data>> getPermsByName(AuthzTrans trans, - String type, String instance, String action) { - Result<NsSplit> nss = deriveNsSplit(trans, type); - if (nss.notOK()) { - return Result.err(nss); - } - return permDAO.read(trans, nss.value.ns, nss.value.name, instance,action); + public Result<List<PermDAO.Data>> getPermsByName(AuthzTrans trans, String type, String instance, String action) { + if(type.indexOf('@') >= 0) { + int colon = type.indexOf(':'); + if(colon>=0) { + return permDAO.read(trans, type.substring(0, colon),type.substring(colon+1), instance,action); + } else { + return Result.err(Result.ERR_BadData, "%s is malformed",type); + } + } else { + Result<NsSplit> nss = deriveNsSplit(trans, type); + if (nss.notOK()) { + return Result.err(nss); + } + + return permDAO.read(trans, nss.value.ns, nss.value.name, instance,action); + } } public Result<List<PermDAO.Data>> getPermsByRole(AuthzTrans trans, String role, boolean lookup) { @@ -374,8 +386,14 @@ public class Question { return Result.ok(perms); } - public Result<List<RoleDAO.Data>> getRolesByName(AuthzTrans trans, - String role) { + public Result<List<RoleDAO.Data>> getRolesByName(AuthzTrans trans, String role) { + if(role.startsWith(trans.user()) ) { + if(role.endsWith(":user")) { + return roleDAO.read(trans,trans.user(), "user"); + } else { + return Result.err(Result.ERR_BadData,"%s is a badly formatted role",role); + } + } Result<NsSplit> nss = deriveNsSplit(trans, role); if (nss.notOK()) { return Result.err(nss); @@ -412,12 +430,7 @@ public class Question { if (r.isOKhasData()) { return Result.ok(r.value.get(0)); } else { - int dot; - if (child==null) { - return Result.err(Status.ERR_NsNotFound, "No Namespace"); - } else { - dot = child.lastIndexOf('.'); - } + int dot = child.lastIndexOf('.'); if (dot < 0) { return Result.err(Status.ERR_NsNotFound, "No Namespace for [%s]", child); } else { @@ -558,6 +571,9 @@ public class Question { } public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user, RoleDAO.Data rdd, Access access) { + if(trans.user().equals(rdd.ns)) { + return Result.ok((NsDAO.Data)null); + } Result<NsDAO.Data> rnsd = deriveNs(trans, rdd.ns); if (rnsd.isOK()) { return mayUser(trans, user, rnsd.value, rdd, access); @@ -612,6 +628,17 @@ public class Question { } public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user,PermDAO.Data pdd, Access access) { + if(pdd.ns.indexOf('@')>-1) { + if(user.equals(pdd.ns) || isGranted(trans,user,Define.ROOT_NS(),"access",pdd.instance,READ)) { + NsDAO.Data ndd = new NsDAO.Data(); + ndd.name = user; + ndd.type = NsDAO.USER; + ndd.parent = ""; + return Result.ok(ndd); + } else { + return Result.err(Result.ERR_Security,"Only a User may modify User"); + } + } Result<NsDAO.Data> rnsd = deriveNs(trans, pdd.ns); if (rnsd.isOK()) { return mayUser(trans, user, rnsd.value, pdd, access); @@ -831,6 +858,7 @@ public class Question { byte[] md5=Hash.hashMD5(cred); if (Hash.compareTo(md5,dbcred)==0) { checkLessThanDays(trans,cldays,now,cdd); + trans.setTag(cdd.tag); return Result.ok(cdd.expires); } else if (debug!=null) { load(debug, cdd); @@ -844,6 +872,7 @@ public class Question { if (Hash.compareTo(hash,dbcred)==0) { checkLessThanDays(trans,cldays,now,cdd); + trans.setTag(cdd.tag); return Result.ok(cdd.expires); } else if (debug!=null) { load(debug, cdd); @@ -858,34 +887,41 @@ public class Question { } else { if (expired==null || expired.before(cdd.expires)) { expired = cdd.expires; + trans.setTag(cdd.tag); } } } // end for each - if (debug==null) { - trans.audit().printf("No cred matches ip=%s, user=%s\n",trans.ip(),user); - } else { - trans.audit().printf("No cred matches ip=%s, user=%s %s\n",trans.ip(),user,debug.toString()); - } + if (expired!=null) { // Note: this is only returned if there are no good Credentials rv = Result.err(Status.ERR_Security, - "Credentials %s from %s expired %s",trans.user(), trans.ip(), Chrono.dateTime(expired)); + "Credentials expired %s",Chrono.utcStamp(expired)); + } else { + if (debug==null && alwaysSpecial) { + debug = new StringBuilder(); + } + if (debug!=null) { + debug.append(trans.env().encryptor().encrypt(new String(cred))); + rv = Result.err(Status.ERR_Security,String.format("invalid password - %s",debug.toString())); + } } } } else { return Result.err(result); } - return rv == null ? Result.create((Date) null, Status.ERR_Security, "Wrong credential") : rv; + return rv == null ? Result.err(Status.ERR_Security, "Wrong credential") : rv; } private void load(StringBuilder debug, Data cdd) { - debug.append("DB Entry: user="); + debug.append("\nDB Entry: user="); debug.append(cdd.id); debug.append(",type="); debug.append(cdd.type); debug.append(",expires="); debug.append(Chrono.dateTime(cdd.expires)); + debug.append(",tag="); + debug.append(cdd.tag); debug.append('\n'); } diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectAAFLocator.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectAAFLocator.java index 98459672..2f1d150c 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectAAFLocator.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectAAFLocator.java @@ -73,9 +73,11 @@ public class DirectAAFLocator extends AbsAAFLocator<AuthzTrans> { } try { - String aaf_url = access.getProperty(Config.AAF_URL, null); - if(aaf_url==null) { - aaf_url = "https://"+Config.AAF_LOCATE_URL_TAG+"/%NS."+name; + String aaf_url; + if(name.indexOf('.')>=0) { + aaf_url = "https://"+Config.AAF_LOCATE_URL_TAG+'/'+name+':'+version; + } else { + aaf_url = "https://"+Config.AAF_LOCATE_URL_TAG+"/%NS."+name+':'+version; } RegistrationPropHolder rph = new RegistrationPropHolder(access,0); aaf_url = rph.replacements(getClass().getSimpleName(),aaf_url, null,null); diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectAAFUserPass.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectAAFUserPass.java index 3ef532b4..3c7d873e 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectAAFUserPass.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectAAFUserPass.java @@ -52,28 +52,37 @@ public class DirectAAFUserPass implements CredVal { @Override public boolean validate(String user, Type type, byte[] pass, Object state) { + if(user==null || type==null || pass==null) { + return false; + } + try { AuthzTrans trans; + boolean transfer = false; if (state !=null) { if (state instanceof AuthzTrans) { trans = (AuthzTrans)state; } else { trans = env.newTransNoAvg(); if (state instanceof HttpServletRequest) { - trans.set((HttpServletRequest)state); + trans.set((HttpServletRequest)state,null); + transfer=true; } } } else { trans = env.newTransNoAvg(); } Result<Date> result = question.doesUserCredMatch(trans, user, pass); - trans.logAuditTrail(env.info()); + if(transfer) { + ((HttpServletRequest)state).setAttribute("CRED_TAG", trans.getTag()); + } + trans.logAuditTrail(env.debug()); switch(result.status) { case OK: return true; default: - String ip = trans.ip()==null?"":(", ip="+trans.ip()); - env.warn().log(user, "failed password validation" + ip + ':',result.errorString()); + String ip = trans.ip()==null?"":trans.ip(); + env.audit().printf("user=%s,tag=%s,ip=%s,msg=\"failed password validation: %s\"",user,trans.getTag(),ip,result.errorString()); } } catch (DAOException e) { env.error().log(e,"Cannot validate user/pass from cassandra"); diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectRegistrar.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectRegistrar.java index ec5449df..99421097 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectRegistrar.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectRegistrar.java @@ -49,7 +49,7 @@ public class DirectRegistrar implements Registrant<AuthzEnv> { ldd.add(convert(me)); } } - + private LocateDAO.Data convert(MgmtEndpoint me) { LocateDAO.Data out = new LocateDAO.Data(); out.name=me.getName(); diff --git a/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/aaf/test/AbsJUCass.java b/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/aaf/test/AbsJUCass.java index dea2ccdd..bb0fcd43 100644 --- a/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/aaf/test/AbsJUCass.java +++ b/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/aaf/test/AbsJUCass.java @@ -104,9 +104,6 @@ public class AbsJUCass { // Load special data here - // WebPhone - env.setProperty("java.naming.provider.url","ldap://ldap.webphone.att.com:389"); - env.setProperty("com.sun.jndi.ldap.connect.pool","true"); iterations = 0; diff --git a/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/cass/JU_RoleDAO.java b/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/cass/JU_RoleDAO.java index 16f05aa3..fa023af3 100644 --- a/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/cass/JU_RoleDAO.java +++ b/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/cass/JU_RoleDAO.java @@ -430,7 +430,7 @@ public class JU_RoleDAO { } @Test - public void testWasMOdified() { + public void testWasModified() { TimeTaken tt = Mockito.mock(TimeTaken.class); Mockito.doReturn(tt).when(trans).start("RoleDAO CREATE", Env.REMOTE); Mockito.doReturn(tt).when(trans).start("Clear Reset Deque", Env.SUB); diff --git a/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFLur.java b/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFLur.java index 05077438..f0f3c5d0 100644 --- a/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFLur.java +++ b/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFLur.java @@ -237,7 +237,7 @@ public class JU_DirectAAFLur { assertFalse(pp.match(null)); - pond = new AAFPermission("null.test", "name", "instance", "action"); - pp.match(pond); + pond = new AAFPermission("test.test", "test", "test", "test"); + assertTrue(pp.match(pond)); } } diff --git a/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFUserPass.java b/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFUserPass.java index ca0a8917..c767aeb5 100644 --- a/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFUserPass.java +++ b/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFUserPass.java @@ -125,7 +125,7 @@ public class JU_DirectAAFUserPass { } boolean retVal = aafLocatorObj.validate(null, null, null, null); - assertTrue(retVal); + assertFalse(retVal); } @Test |