X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=auth%2Fauth-service%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fauth%2Fservice%2FAuthzCassServiceImpl.java;h=d102b04562de9064bf62b1a25c5e3a3b1bf9d0f5;hb=1c887acbb462552aa6478e72c1bf3cf0f145e74d;hp=67bf3b5016c5a1b3033262b3d5094b5a6cd8507c;hpb=eb9165705a614af7b98ee6b643f871eab1284976;p=aaf%2Fauthz.git diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java index 67bf3b50..d102b045 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java @@ -33,7 +33,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; @@ -43,11 +42,15 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.UUID; +import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; import org.onap.aaf.auth.common.Define; import org.onap.aaf.auth.dao.DAOException; +import org.onap.aaf.auth.dao.cached.CachedPermDAO; +import org.onap.aaf.auth.dao.cached.CachedRoleDAO; +import org.onap.aaf.auth.dao.cached.CachedUserRoleDAO; import org.onap.aaf.auth.dao.cass.ApprovalDAO; import org.onap.aaf.auth.dao.cass.CertDAO; import org.onap.aaf.auth.dao.cass.CredDAO; @@ -68,9 +71,11 @@ import org.onap.aaf.auth.dao.hl.Function; import org.onap.aaf.auth.dao.hl.Function.FUTURE_OP; import org.onap.aaf.auth.dao.hl.Function.Lookup; import org.onap.aaf.auth.dao.hl.Function.OP_STATUS; +import org.onap.aaf.auth.dao.hl.PermLookup; import org.onap.aaf.auth.dao.hl.Question; import org.onap.aaf.auth.dao.hl.Question.Access; import org.onap.aaf.auth.env.AuthzTrans; +import org.onap.aaf.auth.env.AuthzTrans.REQD_TYPE; import org.onap.aaf.auth.layer.Result; import org.onap.aaf.auth.org.Executor; import org.onap.aaf.auth.org.Organization; @@ -83,7 +88,9 @@ import org.onap.aaf.auth.service.mapper.Mapper; import org.onap.aaf.auth.service.mapper.Mapper.API; import org.onap.aaf.auth.service.validation.ServiceValidator; import org.onap.aaf.auth.validation.Validator; +import org.onap.aaf.cadi.aaf.Defaults; import org.onap.aaf.cadi.principal.BasicPrincipal; +import org.onap.aaf.cadi.util.FQI; import org.onap.aaf.misc.env.Env; import org.onap.aaf.misc.env.TimeTaken; import org.onap.aaf.misc.env.util.Chrono; @@ -110,7 +117,8 @@ import aaf.v2_0.CredRequest; public class AuthzCassServiceImpl implements AuthzService { - private Mapper mapper; + private static final String TWO_SPACE = " "; + private Mapper mapper; @Override public Mapper mapper() {return mapper;} @@ -169,6 +177,7 @@ public class AuthzCassServiceImpl > rlnsd = ques.nsDAO.read(trans, ns); + Result> rlnsd = ques.nsDAO().read(trans, ns); if (rlnsd.notOKorIsEmpty()) { return Result.err(rlnsd); } @@ -319,7 +328,8 @@ public class AuthzCassServiceImpl > rsd = ques.nsDAO.dao().readNsByAttrib(trans, key); + Result> rsd = ques.nsDAO().dao().readNsByAttrib(trans, key); if (rsd.notOK()) { return Result.err(rsd); } @@ -383,7 +393,7 @@ public class AuthzCassServiceImpl > rlnsd = ques.nsDAO.read(trans, ns); + Result> rlnsd = ques.nsDAO().read(trans, ns); if (rlnsd.notOKorIsEmpty()) { return Result.err(rlnsd); } @@ -402,8 +412,8 @@ public class AuthzCassServiceImpl > rlnsd = ques.nsDAO.read(trans, ns); + Result> rlnsd = ques.nsDAO().read(trans, ns); if (rlnsd.notOKorIsEmpty()) { return Result.err(rlnsd); } @@ -452,7 +462,8 @@ public class AuthzCassServiceImpl getNSbyName(AuthzTrans trans, String ns) { + public Result getNSbyName(AuthzTrans trans, String ns, boolean includeExpired) { final Validator v = new ServiceValidator(); if (v.nullOrBlank("NS", ns).err()) { return Result.err(Status.ERR_BadData,v.errs()); } - Result> rlnd = ques.nsDAO.read(trans, ns); + Result> rlnd = ques.nsDAO().read(trans, ns); if (rlnd.isOK()) { if (rlnd.isEmpty()) { return Result.err(Status.ERR_NotFound, "No data found for %s",ns); @@ -489,11 +499,11 @@ public class AuthzCassServiceImpl > rd = func.getOwners(trans, namespace.name, false); + Result> rd = func.getOwners(trans, namespace.name, includeExpired); if (rd.isOK()) { namespace.owner = rd.value; } - rd = func.getAdmins(trans, namespace.name, false); + rd = func.getAdmins(trans, namespace.name, includeExpired); if (rd.isOK()) { namespace.admin = rd.value; } @@ -564,7 +574,7 @@ public class AuthzCassServiceImpl > loadNamepace(AuthzTrans trans, String user, String endsWith, boolean full) { - Result> urd = ques.userRoleDAO.readByUser(trans, user); + Result> urd = ques.userRoleDAO().readByUser(trans, user); if (urd.notOKorIsEmpty()) { return Result.err(urd); } @@ -680,7 +690,7 @@ public class AuthzCassServiceImpl lm = new HashSet<>(); - Result> rlnd = ques.nsDAO.dao().getChildren(trans, parent); + Result> rlnd = ques.nsDAO().dao().getChildren(trans, parent); if (rlnd.isOK()) { if (rlnd.isEmpty()) { return Result.err(Status.ERR_NotFound, "No data found for %s",parent); @@ -728,7 +738,7 @@ public class AuthzCassServiceImpl > rlnd = ques.nsDAO.read(trans, namespace.name); + Result> rlnd = ques.nsDAO().read(trans, namespace.name); if (rlnd.notOKorIsEmpty()) { return Result.err(Status.ERR_NotFound, "Namespace [%s] does not exist",namespace.name); @@ -738,7 +748,7 @@ public class AuthzCassServiceImpl rdr = ques.nsDAO.dao().addDescription(trans, namespace.name, namespace.description); + Result rdr = ques.nsDAO().dao().addDescription(trans, namespace.name, namespace.description); if (rdr.isOK()) { return Result.ok(); } else { @@ -798,56 +808,129 @@ public class AuthzCassServiceImpl createPerm(final AuthzTrans trans,REQUEST rreq) { final Result newPd = mapper.perm(trans, rreq); + final ServiceValidator v = new ServiceValidator(); if (v.perm(newPd).err()) { return Result.err(Status.ERR_BadData,v.errs()); } - - Result fd = mapper.future(trans, PermDAO.TABLE, rreq, newPd.value,false, - new Mapper.Memo() { - @Override - public String get() { - return "Create Permission [" + - newPd.value.fullType() + '|' + - newPd.value.instance + '|' + - newPd.value.action + ']'; - } - }, - new MayChange() { - private Result nsd; - @Override - public Result mayChange() { - if (nsd==null) { - nsd = ques.mayUser(trans, trans.user(), newPd.value, Access.write); - } - return nsd; - } - }); - Result> nsr = ques.nsDAO.read(trans, newPd.value.ns); - if (nsr.notOKorIsEmpty()) { - return Result.err(nsr); + + // User Permission mechanism + if(newPd.value.ns.indexOf('@')>0) { + PermDAO.Data pdd = newPd.value; + if(trans.user().equals(newPd.value.ns)) { + CachedPermDAO permDAO = ques.permDAO(); + Result> rlpdd = permDAO.read(trans, pdd); + if(rlpdd.notOK()) { + return Result.err(rlpdd); + } + if(!rlpdd.isEmpty()) { + return Result.err(Result.ERR_ConflictAlreadyExists,"Permission already exists"); + } + + RoleDAO.Data rdd = new RoleDAO.Data(); + rdd.ns = pdd.ns; + rdd.name = "user"; + + pdd.roles(true).add(rdd.fullName()); + Result rpdd = permDAO.create(trans, pdd); + if(rpdd.notOK()) { + return Result.err(rpdd); + } + + CachedRoleDAO roleDAO = ques.roleDAO(); + Result> rlrdd = roleDAO.read(trans, rdd); + if(rlrdd.notOK()) { + return Result.err(rlrdd); + } else { + if(!rlrdd.isEmpty()) { + rdd = rlrdd.value.get(0); + } + } + + String eperm = pdd.encode(); + rdd.perms(true).add(eperm); + Result rv = roleDAO.update(trans, rdd); + if(rv.notOK()) { + return rv; + } + + CachedUserRoleDAO urDAO = ques.userRoleDAO(); + UserRoleDAO.Data urdd = new UserRoleDAO.Data(); + urdd.user = trans.user(); + urdd.ns = rdd.ns; + urdd.rname = rdd.name; + urdd.role = rdd.fullName(); + Result> rlurdd = urDAO.read(trans, urdd); + if(rlurdd.notOK()) { + return Result.err(rlrdd); + } else if(rlurdd.isEmpty()) { + GregorianCalendar gc = trans.org().expiration(null, Expiration.UserInRole); + if(gc==null) { + return Result.err(Result.ERR_Policy,"Organzation does not grant Expiration for UserRole"); + } else { + urdd.expires = gc.getTime(); + } + Result rurdd = urDAO.create(trans, urdd); + return Result.err(rurdd); + } + return rv; + } else { + return Result.err(Result.ERR_Security,"Only the User can create User Permissions"); + } + } else { + // Does Perm Type exist as a Namespace? + if(newPd.value.type.isEmpty() || ques.nsDAO().read(trans, newPd.value.fullType()).isOKhasData()) { + return Result.err(Status.ERR_ConflictAlreadyExists, + "Permission Type exists as a Namespace"); + } + + Result fd = mapper.future(trans, PermDAO.TABLE, rreq, newPd.value,false, + new Mapper.Memo() { + @Override + public String get() { + return "Create Permission [" + + newPd.value.fullType() + '|' + + newPd.value.instance + '|' + + newPd.value.action + ']'; + } + }, + new MayChange() { + private Result nsd; + @Override + public Result mayChange() { + if (nsd==null) { + nsd = ques.mayUser(trans, trans.user(), newPd.value, Access.write); + } + return nsd; + } + }); + + Result> nsr = ques.nsDAO().read(trans, newPd.value.ns); + if (nsr.notOKorIsEmpty()) { + return Result.err(nsr); + } + switch(fd.status) { + case OK: + Result rfc = func.createFuture(trans,fd.value, + newPd.value.fullType() + '|' + newPd.value.instance + '|' + newPd.value.action, + trans.user(), + nsr.value.get(0), + FUTURE_OP.C); + if (rfc.isOK()) { + return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing", + newPd.value.ns, + newPd.value.type, + newPd.value.instance, + newPd.value.action); + } else { + return Result.err(rfc); + } + case Status.ACC_Now: + return func.createPerm(trans, newPd.value, true); + default: + return Result.err(fd); + } } - switch(fd.status) { - case OK: - Result rfc = func.createFuture(trans,fd.value, - newPd.value.fullType() + '|' + newPd.value.instance + '|' + newPd.value.action, - trans.user(), - nsr.value.get(0), - FUTURE_OP.C); - if (rfc.isOK()) { - return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing", - newPd.value.ns, - newPd.value.type, - newPd.value.instance, - newPd.value.action); - } else { - return Result.err(rfc); - } - case Status.ACC_Now: - return func.createPerm(trans, newPd.value, true); - default: - return Result.err(fd); - } } @ApiDoc( @@ -930,8 +1013,8 @@ public class AuthzCassServiceImpl > rlpd = ques.getPermsByUser(trans, user, - trans.requested(force)); + PermLookup pl = PermLookup.get(trans,ques,user); + Result> rlpd = pl.getPerms(trans.requested(force)); if (rlpd.notOK()) { return Result.err(rlpd); } @@ -1019,7 +1102,8 @@ public class AuthzCassServiceImpl > rlpd = ques.getPermsByUser(trans, user,trans.requested(force)); + PermLookup pl = PermLookup.get(trans,ques,user); + Result> rlpd = pl.getPerms(trans.requested(force)); if (rlpd.notOK()) { return Result.err(rlpd); } @@ -1139,7 +1223,7 @@ public class AuthzCassServiceImpl > rlpd = ques.permDAO.readNS(trans, ns); + Result> rlpd = ques.permDAO().readNS(trans, ns); if (rlpd.notOK()) { return Result.err(rlpd); } @@ -1177,7 +1261,7 @@ public class AuthzCassServiceImpl nss = ques.deriveNsSplit(trans, origType); - Result> origRlpd = ques.permDAO.read(trans, nss.value.ns, nss.value.name, origInstance, origAction); + Result> origRlpd = ques.permDAO().read(trans, nss.value.ns, nss.value.name, origInstance, origAction); if (origRlpd.notOKorIsEmpty()) { return Result.err(Status.ERR_PermissionNotFound, @@ -1236,7 +1320,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, pd.value.ns); + Result> nsr = ques.nsDAO().read(trans, pd.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } - Result rdr = ques.permDAO.addDescription(trans, perm.ns, perm.type, perm.instance, + Result rdr = ques.permDAO().addDescription(trans, perm.ns, perm.type, perm.instance, perm.action, perm.description); if (rdr.isOK()) { return Result.ok(); @@ -1288,7 +1372,7 @@ public class AuthzCassServiceImpl > rcurr = ques.permDAO.read(trans, + Result> rcurr = ques.permDAO().read(trans, updt.value.ns, updt.value.type, updt.value.instance, @@ -1322,7 +1406,7 @@ public class AuthzCassServiceImpl key = RoleDAO.Data.decode(trans, ques, role); if (key.isOKhasData()) { - Result> rrd = ques.roleDAO.read(trans, key.value); + Result> rrd = ques.roleDAO().read(trans, key.value); if (rrd.isOKhasData()) { for (RoleDAO.Data r : rrd.value) { rv = func.addPermToRole(trans, r, curr, false); @@ -1342,7 +1426,7 @@ public class AuthzCassServiceImpl key = RoleDAO.Data.decode(trans, ques, role); if (key.isOKhasData()) { - Result> rdd = ques.roleDAO.read(trans, key.value); + Result> rdd = ques.roleDAO().read(trans, key.value); if (rdd.isOKhasData()) { for (RoleDAO.Data r : rdd.value) { rv = func.delPermFromRole(trans, r, curr, true); @@ -1381,11 +1465,11 @@ public class AuthzCassServiceImpl fd = mapper.future(trans,PermDAO.TABLE,from,perm,false, new Mapper.Memo() { @Override @@ -1406,7 +1490,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, perm.ns); + Result> nsr = ques.nsDAO().read(trans, perm.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -1484,12 +1568,17 @@ public class AuthzCassServiceImpl createRole(final AuthzTrans trans, REQUEST from) { final Result rd = mapper.role(trans, from); + // Does Perm Type exist as a Namespace? + if(rd.value.name.isEmpty() || ques.nsDAO().read(trans, rd.value.fullName()).isOKhasData()) { + return Result.err(Status.ERR_ConflictAlreadyExists, + "Role exists as a Namespace"); + } final ServiceValidator v = new ServiceValidator(); if (v.role(rd).err()) { return Result.err(Status.ERR_BadData,v.errs()); } final RoleDAO.Data role = rd.value; - if (ques.roleDAO.read(trans, role.ns, role.name).isOKhasData()) { + if (ques.roleDAO().read(trans, role.ns, role.name).isOKhasData()) { return Result.err(Status.ERR_ConflictAlreadyExists, "Role [" + role.fullName() + "] already exists"); } @@ -1513,7 +1602,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, rd.value.ns); + Result> nsr = ques.nsDAO().read(trans, rd.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -1530,7 +1619,7 @@ public class AuthzCassServiceImpl rdr = ques.roleDAO.create(trans, role); + Result rdr = ques.roleDAO().create(trans, role); if (rdr.isOK()) { return Result.ok(); } else { @@ -1609,10 +1698,10 @@ public class AuthzCassServiceImpl > rlrd; - Result> rlurd = ques.userRoleDAO.readByUser(trans, user); + Result> rlurd = ques.userRoleDAO().readByUser(trans, user); if (rlurd.isOKhasData()) { for (UserRoleDAO.Data urd : rlurd.value ) { - rlrd = ques.roleDAO.read(trans, urd.ns,urd.rname); + rlrd = ques.roleDAO().read(trans, urd.ns,urd.rname); // Note: Mapper will restrict what can be viewed // if user is the same as that which is looked up, no filtering is required if (rlrd.isOKhasData()) { @@ -1659,7 +1748,7 @@ public class AuthzCassServiceImpl > rlrd = ques.roleDAO.readNS(trans, ns); + Result> rlrd = ques.roleDAO().readNS(trans, ns); if (rlrd.isOK()) { if (!rlrd.isEmpty()) { // Note: Mapper doesn't need to restrict what can be viewed, because we did it already. @@ -1701,7 +1790,7 @@ public class AuthzCassServiceImpl > rlrd = ques.roleDAO.readName(trans, name); + Result> rlrd = ques.roleDAO().readName(trans, name); if (rlrd.isOK()) { if (!rlrd.isEmpty()) { // Note: Mapper will restrict what can be viewed @@ -1758,13 +1847,13 @@ public class AuthzCassServiceImpl > pdlr = ques.permDAO.read(trans, pdd); + Result> pdlr = ques.permDAO().read(trans, pdd); if (pdlr.isOK())for (PermDAO.Data pd : pdlr.value) { Result> rlrd; for (String r : pd.roles) { Result rs = RoleDAO.Data.decodeToArray(trans, ques, r); if (rs.isOK()) { - rlrd = ques.roleDAO.read(trans, rs.value[0],rs.value[1]); + rlrd = ques.roleDAO().read(trans, rs.value[0],rs.value[1]); // Note: Mapper will restrict what can be viewed if (rlrd.isOKhasData()) { mapper.roles(trans,rlrd.value,roles,true); @@ -1800,7 +1889,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, rd.value.ns); + Result> nsr = ques.nsDAO().read(trans, rd.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } - Result rdr = ques.roleDAO.addDescription(trans, role.ns, role.name, role.description); + Result rdr = ques.roleDAO().addDescription(trans, role.ns, role.name, role.description); if (rdr.isOK()) { return Result.ok(); } else { @@ -1862,13 +1951,13 @@ public class AuthzCassServiceImpl > rlrd = ques.roleDAO.read(trans, rrd.value.ns, rrd.value.name); + Result> rlrd = ques.roleDAO().read(trans, rrd.value.ns, rrd.value.name); if (rlrd.notOKorIsEmpty()) { return Result.err(Status.ERR_RoleNotFound, "Role [%s] does not exist", rrd.value.fullName()); } // Check Status of Data in DB (does it exist) - Result> rlpd = ques.permDAO.read(trans, rpd.value.ns, + Result> rlpd = ques.permDAO().read(trans, rpd.value.ns, rpd.value.type, rpd.value.instance, rpd.value.action); PermDAO.Data createPerm = null; // if not null, create first if (rlpd.notOKorIsEmpty()) { // Permission doesn't exist @@ -1905,41 +1994,44 @@ public class AuthzCassServiceImpl mayChange() { if (nsd==null) { nsd = ques.mayUser(trans, trans.user(), rpd.value, Access.write); + if(nsd.notOK()) { + trans.requested(REQD_TYPE.future,true); + } } return nsd; } }); - Result> nsr = ques.nsDAO.read(trans, rpd.value.ns); + Result> nsr = ques.nsDAO().read(trans, rpd.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } switch(fd.status) { - case OK: - Result rfc = func.createFuture(trans,fd.value, - rpd.value.fullPerm(), - trans.user(), - nsr.value.get(0), - FUTURE_OP.G); - if (rfc.isOK()) { - return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing", - rpd.value.ns, - rpd.value.type, - rpd.value.instance, - rpd.value.action); - } else { - return Result.err(rfc); - } - case Status.ACC_Now: - Result rv = null; - if (createPerm!=null) {// has been validated for creating - rv = func.createPerm(trans, createPerm, false); - } - if (rv==null || rv.isOK()) { - rv = func.addPermToRole(trans, rrd.value, rpd.value, false); - } - return rv; - default: - return Result.err(fd); + case OK: + Result rfc = func.createFuture(trans,fd.value, + rpd.value.fullPerm(), + trans.user(), + nsr.value.get(0), + FUTURE_OP.G); + if (rfc.isOK()) { + return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing", + rpd.value.ns, + rpd.value.type, + rpd.value.instance, + rpd.value.action); + } else { + return Result.err(rfc); + } + case Status.ACC_Now: + Result rv = null; + if (createPerm!=null) {// has been validated for creating + rv = func.createPerm(trans, createPerm, false); + } + if (rv==null || rv.isOK()) { + rv = func.addPermToRole(trans, rrd.value, rpd.value, false); + } + return rv; + default: + return Result.err(fd); } } @@ -1981,7 +2073,7 @@ public class AuthzCassServiceImpl delPermFromRole(final AuthzTrans trans, PermDAO.Data pdd, RoleDAO.Data rdd, REQUEST rreq) { - Result> rlpd = ques.permDAO.read(trans, pdd.ns, pdd.type, + Result> rlpd = ques.permDAO().read(trans, pdd.ns, pdd.type, pdd.instance, pdd.action); if (rlpd.notOKorIsEmpty()) { @@ -2008,7 +2100,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, pdd.ns); + Result> nsr = ques.nsDAO().read(trans, pdd.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -2071,12 +2163,12 @@ public class AuthzCassServiceImpl > rrd = ques.roleDAO.read(trans, rrns.value.parent, rrns.value.name); + final Result> rrd = ques.roleDAO().read(trans, rrns.value.parent, rrns.value.name); if (rrd.notOKorIsEmpty()) { return Result.err(rrd); } - final Result> rpd = ques.permDAO.read(trans, rpns.value.parent, rpns.value.name, instance, action); + final Result> rpd = ques.permDAO().read(trans, rpns.value.parent, rpns.value.name, instance, action); if (rpd.notOKorIsEmpty()) { return Result.err(rpd); } @@ -2132,7 +2224,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, rd.value.ns); + Result> nsr = ques.nsDAO().read(trans, rd.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -2217,40 +2309,59 @@ public class AuthzCassServiceImpl nsd; + private static final String EXTEND = "extend"; + private static final String RESET = "reset"; + private static final String DELETE = "delete"; + private Result nsd; private AuthzTrans trans; private CredDAO.Data cred; - public MayChangeCred(AuthzTrans trans, CredDAO.Data cred) { + private String action; + public MayChangeCred(AuthzTrans trans, CredDAO.Data cred, String action) { this.trans = trans; this.cred = cred; + this.action = action; } @Override public Result mayChange() { // User can change himself (but not create) - if (trans.user().equals(cred.id)) { - return Result.ok(); - } if (nsd==null) { nsd = ques.validNSOfDomain(trans, cred.id); } // Get the Namespace if (nsd.isOK()) { - if (ques.mayUser(trans, trans.user(), nsd.value,Access.write).isOK()) { - return Result.ok(); - } - String user[] = Split.split('.',trans.user()); - if (user.length>2) { - String company = user[user.length-1] + '.' + user[user.length-2]; - if (ques.isGranted(trans, trans.user(), ROOT_NS,"password",company,"reset")) { - return Result.ok(); - } - } + String ns = nsd.value.name; + String user = trans.user(); + String company; + String temp[] = Split.split('.',ns); + switch(temp.length) { + case 0: + company = Defaults.AAF_NS; + break; + case 1: + company = temp[0]; + break; + default: + company = temp[0] + '.' + temp[1]; + } + switch(action) { + case DELETE: + if(ques.isOwner(trans, user,ns) || + ques.isAdmin(trans, user,ns) || + ques.isGranted(trans, user, ROOT_NS,"password",company,DELETE)) { + return Result.ok(); + } + break; + case RESET: + case EXTEND: + if (ques.isGranted(trans, trans.user(), ROOT_NS,"password",company,action)) { + return Result.ok(); + } + break; + } } - return Result.err(Status.ERR_Denied,"%s is not allowed to change %s in %s",trans.user(),cred.id,cred.ns); + return Result.err(Status.ERR_Denied,"%s is not allowed to %s %s in %s",trans.user(),action,cred.id,cred.ns); } - } private final long DAY_IN_MILLIS = 24*3600*1000L; @@ -2278,7 +2389,6 @@ public class AuthzCassServiceImpl rcred = mapper.cred(trans, from, true); if (rcred.isOKhasData()) { - byte[] rawCred = rcred.value.cred.array(); rcred = ques.userCredSetup(trans, rcred.value); final ServiceValidator v = new ServiceValidator(); @@ -2300,7 +2410,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, rcred.value.ns); + Result> nsr = ques.nsDAO().read(trans, rcred.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(Status.ERR_NsNotFound,"Cannot provision %s on non-existent Namespace %s",mechID.id(),rcred.value.ns); } @@ -2310,7 +2420,7 @@ public class AuthzCassServiceImpl > rlcd = ques.credDAO.readID(trans, rcred.value.id); + Result> rlcd = ques.credDAO().readID(trans, rcred.value.id); if (rlcd.isOKhasData()) { if (!org.canHaveMultipleCreds(rcred.value.id)) { return Result.err(Status.ERR_ConflictAlreadyExists, "Credential exists"); @@ -2321,14 +2431,28 @@ public class AuthzCassServiceImpl TimeUnit.DAYS.toMillis(1)) { + return Result.err(Status.ERR_ConflictAlreadyExists, "Credential with same Expiration Date exists"); + } + } + } } } else { try { @@ -2336,7 +2460,7 @@ public class AuthzCassServiceImpl > admins = func.getAdmins(trans, nsr.value.get(0).name, false); - // OK, it's a first ID, and not by NS Admin, so let's set TempPassword length - // Note, we only do this on First time, because of possibility of - // prematurely expiring a production id - if (admins.isOKhasData() && !admins.value.contains(trans.user())) { - rcred.value.expires = org.expiration(null, Expiration.TempPassword).getTime(); + // OK, it's a first ID, and not by NS Owner + if(!ques.isOwner(trans,trans.user(),cdd.ns)) { + // Admins are not allowed to set first Cred, but Org has already + // said entity MAY create, typically by Permission + // We can't know which reason they are allowed here, so we + // have to assume that any with Special Permission would not be + // an Admin. + if(ques.isAdmin(trans, trans.user(), cdd.ns)) { + return Result.err(Result.ERR_Denied, + "Only Owners may create first passwords in their Namespace. Admins may modify after one exists" ); + } else { + // Allow IDs that AREN'T part of NS with Org Onboarding Permission (see Org object) to create Temp Passwords. + rcred.value.expires = org.expiration(null, Expiration.TempPassword).getTime(); + } } } } catch (Exception e) { trans.error().log(e, "While setting expiration to TempPassword"); } - Resultudr = ques.credDAO.create(trans, rcred.value); + + Resultudr = ques.credDAO().create(trans, rcred.value); if (udr.isOK()) { return Result.ok(); } @@ -2442,7 +2574,7 @@ public class AuthzCassServiceImpl > rlcd = ques.credDAO.readNS(trans, ns); + Result> rlcd = ques.credDAO().readNS(trans, ns); if (rlcd.isOK()) { if (!rlcd.isEmpty()) { @@ -2489,7 +2621,7 @@ public class AuthzCassServiceImpl > rlcd = ques.credDAO.readID(trans, id); + Result> rlcd = ques.credDAO().readID(trans, id); if (rlcd.isOK()) { if (!rlcd.isEmpty()) { @@ -2519,7 +2651,7 @@ public class AuthzCassServiceImpl > rlcd = ques.certDAO.readID(trans, id); + Result> rlcd = ques.certDAO().readID(trans, id); if (rlcd.isOK()) { if (!rlcd.isEmpty()) { @@ -2547,7 +2679,7 @@ public class AuthzCassServiceImpl changeUserCred(final AuthzTrans trans, REQUEST from) { + public Result resetUserCred(final AuthzTrans trans, REQUEST from) { final String cmdDescription = "Update User Credential"; TimeTaken tt = trans.start(cmdDescription, Env.SUB); try { @@ -2560,18 +2692,20 @@ public class AuthzCassServiceImpl > rlcd = ques.credDAO.readID(trans, rcred.value.id); + Result> rlcd = ques.credDAO().readID(trans, rcred.value.id); if (rlcd.notOKorIsEmpty()) { return Result.err(Status.ERR_UserNotFound, "Credential does not exist"); } - MayChange mc = new MayChangeCred(trans, rcred.value); + MayChange mc = new MayChangeCred(trans, rcred.value,MayChangeCred.RESET); Result rmc = mc.mayChange(); if (rmc.notOK()) { return Result.err(rmc); } - Result ri = selectEntryIfMultiple((CredRequest)from, rlcd.value); + List lcdd = filterList(rlcd.value,CredDAO.BASIC_AUTH, CredDAO.BASIC_AUTH_SHA256); + + Result ri = selectEntryIfMultiple((CredRequest)from, lcdd, MayChangeCred.RESET); if (ri.notOK()) { return Result.err(ri); } @@ -2592,7 +2726,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, rcred.value.ns); + Result> nsr = ques.nsDAO().read(trans, rcred.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -2633,12 +2767,10 @@ public class AuthzCassServiceImpl selectEntryIfMultiple(final CredRequest cr, List lcd) { - int entry = 0; - if (lcd.size() > 1) { - String inputOption = cr.getEntry(); - if (inputOption == null) { - String message = selectCredFromList(lcd, false); - String[] variables = buildVariables(lcd); - return Result.err(Status.ERR_ChoiceNeeded, message, variables); - } else { - entry = Integer.parseInt(inputOption) - 1; - } - if (entry < 0 || entry >= lcd.size()) { - return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); - } - } - return Result.ok(entry); - } - @ApiDoc( method = PUT, path = "/authn/cred/:days", @@ -2714,29 +2825,37 @@ public class AuthzCassServiceImpl > rlcd = ques.credDAO.readID(trans, cred.value.id); + Result> rlcd = ques.credDAO().readID(trans, cred.value.id); if (rlcd.notOKorIsEmpty()) { return Result.err(Status.ERR_UserNotFound, "Credential does not exist"); } + + // Only Passwords can be extended + List lcdd = filterList(rlcd.value,CredDAO.BASIC_AUTH, CredDAO.BASIC_AUTH_SHA256); //Need to do the "Pick Entry" mechanism - Result ri = selectEntryIfMultiple((CredRequest)from, rlcd.value); + // Note, this sorts + Result ri = selectEntryIfMultiple((CredRequest)from, lcdd, MayChangeCred.EXTEND); if (ri.notOK()) { return Result.err(ri); } - CredDAO.Data found = rlcd.value.get(ri.value); + CredDAO.Data found = lcdd.get(ri.value); CredDAO.Data cd = cred.value; // Copy over the cred cd.id = found.id; cd.cred = found.cred; cd.other = found.other; cd.type = found.type; - cd.notes = found.notes; cd.ns = found.ns; + cd.notes = "Extended"; + cd.tag = found.tag; cd.expires = org.expiration(null, Expiration.ExtendPassword,days).getTime(); + if(cd.expires.before(found.expires)) { + return Result.err(Result.ERR_BadData,String.format("Credential's expiration date is more than %s days in the future",days)); + } - cred = ques.credDAO.create(trans, cd); + cred = ques.credDAO().create(trans, cd); if (cred.isOK()) { return Result.ok(); } @@ -2746,172 +2865,279 @@ public class AuthzCassServiceImpl value) { - // ensure credentials are sorted so we can fully automate Cred regression test - Collections.sort(value, (cred1, cred2) -> cred1.expires.compareTo(cred2.expires)); - String [] vars = new String[value.size()+1]; - vars[0]="Choice"; + @ApiDoc( + method = DELETE, + path = "/authn/cred", + params = {}, + expectedCode = 200, + errorCodes = {300,403,404,406}, + text = { "Delete a Credential. If multiple credentials exist for this", + "ID, you will need to specify which entry you are deleting in the", + "CredRequest object." + } + ) + @Override + public Result deleteUserCred(AuthzTrans trans, REQUEST from) { + final Result cred = mapper.cred(trans, from, false); + final Validator v = new ServiceValidator(); + if (v.nullOrBlank("cred", cred.value.id).err()) { + return Result.err(Status.ERR_BadData,v.errs()); + } + + MayChange mc = new MayChangeCred(trans,cred.value,MayChangeCred.DELETE); + Result rmc = mc.mayChange(); + if (rmc.notOK()) { + return Result.err(rmc); + } + + boolean doForce = trans.requested(force); + Result> rlcd = ques.credDAO().readID(trans, cred.value.id); + if (rlcd.notOKorIsEmpty()) { + // Empty Creds should not have user_roles. + Result> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id); + if (rlurd.isOKhasData()) { + for (UserRoleDAO.Data data : rlurd.value) { + ques.userRoleDAO().delete(trans, data, false); + } + } + return Result.err(Status.ERR_UserNotFound, "Credential does not exist"); + } + boolean isLastCred = rlcd.value.size()==1; + + int entry; + CredRequest cr = (CredRequest)from; + if(isLastCred) { + if(cr.getEntry()==null || "1".equals(cr.getEntry())) { + entry = 0; + } else { + return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); + } + } else { + entry = -1; + int fentry = entry; + if(cred.value.type==CredDAO.FQI) { + entry = -1; + for(CredDAO.Data cdd : rlcd.value) { + ++fentry; + if(cdd.type == CredDAO.FQI) { + entry = fentry; + break; + } + } + } else { + if (!doForce) { + if (rlcd.value.size() > 1) { + String inputOption = cr.getEntry(); + if (inputOption == null) { + List list = filterList(rlcd.value,CredDAO.BASIC_AUTH,CredDAO.BASIC_AUTH_SHA256,CredDAO.CERT_SHA256_RSA); + String message = selectCredFromList(list, MayChangeCred.DELETE); + Object[] variables = buildVariables(list); + return Result.err(Status.ERR_ChoiceNeeded, message, variables); + } else { + try { + if (inputOption.length()>5) { // should be a date + Date d = Chrono.xmlDatatypeFactory.newXMLGregorianCalendar(inputOption).toGregorianCalendar().getTime(); + for (CredDAO.Data cd : rlcd.value) { + ++fentry; + if (cd.type.equals(cr.getType()) && cd.expires.equals(d)) { + entry = fentry; + break; + } + } + } else { + entry = Integer.parseInt(inputOption) - 1; + int count = 0; + for (CredDAO.Data cd : rlcd.value) { + if(cd.type!=CredDAO.BASIC_AUTH && cd.type!=CredDAO.BASIC_AUTH_SHA256 && cd.type!=CredDAO.CERT_SHA256_RSA) { + ++entry; + } + if(++count>entry) { + break; + } + } + } + } catch (NullPointerException e) { + return Result.err(Status.ERR_BadData, "Invalid Date Format for Entry"); + } catch (NumberFormatException e) { + return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); + } + } + isLastCred = (entry==-1); + } else { + isLastCred = true; + } + if (entry < -1 || entry >= rlcd.value.size()) { + return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); + } + } + } + } + + Result fd = mapper.future(trans,CredDAO.TABLE,from,cred.value,false, + () -> "Delete Credential [" + + cred.value.id + + ']', + mc); + + Result> nsr = ques.nsDAO().read(trans, cred.value.ns); + if (nsr.notOKorIsEmpty()) { + return Result.err(nsr); + } + + switch(fd.status) { + case OK: + Result rfc = func.createFuture(trans, fd.value, cred.value.id, + trans.user(), nsr.value.get(0), FUTURE_OP.D); + + if (rfc.isOK()) { + return Result.err(Status.ACC_Future, "Credential Delete [%s] is saved for future processing",cred.value.id); + } else { + return Result.err(rfc); + } + case Status.ACC_Now: + Resultudr = null; + if (!trans.requested(force)) { + if (entry<0 || entry >= rlcd.value.size()) { + if(cred.value.type==CredDAO.FQI) { + return Result.err(Status.ERR_BadData,"FQI does not exist"); + } else { + return Result.err(Status.ERR_BadData,"Invalid Choice [" + entry + "] chosen for Delete [%s] is saved for future processing",cred.value.id); + } + } + udr = ques.credDAO().delete(trans, rlcd.value.get(entry),false); + } else { + for (CredDAO.Data curr : rlcd.value) { + udr = ques.credDAO().delete(trans, curr, false); + if (udr.notOK()) { + return Result.err(udr); + } + } + } + if (isLastCred) { + Result> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id); + if (rlurd.isOK()) { + for (UserRoleDAO.Data data : rlurd.value) { + ques.userRoleDAO().delete(trans, data, false); + } + } + } + if (udr==null) { + return Result.err(Result.ERR_NotFound,"No User Data found"); + } + if (udr.isOK()) { + return Result.ok(); + } + return Result.err(udr); + default: + return Result.err(fd); + } + + } + + /* + * Codify the way to get Either Choice Needed or actual Integer from Credit Request + */ + private Result selectEntryIfMultiple(final CredRequest cr, List lcd, String action) { + int entry = 0; + if (lcd.size() > 1) { + String inputOption = cr.getEntry(); + if (inputOption == null) { + String message = selectCredFromList(lcd, action); + Object[] variables = buildVariables(lcd); + return Result.err(Status.ERR_ChoiceNeeded, message, variables); + } else { + if(MayChangeCred.EXTEND.equals(action)) { + // might be Tag + if(inputOption.length()>4) { //Tag is at least 12 + int e = 0; + CredDAO.Data last = null; + int lastIdx = -1; + for(CredDAO.Data cdd : lcd) { + if(inputOption.equals(cdd.tag)) { + if(last==null) { + last = cdd; + lastIdx = e; + } else { + if(last.expires.before(cdd.expires)) { + last = cdd; + lastIdx = e; + } + } + } + ++e; + } + if(last!=null) { + return Result.ok(lastIdx); + } + return Result.err(Status.ERR_BadData, "User chose unknown Tag"); + } + } + entry = Integer.parseInt(inputOption) - 1; + } + if (entry < 0 || entry >= lcd.size()) { + return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); + } + } + return Result.ok(entry); + } + + private List filterList(List orig, Integer ... types) { + List rv = new ArrayList<>(); + for(CredDAO.Data cdd : orig) { + if(cdd!=null) { + for(int t : types) { + if(t==cdd.type) { + rv.add(cdd); + } + } + } + } + Collections.sort(rv, (o1,o2) -> { + if(o1.type==o2.type) { + return o1.expires.compareTo(o2.expires); + } else { + return o1.type.compareTo(o2.type); + } + }); + return rv; + } + + private String[] buildVariables(List value) { + String [] vars = new String[value.size()]; + CredDAO.Data cdd; + for (int i = 0; i < value.size(); i++) { - vars[i+1] = value.get(i).id + " " + value.get(i).type - + " |" + value.get(i).expires; + cdd = value.get(i); + vars[i] = cdd.id + TWO_SPACE + Define.getCredType(cdd.type) + TWO_SPACE + Chrono.niceUTCStamp(cdd.expires) + TWO_SPACE + cdd.tag; } return vars; } - private String selectCredFromList(List value, boolean isDelete) { + private String selectCredFromList(List value, String action) { StringBuilder errMessage = new StringBuilder(); - String userPrompt = isDelete?"Select which cred to delete (set force=true to delete all):":"Select which cred to update:"; + String userPrompt = MayChangeCred.DELETE.equals(action)? + "Select which cred to delete (set force=true to delete all):": + "Select which cred to " + action + ':'; int numSpaces = value.get(0).id.length() - "Id".length(); errMessage.append(userPrompt + '\n'); - errMessage.append(" Id"); + errMessage.append(" ID"); for (int i = 0; i < numSpaces; i++) { errMessage.append(' '); } - errMessage.append(" Type Expires" + '\n'); + errMessage.append(" Type Expires Tag " + '\n'); for (int i=0;i deleteUserCred(AuthzTrans trans, REQUEST from) { - final Result cred = mapper.cred(trans, from, false); - final Validator v = new ServiceValidator(); - if (v.nullOrBlank("cred", cred.value.id).err()) { - return Result.err(Status.ERR_BadData,v.errs()); - } - - Result> rlcd = ques.credDAO.readID(trans, cred.value.id); - if (rlcd.notOKorIsEmpty()) { - // Empty Creds should have no user_roles. - Result> rlurd = ques.userRoleDAO.readByUser(trans, cred.value.id); - if (rlurd.isOK()) { - for (UserRoleDAO.Data data : rlurd.value) { - ques.userRoleDAO.delete(trans, data, false); - } - } - return Result.err(Status.ERR_UserNotFound, "Credential does not exist"); - } - boolean isLastCred = rlcd.value.size()==1; - - MayChange mc = new MayChangeCred(trans,cred.value); - Result rmc = mc.mayChange(); - if (rmc.notOK()) { - return Result.err(rmc); - } - - int entry = 0; - if (!trans.requested(force)) { - if (rlcd.value.size() > 1) { - CredRequest cr = (CredRequest)from; - String inputOption = cr.getEntry(); - if (inputOption == null) { - String message = selectCredFromList(rlcd.value, true); - String[] variables = buildVariables(rlcd.value); - return Result.err(Status.ERR_ChoiceNeeded, message, variables); - } else { - try { - if (inputOption.length()>5) { // should be a date - Date d = Chrono.xmlDatatypeFactory.newXMLGregorianCalendar(inputOption).toGregorianCalendar().getTime(); - entry = 0; - for (CredDAO.Data cd : rlcd.value) { - if (cd.type.equals(cr.getType()) && cd.expires.equals(d)) { - break; - } - ++entry; - } - } else { - entry = Integer.parseInt(inputOption) - 1; - } - } catch (NullPointerException e) { - return Result.err(Status.ERR_BadData, "Invalid Date Format for Entry"); - } catch (NumberFormatException e) { - return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); - } - } - isLastCred = (entry==-1)?true:false; - } else { - isLastCred = true; - } - if (entry < -1 || entry >= rlcd.value.size()) { - return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); - } + if(MayChangeCred.EXTEND.equals(action)) { + errMessage.append("Run same command again with chosen entry or Tag as last parameter"); + } else { + errMessage.append("Run same command again with chosen entry as last parameter"); } + return errMessage.toString(); - Result fd = mapper.future(trans,CredDAO.TABLE,from,cred.value,false, - () -> "Delete Credential [" + - cred.value.id + - ']', - mc); - - Result> nsr = ques.nsDAO.read(trans, cred.value.ns); - if (nsr.notOKorIsEmpty()) { - return Result.err(nsr); - } - - switch(fd.status) { - case OK: - Result rfc = func.createFuture(trans, fd.value, cred.value.id, - trans.user(), nsr.value.get(0), FUTURE_OP.D); - - if (rfc.isOK()) { - return Result.err(Status.ACC_Future, "Credential Delete [%s] is saved for future processing",cred.value.id); - } else { - return Result.err(rfc); - } - case Status.ACC_Now: - Resultudr = null; - if (!trans.requested(force)) { - if (entry<0 || entry >= rlcd.value.size()) { - return Result.err(Status.ERR_BadData,"Invalid Choice [" + entry + "] chosen for Delete [%s] is saved for future processing",cred.value.id); - } - udr = ques.credDAO.delete(trans, rlcd.value.get(entry),false); - } else { - for (CredDAO.Data curr : rlcd.value) { - udr = ques.credDAO.delete(trans, curr, false); - if (udr.notOK()) { - return Result.err(udr); - } - } - } - if (isLastCred) { - Result> rlurd = ques.userRoleDAO.readByUser(trans, cred.value.id); - if (rlurd.isOK()) { - for (UserRoleDAO.Data data : rlurd.value) { - ques.userRoleDAO.delete(trans, data, false); - } - } - } - if (udr==null) { - return Result.err(Result.ERR_NotFound,"No User Data found"); - } - if (udr.isOK()) { - return Result.ok(); - } - return Result.err(udr); - default: - return Result.err(fd); - } - } - @Override public Result doesCredentialMatch(AuthzTrans trans, REQUEST credReq) { TimeTaken tt = trans.start("Does Credential Match", Env.SUB); @@ -2936,22 +3162,6 @@ public class AuthzCassServiceImpl nsd; @Override public Result mayChange() { + if(urr.value.role.startsWith(urr.value.user)) { + return Result.ok((NsDAO.Data)null); + } if (nsd==null) { RoleDAO.Data r = RoleDAO.Data.decode(userRole); nsd = ques.mayUser(trans, trans.user(), r, Access.write); @@ -3032,15 +3261,24 @@ public class AuthzCassServiceImpl nsr = ques.deriveNs(trans, userRole.role); - if (nsr.notOKorIsEmpty()) { - return Result.err(nsr); + + NsDAO.Data ndd; + if(userRole.role.startsWith(userRole.user)) { + userRole.ns=userRole.user; + userRole.rname="user"; + ndd = null; + } else { + Result nsr = ques.deriveNs(trans, userRole.role); + if (nsr.notOK()) { + return Result.err(nsr); + } + ndd = nsr.value; } switch(fd.status) { case OK: Result rfc = func.createFuture(trans, fd.value, userRole.user+'|'+userRole.ns + '.' + userRole.rname, - userRole.user, nsr.value, FUTURE_OP.C); + userRole.user, ndd, FUTURE_OP.C); if (rfc.isOK()) { return Result.err(Status.ACC_Future, "UserRole [%s - %s.%s] is saved for future processing", userRole.user, @@ -3095,7 +3333,7 @@ public class AuthzCassServiceImpl userSet = new HashSet<>(); - Result> rlurd = ques.userRoleDAO.readByRole(trans, role); + Result> rlurd = ques.userRoleDAO().readByRole(trans, role); if (rlurd.isOK()) { for (UserRoleDAO.Data data : rlurd.value) { userSet.add(data); @@ -3128,7 +3366,7 @@ public class AuthzCassServiceImpl > rlurd = ques.userRoleDAO.readByUser(trans, user); + Result> rlurd = ques.userRoleDAO().readByUser(trans, user); if (rlurd.notOK()) { return Result.err(rlurd); } @@ -3189,172 +3427,9 @@ public class AuthzCassServiceImpl resetRolesForUser(AuthzTrans trans, REQUEST rreq) { - Result rurdd = mapper.userRole(trans, rreq); - final ServiceValidator v = new ServiceValidator(); - if (rurdd.notOKorIsEmpty()) { - return Result.err(rurdd); - } - if (v.user(trans.org(), rurdd.value.user).err()) { - return Result.err(Status.ERR_BadData,v.errs()); - } - - Set currRoles = new HashSet<>(); - Result> rlurd = ques.userRoleDAO.readByUser(trans, rurdd.value.user); - if (rlurd.isOK()) { - for (UserRoleDAO.Data data : rlurd.value) { - currRoles.add(data.role); - } - } - - Result rv = null; - String[] roles; - if (rurdd.value.role==null) { - roles = new String[0]; - } else { - roles = rurdd.value.role.split(","); - } - - for (String role : roles) { - if (v.role(role).err()) { - return Result.err(Status.ERR_BadData,v.errs()); - } - Result rrdd = RoleDAO.Data.decode(trans, ques, role); - if (rrdd.notOK()) { - return Result.err(rrdd); - } - - rurdd.value.role(rrdd.value); - - Result nsd = ques.mayUser(trans, trans.user(), rrdd.value,Access.write); - if (nsd.notOK()) { - return Result.err(nsd); - } - Result nsr = ques.deriveNs(trans, role); - if (nsr.notOKorIsEmpty()) { - return Result.err(nsr); - } - - if (currRoles.contains(role)) { - currRoles.remove(role); - } else { - rv = func.addUserRole(trans, rurdd.value); - if (rv.notOK()) { - return rv; - } - } - } - - for (String role : currRoles) { - rurdd.value.role(trans,ques,role); - rv = ques.userRoleDAO.delete(trans, rurdd.value, false); - if (rv.notOK()) { - trans.info().log(rurdd.value.user,"/",rurdd.value.role, "expected to be deleted, but does not exist"); - // return rv; // if it doesn't exist, don't error out - } - - } - - return Result.ok(); - - } - - @ApiDoc( - method = PUT, - path = "/authz/userRole/role", - params = {}, - expectedCode = 200, - errorCodes = {403,404,406}, - text = { "Set a Role's users to the users specified in the UserRoleRequest object.", - "WARNING: Users supplied will be the ONLY users attached to this role", - "If no users are supplied, role's users are reset." - } - ) - @Override - public Result resetUsersForRole(AuthzTrans trans, REQUEST rreq) { - Result rurdd = mapper.userRole(trans, rreq); - if (rurdd.notOKorIsEmpty()) { - return Result.err(rurdd); - } - final ServiceValidator v = new ServiceValidator(); - if (v.user_role(rurdd.value).err()) { - return Result.err(Status.ERR_BadData,v.errs()); - } - - RoleDAO.Data rd = RoleDAO.Data.decode(rurdd.value); - - Result nsd = ques.mayUser(trans, trans.user(), rd, Access.write); - if (nsd.notOK()) { - return Result.err(nsd); - } - - Result nsr = ques.deriveNs(trans, rurdd.value.role); - if (nsr.notOKorIsEmpty()) { - return Result.err(nsr); - } - - Set currUsers = new HashSet<>(); - Result> rlurd = ques.userRoleDAO.readByRole(trans, rurdd.value.role); - if (rlurd.isOK()) { - for (UserRoleDAO.Data data : rlurd.value) { - currUsers.add(data.user); - } - } - - // found when connected remotely to DEVL, can't replicate locally - // inconsistent errors with cmd: role user setTo [nothing] - // deleteUserRole --> read --> get --> cacheIdx(?) - // sometimes returns idx for last added user instead of user passed in - // cache bug? - - - Result rv = null; - String[] users = {}; - if (rurdd.value.user != null) { - users = rurdd.value.user.split(","); - } - - for (String user : users) { - if (v.user(trans.org(), user).err()) { - return Result.err(Status.ERR_BadData,v.errs()); - } - rurdd.value.user = user; - - if (currUsers.contains(user)) { - currUsers.remove(user); - } else { - rv = func.addUserRole(trans, rurdd.value); - if (rv.notOK()) { - return rv; - } - } - } - - for (String user : currUsers) { - rurdd.value.user = user; - rv = ques.userRoleDAO.delete(trans, rurdd.value, false); - if (rv.notOK()) { - trans.info().log(rurdd.value, "expected to be deleted, but not exists"); - return rv; - } - } - - return Result.ok(); - } + - @ApiDoc( + @ApiDoc( method = GET, path = "/authz/userRole/extend/:user/:role", params = { "user|string|true", @@ -3387,7 +3462,7 @@ public class AuthzCassServiceImpl > rr = ques.userRoleDAO.read(trans, user,role); + Result> rr = ques.userRoleDAO().read(trans, user,role); if (rr.notOK()) { return Result.err(rr); } @@ -3462,7 +3537,7 @@ public class AuthzCassServiceImpl > rulr; - if ((rulr=ques.userRoleDAO.read(trans, usr, role)).notOKorIsEmpty()) { + if ((rulr=ques.userRoleDAO().read(trans, usr, role)).notOKorIsEmpty()) { return Result.err(Status.ERR_UserRoleNotFound, "User [ "+usr+" ] is not " + "Assigned to the Role [ " + role + " ]"); } @@ -3486,7 +3561,7 @@ public class AuthzCassServiceImpl userSet = new HashSet<>(); - Result> rlurd = ques.userRoleDAO.readUserInRole(trans, user, role); + Result> rlurd = ques.userRoleDAO().readUserInRole(trans, user, role); if (rlurd.isOK()) { for (UserRoleDAO.Data data : rlurd.value) { userSet.add(data); @@ -3574,7 +3649,7 @@ public class AuthzCassServiceImpl userSet = new HashSet<>(); - Result> rlurd = ques.userRoleDAO.readByRole(trans, role); + Result> rlurd = ques.userRoleDAO().readByRole(trans, role); if (rlurd.isOK()) { for (UserRoleDAO.Data data : rlurd.value) { if (contactOnly) { //scrub data @@ -3627,7 +3702,7 @@ public class AuthzCassServiceImpl > nsd = ques.nsDAO.read(trans, nss.value.ns); + Result> nsd = ques.nsDAO().read(trans, nss.value.ns); if (nsd.notOK()) { return Result.err(nsd); } @@ -3641,7 +3716,7 @@ public class AuthzCassServiceImpl userSet = new HashSet<>(); if (!nss.isEmpty()) { - Result> rlp = ques.permDAO.readByType(trans, nss.value.ns, nss.value.name); + Result> rlp = ques.permDAO().readByType(trans, nss.value.ns, nss.value.name); if (rlp.isOKhasData()) { for (PermDAO.Data pd : rlp.value) { if ((allInstance || pd.instance.equals(instance)) && @@ -3650,7 +3725,7 @@ public class AuthzCassServiceImpl > rlurd = ques.userRoleDAO.readByRole(trans, role.replace('|', '.')); + Result> rlurd = ques.userRoleDAO().readByRole(trans, role.replace('|', '.')); if (rlurd.isOKhasData()) { for (UserRoleDAO.Data urd : rlurd.value) { userSet.add(urd); @@ -3669,7 +3744,7 @@ public class AuthzCassServiceImpl > resp = ques.historyDAO.readByUser(trans, user, yyyymm); + Result> resp = ques.historyDAO().readByUser(trans, user, yyyymm); if (resp.notOK()) { return Result.err(resp); } @@ -3727,7 +3802,7 @@ public class AuthzCassServiceImpl > resp = ques.historyDAO.readBySubject(trans, role, "role", yyyymm); + Result> resp = ques.historyDAO().readBySubject(trans, role, "role", yyyymm); if (resp.notOK()) { return Result.err(resp); } @@ -3743,16 +3818,21 @@ public class AuthzCassServiceImpl rnd = ques.deriveNs(trans,type); - if (rnd.notOK()) { - return Result.err(rnd); + Result> resp; + if(type.startsWith(trans.user())) { + resp = ques.historyDAO().readBySubject(trans, type, "perm", yyyymm); + } else { + Result rnd = ques.deriveNs(trans,type); + if (rnd.notOK()) { + return Result.err(rnd); + } + rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read); + if (rnd.notOK()) { + return Result.err(rnd); + } + resp = ques.historyDAO().readBySubject(trans, type, "perm", yyyymm); } - rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read); - if (rnd.notOK()) { - return Result.err(rnd); - } - Result> resp = ques.historyDAO.readBySubject(trans, type, "perm", yyyymm); if (resp.notOK()) { return Result.err(resp); } @@ -3762,8 +3842,7 @@ public class AuthzCassServiceImpl getHistoryByNS(AuthzTrans trans, String ns, int[] yyyymm, final int sort) { final Validator v = new ServiceValidator(); - if (v.nullOrBlank("NS",ns) - .err()) { + if (v.nullOrBlank("NS",ns).err()) { return Result.err(Status.ERR_BadData,v.errs()); } @@ -3776,7 +3855,23 @@ public class AuthzCassServiceImpl > resp = ques.historyDAO.readBySubject(trans, ns, "ns", yyyymm); + Result> resp = ques.historyDAO().readBySubject(trans, ns, "ns", yyyymm); + if (resp.notOK()) { + return Result.err(resp); + } + return mapper.history(trans, resp.value,sort); + } + + @Override + public Result getHistoryBySubject(AuthzTrans trans, String subject, String target, int[] yyyymm, final int sort) { + NsDAO.Data ndd = new NsDAO.Data(); + ndd.name = FQI.reverseDomain(subject); + Result rnd = ques.mayUser(trans, trans.user(), ndd, Access.read); + if (rnd.notOK()) { + return Result.err(rnd); + } + + Result> resp = ques.historyDAO().readBySubject(trans, subject, target, yyyymm); if (resp.notOK()) { return Result.err(resp); } @@ -3806,7 +3901,7 @@ public class AuthzCassServiceImpl > ddr = ques.delegateDAO.read(trans, dd); + Result> ddr = ques.delegateDAO().read(trans, dd); if (access==Access.create && ddr.isOKhasData()) { return Result.err(Status.ERR_ConflictAlreadyExists, "[%s] already delegates to [%s]", dd.user, ddr.value.get(0).delegate); } else if (access!=Access.create && ddr.notOKorIsEmpty()) { @@ -3846,14 +3941,14 @@ public class AuthzCassServiceImpl rdr = ques.delegateDAO.create(trans, dd); + Result rdr = ques.delegateDAO().create(trans, dd); if (rdr.isOK()) { return Result.ok(); } else { return Result.err(rdr); } } else { - return ques.delegateDAO.update(trans, dd); + return ques.delegateDAO().update(trans, dd); } default: return Result.err(fd); @@ -3869,7 +3964,7 @@ public class AuthzCassServiceImpl > ddl; - if ((ddl=ques.delegateDAO.read(trans, rd.value)).notOKorIsEmpty()) { + if ((ddl=ques.delegateDAO().read(trans, rd.value)).notOKorIsEmpty()) { return Result.err(Status.ERR_DelegateNotFound,"Cannot delete non-existent Delegate"); } final DelegateDAO.Data dd = ddl.value.get(0); @@ -3878,7 +3973,7 @@ public class AuthzCassServiceImpl > ddl; - if ((ddl=ques.delegateDAO.read(trans, dd)).notOKorIsEmpty()) { + if ((ddl=ques.delegateDAO().read(trans, dd)).notOKorIsEmpty()) { return Result.err(Status.ERR_DelegateNotFound,"Cannot delete non-existent Delegate"); } dd = ddl.value.get(0); @@ -3899,7 +3994,7 @@ public class AuthzCassServiceImpl > dbDelgs = ques.delegateDAO.read(trans, user); + Result> dbDelgs = ques.delegateDAO().read(trans, user); try { if (dbDelgs.isOKhasData()) { return mapper.delegate(dbDelgs.value); @@ -3947,7 +4042,7 @@ public class AuthzCassServiceImpl > dbDelgs = ques.delegateDAO.readByDelegate(trans, delegate); + Result> dbDelgs = ques.delegateDAO().readByDelegate(trans, delegate); try { if (dbDelgs.isOKhasData()) { return mapper.delegate(dbDelgs.value); @@ -3980,16 +4075,16 @@ public class AuthzCassServiceImpl > apprByTicket=null; for (ApprovalDAO.Data updt : rlad.value) { if (updt.ticket!=null) { - curr = ques.approvalDAO.readByTicket(trans, updt.ticket); + curr = ques.approvalDAO().readByTicket(trans, updt.ticket); if (curr.isOKhasData()) { final List add = curr.value; // Store a Pre-Lookup apprByTicket = (trans1, noop) -> add; } } else if (updt.id!=null) { - curr = ques.approvalDAO.read(trans, updt); + curr = ques.approvalDAO().read(trans, updt); } else if (updt.approver!=null) { - curr = ques.approvalDAO.readByApprover(trans, updt.approver); + curr = ques.approvalDAO().readByApprover(trans, updt.approver); } else { return Result.err(Status.ERR_BadData,"Approvals need ID, Ticket or Approval data to update"); } @@ -4019,13 +4114,13 @@ public class AuthzCassServiceImpl rfdd = ques.futureDAO.readPrimKey(trans, cd.ticket); + Result rfdd = ques.futureDAO().readPrimKey(trans, cd.ticket); if (rfdd.isOK()) { fdd = rfdd.value; // null is ok } else { @@ -4068,7 +4163,7 @@ public class AuthzCassServiceImpl > rapd = ques.approvalDAO.readByUser(trans, user); + Result> rapd = ques.approvalDAO().readByUser(trans, user); if (rapd.isOK()) { return mapper.approvals(rapd.value); } else { @@ -4132,7 +4227,7 @@ public class AuthzCassServiceImpl > rapd = ques.approvalDAO.readByTicket(trans, uuid); + Result> rapd = ques.approvalDAO().readByTicket(trans, uuid); if (rapd.isOK()) { return mapper.approvals(rapd.value); } else { @@ -4149,19 +4244,19 @@ public class AuthzCassServiceImpl listRapds = new ArrayList<>(); - Result> myRapd = ques.approvalDAO.readByApprover(trans, approver); + Result> myRapd = ques.approvalDAO().readByApprover(trans, approver); if (myRapd.notOK()) { return Result.err(myRapd); } listRapds.addAll(myRapd.value); - Result> delegatedFor = ques.delegateDAO.readByDelegate(trans, approver); + Result> delegatedFor = ques.delegateDAO().readByDelegate(trans, approver); if (delegatedFor.isOK()) { for (DelegateDAO.Data dd : delegatedFor.value) { if (dd.expires.after(new Date())) { String delegator = dd.user; - Result> rapd = ques.approvalDAO.readByApprover(trans, delegator); + Result> rapd = ques.approvalDAO().readByApprover(trans, delegator); if (rapd.isOK()) { for (ApprovalDAO.Data d : rapd.value) { if (!d.user.equals(trans.user())) { @@ -4211,7 +4306,7 @@ public class AuthzCassServiceImpl