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=2431e0ebb1d7e6e6d66866a46d5e340ffe7f0dc1;hb=1296352d8eafee57f982a4342ad79ada4aa56d28;hp=81a9d5ec8e7593e1420a8389212ca85985fb3435;hpb=a50007dcded86acc2dcd610810f8afac720a058a;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 81a9d5ec..2431e0eb 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
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -42,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;
@@ -67,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;
@@ -82,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;
@@ -91,8 +99,8 @@ import org.onap.aaf.misc.env.util.Split;
import aaf.v2_0.CredRequest;
/**
- * AuthzCassServiceImpl implements AuthzCassService for
- *
+ * AuthzCassServiceImpl implements AuthzCassService for
+ *
* @author Jonathan
*
* @param
@@ -108,11 +116,12 @@ import aaf.v2_0.CredRequest;
*/
public class AuthzCassServiceImpl
implements AuthzService {
-
+
+ private static final String TWO_SPACE = " ";
private Mapper mapper;
@Override
public Mapper mapper() {return mapper;}
-
+
private static final String ASTERIX = "*";
private static final String CACHE = "cache";
private static final String ROOT_NS = Define.ROOT_NS();
@@ -120,28 +129,28 @@ public class AuthzCassServiceImpl mapper,Question question) {
this.ques = question;
func = new Function(trans, question);
this.mapper = mapper;
-
+
}
/***********************************
- * NAMESPACE
+ * NAMESPACE
***********************************/
/**
* createNS
- * @throws DAOException
+ * @throws DAOException
* @see org.onap.aaf.auth.service.AuthzService#createNS(org.onap.aaf.auth.env.test.AuthzTrans, java.lang.String, java.lang.String)
*/
- @ApiDoc(
- method = POST,
+ @ApiDoc(
+ method = POST,
path = "/authz/ns",
params = {},
expectedCode = 201,
- errorCodes = { 403,404,406,409 },
+ errorCodes = { 403,404,406,409 },
text = { "Namespace consists of: ",
"- name - What you want to call this Namespace
",
"- responsible(s) - Person(s) who receive Notifications and approves Requests ",
@@ -159,7 +168,7 @@ public class AuthzCassServiceImpl createNS(final AuthzTrans trans, REQUEST from, NsType type) {
final Result rnamespace = mapper.ns(trans, from);
final ServiceValidator v = new ServiceValidator();
- if (v.ns(rnamespace).err()) {
+ if (v.ns(rnamespace).err()) {
return Result.err(Status.ERR_BadData,v.errs());
}
final Namespace namespace = rnamespace.value;
@@ -167,12 +176,13 @@ public class AuthzCassServiceImpl fd = mapper.future(trans, NsDAO.TABLE,from,namespace,true,
+
+ Result fd = mapper.future(trans, NsDAO.TABLE,from,namespace,true,
new Mapper.Memo() {
@Override
public String get() {
@@ -194,7 +204,7 @@ public class AuthzCassServiceImpl rfc = func.createFuture(trans, fd.value, namespace.name, trans.user(),parentNs.value, FUTURE_OP.C);
if (rfc.isOK()) {
return Result.err(Status.ACC_Future, "NS [%s] is saved for future processing",namespace.name);
- } else {
+ } else {
return Result.err(rfc);
}
case Status.ACC_Now:
@@ -203,16 +213,16 @@ public class AuthzCassServiceImpl > rlnsd = ques.nsDAO.read(trans, ns);
+ Result
> rlnsd = ques.nsDAO().read(trans, ns);
if (rlnsd.notOKorIsEmpty()) {
return Result.err(rlnsd);
}
@@ -309,29 +319,30 @@ 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);
}
@@ -358,13 +369,13 @@ public class AuthzCassServiceImpl > rlnsd = ques.nsDAO.read(trans, ns);
+ Result> rlnsd = ques.nsDAO().read(trans, ns);
if (rlnsd.notOKorIsEmpty()) {
return Result.err(rlnsd);
}
@@ -392,31 +403,31 @@ public class AuthzCassServiceImpl > rlnsd = ques.nsDAO.read(trans, ns);
+ Result> rlnsd = ques.nsDAO().read(trans, ns);
if (rlnsd.notOKorIsEmpty()) {
return Result.err(rlnsd);
}
@@ -443,7 +454,7 @@ public class AuthzCassServiceImpl > 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);
}
Result rnd = ques.mayUser(trans, trans.user(), rlnd.value.get(0), Access.read);
if (rnd.notOK()) {
- return Result.err(rnd);
+ return Result.err(rnd);
}
-
-
+
+
Namespace namespace = new Namespace(rnd.value);
Result> rd = func.getOwners(trans, namespace.name, includeExpired);
if (rd.isOK()) {
@@ -496,7 +507,7 @@ public class AuthzCassServiceImpl > rn = loadNamepace(trans, user, ".admin", full);
if (rn.notOK()) {
return Result.err(rn);
}
if (rn.isEmpty()) {
- return Result.err(Status.ERR_NotFound, "[%s] is not an admin for any namespaces",user);
+ return Result.err(Status.ERR_NotFound, "[%s] is not an admin for any namespaces",user);
}
NSS nss = mapper.newInstance(API.NSS);
// Note: "loadNamespace" already validates view of Namespace
@@ -534,13 +545,13 @@ public class AuthzCassServiceImpl > rn = loadNamepace(trans, user, null, full);
if (rn.notOK()) {
return Result.err(rn);
}
if (rn.isEmpty()) {
- return Result.err(Status.ERR_NotFound, "[%s] is not an admin or owner for any namespaces",user);
+ return Result.err(Status.ERR_NotFound, "[%s] is not an admin or owner for any namespaces",user);
}
NSS nss = mapper.newInstance(API.NSS);
// Note: "loadNamespace" already validates view of Namespace
@@ -563,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);
}
@@ -584,7 +595,7 @@ public class AuthzCassServiceImpl rnd = ques.deriveNs(trans, parent);
if (rnd.notOK()) {
return Result.err(rnd);
}
rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read);
if (rnd.notOK()) {
- return Result.err(rnd);
+ return Result.err(rnd);
}
Set 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);
@@ -690,7 +701,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);
}
-
+
if (ques.mayUser(trans, trans.user(), rlnd.value.get(0), Access.write).notOK()) {
return Result.err(Status.ERR_Denied, "You do not have approval to change %s",namespace.name);
}
- Result 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 {
return Result.err(rdr);
}
}
-
+
/**
* deleteNS
- * @throws DAOException
+ * @throws DAOException
* @see org.onap.aaf.auth.service.AuthzService#deleteNS(org.onap.aaf.auth.env.test.AuthzTrans, java.lang.String, java.lang.String)
*/
@ApiDoc(
- method = DELETE,
+ method = DELETE,
path = "/authz/ns/:ns",
params = { "ns|string|true" },
expectedCode = 200,
- errorCodes = { 403,404,424 },
+ errorCodes = { 403,404,424 },
text = { "Delete the Namespace :ns. Namespaces cannot normally be deleted when there ",
"are still credentials associated with them, but they can be deleted by setting ",
"the \"force\" property. To do this: Add 'force=true' as a query parameter",
@@ -772,19 +783,19 @@ public class AuthzCassServiceImpl - type - a Namespace qualified identifier specifying what kind of resource "
+ "is being protected
",
@@ -795,66 +806,139 @@ public class AuthzCassServiceImpl createPerm(final AuthzTrans trans,REQUEST rreq) {
+ public Result 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 + ']';
+
+ // 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);
}
- },
- new MayChange() {
- private Result nsd;
- @Override
- public Result> mayChange() {
- if (nsd==null) {
- nsd = ques.mayUser(trans, trans.user(), newPd.value, Access.write);
- }
- return nsd;
+ if(!rlpdd.isEmpty()) {
+ return Result.err(Result.ERR_ConflictAlreadyExists,"Permission already exists");
}
- });
- 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);
+
+ 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 {
- return Result.err(rfc);
+ if(!rlrdd.isEmpty()) {
+ rdd = rlrdd.value.get(0);
+ }
}
- case Status.ACC_Now:
- return func.createPerm(trans, newPd.value, true);
- default:
- return Result.err(fd);
- }
+
+ 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);
+ }
+ }
}
- @ApiDoc(
- method = GET,
+ @ApiDoc(
+ method = GET,
path = "/authz/perms/:type",
params = {"type|string|true"},
expectedCode = 200,
- errorCodes = { 404,406 },
+ errorCodes = { 404,406 },
text = { "List All Permissions that match the :type element of the key" }
)
@Override
@@ -872,7 +956,7 @@ public class AuthzCassServiceImpl r;
// if ((r = ques.mayUserViewPerm(trans, trans.user(), permType)).notOK())return Result.err(r);
-
+
PERMS perms = mapper.newInstance(API.PERMS);
if (!rlpd.isEmpty()) {
// Note: Mapper will restrict what can be viewed
@@ -880,15 +964,15 @@ public class AuthzCassServiceImpl > rlpd = ques.getPermsByName(trans, type, instance, action);
if (rlpd.notOK()) {
return Result.err(rlpd);
@@ -913,12 +997,12 @@ public class AuthzCassServiceImpl 'user' must be expressed as full identity (ex: id@full.domain.com)
"}
)
@@ -929,30 +1013,30 @@ 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);
}
-
+
PERMS perms = mapper.newInstance(API.PERMS);
-
+
if (rlpd.isEmpty()) {
return Result.ok(perms);
}
// Note: Mapper will restrict what can be viewed
// if user is the same as that which is looked up, no filtering is required
- return mapper.perms(trans, rlpd.value,
- perms,
+ return mapper.perms(trans, rlpd.value,
+ perms,
!user.equals(trans.user()));
}
- @ApiDoc(
- method = GET,
+ @ApiDoc(
+ method = GET,
path = "/authz/perms/user/:user/scope/:scope",
params = {"user|string|true","scope|string|true"},
expectedCode = 200,
- errorCodes = { 404,406 },
+ errorCodes = { 404,406 },
text = { "List All Permissions that match user :user, filtered by NS (Scope)",
"'user' must be expressed as full identity (ex: id@full.domain.com)
",
"'scope' must be expressed as NSs separated by ':'
"
@@ -969,26 +1053,26 @@ public class AuthzCassServiceImpl 'user' must be expressed as full identity (ex: id@full.domain.com)",
"",
@@ -1016,14 +1100,15 @@ 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);
}
-
- /*//TODO
+
+ /*//TODO
1) See if allowed to query
2) See if User is allowed
*/
@@ -1065,25 +1150,25 @@ public class AuthzCassServiceImpl > rlpd = ques.permDAO.readNS(trans, ns);
+
+ Result> rlpd = ques.permDAO().readNS(trans, ns);
if (rlpd.notOK()) {
return Result.err(rlpd);
}
@@ -1150,15 +1235,15 @@ 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,
+ return Result.err(Status.ERR_PermissionNotFound,
"Permission [%s|%s|%s] does not exist",
origType,origInstance,origAction);
}
-
+
PermDAO.Data origPd = origRlpd.value.get(0);
if (!origPd.ns.equals(newPd.value.ns)) {
return Result.err(Status.ERR_Denied, "Cannot change namespace with rename command. " +
" must start with [" + origPd.ns + "]");
}
-
- if ( origPd.type.equals(newPd.value.type) &&
- origPd.action.equals(newPd.value.action) &&
+
+ if ( origPd.type.equals(newPd.value.type) &&
+ origPd.action.equals(newPd.value.action) &&
origPd.instance.equals(newPd.value.instance) ) {
return Result.err(Status.ERR_ConflictAlreadyExists, "New Permission must be different than original permission");
}
-
+
Set origRoles = origPd.roles(false);
if (!origRoles.isEmpty()) {
Set roles = newPd.value.roles(true);
for (String role : origPd.roles) {
- roles.add(role);
+ roles.add(role);
}
- }
-
+ }
+
newPd.value.description = origPd.description;
-
+
Result rv = null;
-
+
rv = func.createPerm(trans, newPd.value, false);
if (rv.isOK()) {
rv = func.deletePerm(trans, origPd, true, false);
}
return rv;
}
-
- @ApiDoc(
- method = PUT,
+
+ @ApiDoc(
+ method = PUT,
path = "/authz/perm",
params = {},
expectedCode = 200,
- errorCodes = { 404,406 },
+ errorCodes = { 404,406 },
text = { "Add Description Data to Perm" }
)
@Override
@@ -1235,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();
@@ -1259,7 +1344,7 @@ public class AuthzCassServiceImpl > rcurr = ques.permDAO.read(trans,
- updt.value.ns,
- updt.value.type,
- updt.value.instance,
+ Result> rcurr = ques.permDAO().read(trans,
+ updt.value.ns,
+ updt.value.type,
+ updt.value.instance,
updt.value.action);
-
+
if (rcurr.notOKorIsEmpty()) {
- return Result.err(Status.ERR_PermissionNotFound,
+ return Result.err(Status.ERR_PermissionNotFound,
"Permission [%s.%s|%s|%s] does not exist",
updt.value.ns,updt.value.type,updt.value.instance,updt.value.action);
}
-
+
// Create a set of Update Roles, which are in Internal Format
Set updtRoles = new HashSet<>();
Result nss;
@@ -1312,16 +1397,16 @@ public class AuthzCassServiceImpl rv = null;
-
+
for (PermDAO.Data curr : rcurr.value) {
Set currRoles = curr.roles(false);
- // must add roles to this perm, and add this perm to each role
- // in the update, but not in the current
+ // must add roles to this perm, and add this perm to each role
+ // in the update, but not in the current
for (String role : updtRoles) {
if (!currRoles.contains(role)) {
Result 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);
@@ -1341,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);
@@ -1352,17 +1437,17 @@ 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);
}
-
- Result rfc = func.createFuture(trans, fd.value,
+
+ Result rfc = func.createFuture(trans, fd.value,
perm.encode(), trans.user(),nsr.value.get(0),FUTURE_OP.D);
if (rfc.isOK()) {
return Result.err(Status.ACC_Future, "Perm Deletion [%s] is saved for future processing",perm.encode());
- } else {
+ } else {
return Result.err(rfc);
}
case Status.ACC_Now:
return func.deletePerm(trans,perm,trans.requested(force), false);
default:
return Result.err(fd);
- }
- }
-
- @ApiDoc(
+ }
+ }
+
+ @ApiDoc(
method = DELETE,
path = "/authz/perm/:name/:type/:action",
params = {"type|string|true",
"instance|string|true",
"action|string|true"},
expectedCode = 200,
- errorCodes = { 404,406 },
+ errorCodes = { 404,406 },
text = { "Delete the Permission referenced by :type :instance :action",
"You cannot normally delete a permission which is still granted to roles,",
"however the \"force\" property allows you to do just that. To do this: Add",
@@ -1447,7 +1532,7 @@ public class AuthzCassServiceImpl pd = ques.permFrom(trans, type, instance, action);
if (pd.isOK()) {
return func.deletePerm(trans, pd.value, trans.requested(force), false);
@@ -1457,7 +1542,7 @@ 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");
}
@@ -1496,8 +1586,8 @@ 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);
}
switch(fd.status) {
case OK:
- Result rfc = func.createFuture(trans, fd.value,
+ Result rfc = func.createFuture(trans, fd.value,
role.encode(), trans.user(),nsr.value.get(0),FUTURE_OP.C);
if (rfc.isOK()) {
return Result.err(Status.ACC_Future, "Role [%s.%s] is saved for future processing",
rd.value.ns,
rd.value.name);
- } else {
+ } else {
return Result.err(rfc);
}
case Status.ACC_Now:
- Result rdr = ques.roleDAO.create(trans, role);
+ Result rdr = ques.roleDAO().create(trans, role);
if (rdr.isOK()) {
return Result.ok();
} else {
@@ -1546,7 +1636,7 @@ public class AuthzCassServiceImpl rrdd = RoleDAO.Data.decode(trans, ques, role);
if (rrdd.isOKhasData()) {
@@ -1570,7 +1660,7 @@ public class AuthzCassServiceImpl > rlrd = ques.getRolesByName(trans, query<0?role:role.substring(0, query));
@@ -1608,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()) {
@@ -1632,7 +1722,7 @@ public class AuthzCassServiceImpl rnsd = ques.deriveNs(trans, ns);
+ Result rnsd = ques.deriveNs(trans, ns);
if (rnsd.notOK()) {
- return Result.err(rnsd);
+ return Result.err(rnsd);
}
rnsd = ques.mayUser(trans, trans.user(), rnsd.value, Access.read);
if (rnsd.notOK()) {
- return Result.err(rnsd);
+ return Result.err(rnsd);
}
TimeTaken tt = trans.start("MAP Roles by NS to Roles", Env.SUB);
try {
ROLES roles = mapper.newInstance(API.ROLES);
// Get list of roles per user, then add to Roles as we go
- Result> 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.
@@ -1683,7 +1773,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
@@ -1744,7 +1834,7 @@ 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);
@@ -1799,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 {
@@ -1820,7 +1910,7 @@ public class AuthzCassServiceImpl type - a Namespace qualified identifier specifying what kind of resource "
+ "is being protected",
"instance - a key, possibly multi-dimensional, that identifies a specific "
@@ -1852,7 +1942,7 @@ 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
@@ -1876,7 +1966,7 @@ public class AuthzCassServiceImpl fd = mapper.future(trans, PermDAO.TABLE, rreq, rpd.value,true, // Allow grants to create Approvals
new Mapper.Memo() {
@Override
@@ -1904,43 +1994,46 @@ 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);
}
-
+
}
/**
@@ -1978,17 +2071,17 @@ 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,
+
+ private Result delPermFromRole(final AuthzTrans trans, PermDAO.Data pdd, RoleDAO.Data rdd, REQUEST rreq) {
+ Result> rlpd = ques.permDAO().read(trans, pdd.ns, pdd.type,
pdd.instance, pdd.action);
-
+
if (rlpd.notOKorIsEmpty()) {
- return Result.err(Status.ERR_PermissionNotFound,
+ return Result.err(Status.ERR_PermissionNotFound,
"Permission [%s.%s|%s|%s] does not exist",
pdd.ns,pdd.type,pdd.instance,pdd.action);
}
-
+
Result fd = mapper.future(trans, PermDAO.TABLE, rreq, pdd,true, // allow ungrants requests
new Mapper.Memo() {
@Override
@@ -2007,13 +2100,13 @@ 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);
}
switch(fd.status) {
case OK:
- Result rfc = func.createFuture(trans,fd.value,
+ Result rfc = func.createFuture(trans,fd.value,
pdd.fullPerm(),
trans.user(),
nsr.value.get(0),
@@ -2034,7 +2127,7 @@ public class AuthzCassServiceImpl rrns = ques.deriveNs(trans, role);
if (rrns.notOKorIsEmpty()) {
return Result.err(rrns);
}
-
- final Result> 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);
}
-
+
return delPermFromRole(trans,rpd.value.get(0), rrd.value.get(0), mapper.ungrantRequest(trans, role, type, instance, action));
}
-
+
@ApiDoc(
method = DELETE,
path = "/authz/role/:role",
@@ -2098,7 +2191,7 @@ public class AuthzCassServiceImpl rrdd = RoleDAO.Data.decode(trans,ques,role);
if (rrdd.isOKhasData()) {
final ServiceValidator v = new ServiceValidator();
- if (v.nullOrBlank(rrdd.value).err()) {
+ if (v.nullOrBlank(rrdd.value).err()) {
return Result.err(Status.ERR_BadData,v.errs());
}
return func.deleteRole(trans, rrdd.value, false, false);
@@ -2131,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);
}
-
- Result rfc = func.createFuture(trans, fd.value,
+
+ Result rfc = func.createFuture(trans, fd.value,
role.encode(), trans.user(),nsr.value.get(0),FUTURE_OP.D);
if (rfc.isOK()) {
return Result.err(Status.ACC_Future, "Role Deletion [%s.%s] is saved for future processing",
rd.value.ns,
rd.value.name);
- } else {
+ } else {
return Result.err(rfc);
}
case Status.ACC_Now:
@@ -2174,14 +2267,14 @@ public class AuthzCassServiceImpl nsd;
private AuthzTrans trans;
private CredDAO.Data cred;
private Executor exec;
-
+
public MayCreateCred(AuthzTrans trans, CredDAO.Data cred, Executor exec) {
this.trans = trans;
this.cred = cred;
@@ -2198,7 +2291,7 @@ public class AuthzCassServiceImpl rmc = ques.mayUser(trans, trans.user(), nsd.value, Access.write);
if (rmc.isOKhasData()) {
@@ -2216,50 +2309,69 @@ public class AuthzCassServiceImpl 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 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];
}
- 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();
- }
+ 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;
-
- @ApiDoc(
- method = POST,
+
+ @ApiDoc(
+ method = POST,
path = "/authn/cred",
params = {},
expectedCode = 201,
- errorCodes = {403,404,406,409},
+ errorCodes = {403,404,406,409},
text = { "A credential consists of:",
"- id - the ID to create within AAF. The domain is in reverse",
"order of Namespace (i.e. Users of Namespace com.att.myapp would be",
@@ -2273,19 +2385,18 @@ public class AuthzCassServiceImpl createUserCred(final AuthzTrans trans, REQUEST from) {
final String cmdDescription = ("Create User Credential");
TimeTaken tt = trans.start(cmdDescription, Env.SUB);
-
+
try {
Result 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();
-
- if (v.cred(trans, trans.org(),rcred,true).err()) { // Note: Creates have stricter Validations
+
+ if (v.cred(trans, trans.org(),rcred,true).err()) { // Note: Creates have stricter Validations
return Result.err(Status.ERR_BadData,v.errs());
}
-
+
// 2016-4 Jonathan, New Behavior - If MechID is not registered with Org, deny creation
Identity mechID = null;
@@ -2295,21 +2406,21 @@ 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);
}
-
+
boolean firstID = false;
MayChange mc;
-
+
CassExecutor exec = new CassExecutor(trans, func);
- Result> 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");
@@ -2319,23 +2430,37 @@ public class AuthzCassServiceImpl TimeUnit.DAYS.toMillis(1)) {
+ return Result.err(Status.ERR_ConflictAlreadyExists, "Credential with same Expiration Date exists");
+ }
+ }
}
- }
+ }
} else {
try {
// 2016-04-12 Jonathan If Caller is the Sponsor and is also an Owner of NS, allow without special Perm
String theMechID = rcred.value.id;
Boolean otherMechIDs = false;
// find out if this is the only mechID. other MechIDs mean special handling (not automated)
- for (CredDAO.Data cd : ques.credDAO.readNS(trans,nsr.value.get(0).name).value) {
+ for (CredDAO.Data cd : ques.credDAO().readNS(trans,nsr.value.get(0).name).value) {
if (!cd.id.equals(theMechID)) {
otherMechIDs = true;
break;
@@ -2344,32 +2469,32 @@ public class AuthzCassServiceImpl fd = mapper.future(trans,CredDAO.TABLE,from, rcred.value,false, // may want to enable in future.
new Mapper.Memo() {
@Override
public String get() {
- return cmdDescription + " [" +
- cdd.id + '|'
- + cdd.type + '|'
+ return cmdDescription + " [" +
+ cdd.id + '|'
+ + cdd.type + '|'
+ cdd.expires + ']';
}
},
mc);
-
+
switch(fd.status) {
case OK:
- Result rfc = func.createFuture(trans, fd.value,
+ Result rfc = func.createFuture(trans, fd.value,
rcred.value.id + '|' + rcred.value.type.toString() + '|' + rcred.value.expires,
trans.user(), nsr.value.get(0), FUTURE_OP.C);
if (rfc.isOK()) {
@@ -2377,26 +2502,33 @@ 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");
}
-
- Result>udr = ques.credDAO.create(trans, rcred.value);
+
+ Result>udr = ques.credDAO().create(trans, rcred.value);
if (udr.isOK()) {
return Result.ok();
}
@@ -2413,12 +2545,12 @@ public class AuthzCassServiceImpl rnd = ques.deriveNs(trans,ns);
if (rnd.notOK()) {
- return Result.err(rnd);
+ return Result.err(rnd);
}
rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read);
if (rnd.notOK()) {
- return Result.err(rnd);
+ return Result.err(rnd);
}
-
+
TimeTaken tt = trans.start("MAP Creds by NS to Creds", Env.SUB);
- try {
+ try {
USERS users = mapper.newInstance(API.USERS);
- Result> rlcd = ques.credDAO.readNS(trans, ns);
-
+ Result> rlcd = ques.credDAO().readNS(trans, ns);
+
if (rlcd.isOK()) {
if (!rlcd.isEmpty()) {
return mapper.cred(rlcd.value, users);
}
- return Result.ok(users);
+ return Result.ok(users);
} else {
return Result.err(rlcd);
}
} finally {
tt.done();
}
-
+
}
- @ApiDoc(
- method = GET,
+ @ApiDoc(
+ method = GET,
path = "/authn/creds/id/:ns",
params = {"id|string|true"},
expectedCode = 200,
- errorCodes = {403,404,406},
+ errorCodes = {403,404,406},
text = { "Return all IDs in for ID"
,"(because IDs are multiple, due to multiple Expiration Dates)"
}
@@ -2474,59 +2606,59 @@ public class AuthzCassServiceImpl rnd = ques.deriveNs(trans,ns);
if (rnd.notOK()) {
- return Result.err(rnd);
+ return Result.err(rnd);
}
rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read);
if (rnd.notOK()) {
- return Result.err(rnd);
+ return Result.err(rnd);
}
-
+
TimeTaken tt = trans.start("MAP Creds by ID to Creds", Env.SUB);
- try {
+ try {
USERS users = mapper.newInstance(API.USERS);
- Result> rlcd = ques.credDAO.readID(trans, id);
-
+ Result> rlcd = ques.credDAO().readID(trans, id);
+
if (rlcd.isOK()) {
if (!rlcd.isEmpty()) {
return mapper.cred(rlcd.value, users);
}
- return Result.ok(users);
+ return Result.ok(users);
} else {
return Result.err(rlcd);
}
} finally {
tt.done();
}
-
+
}
- @ApiDoc(
- method = GET,
+ @ApiDoc(
+ method = GET,
path = "/authn/certs/id/:id",
params = {"id|string|true"},
expectedCode = 200,
- errorCodes = {403,404,406},
+ errorCodes = {403,404,406},
text = { "Return Cert Info for ID"
}
)
@Override
public Result getCertInfoByID(AuthzTrans trans, HttpServletRequest req, String id) {
TimeTaken tt = trans.start("Get Cert Info by ID", Env.SUB);
- try {
+ try {
CERTS certs = mapper.newInstance(API.CERTS);
- Result> rlcd = ques.certDAO.readID(trans, id);
-
+ Result> rlcd = ques.certDAO().readID(trans, id);
+
if (rlcd.isOK()) {
if (!rlcd.isEmpty()) {
return mapper.cert(rlcd.value, certs);
}
- return Result.ok(certs);
- } else {
+ return Result.ok(certs);
+ } else {
return Result.err(rlcd);
}
} finally {
@@ -2535,71 +2667,73 @@ 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 {
Result rcred = mapper.cred(trans, from, true);
if (rcred.isOKhasData()) {
rcred = ques.userCredSetup(trans, rcred.value);
-
+
final ServiceValidator v = new ServiceValidator();
-
- if (v.cred(trans, trans.org(),rcred,false).err()) {// Note: Creates have stricter Validations
+
+ if (v.cred(trans, trans.org(),rcred,false).err()) {// Note: Creates have stricter Validations
return Result.err(Status.ERR_BadData,v.errs());
}
- Result> 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);
- Result> rmc = mc.mayChange();
+ }
+
+ 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);
}
int entry = ri.value;
-
-
+
+
final CredDAO.Data cred = rcred.value;
-
+
Result fd = mapper.future(trans,CredDAO.TABLE,from, rcred.value,false,
new Mapper.Memo() {
@Override
public String get() {
- return cmdDescription + " [" +
- cred.id + '|'
- + cred.type + '|'
+ return cmdDescription + " [" +
+ cred.id + '|'
+ + cred.type + '|'
+ cred.expires + ']';
}
},
mc);
-
- Result> nsr = ques.nsDAO.read(trans, rcred.value.ns);
+
+ Result> nsr = ques.nsDAO().read(trans, rcred.value.ns);
if (nsr.notOKorIsEmpty()) {
return Result.err(nsr);
}
-
+
switch(fd.status) {
case OK:
- Result rfc = func.createFuture(trans, fd.value,
+ Result rfc = func.createFuture(trans, fd.value,
rcred.value.id + '|' + rcred.value.type.toString() + '|' + rcred.value.expires,
trans.user(), nsr.value.get(0), FUTURE_OP.U);
if (rfc.isOK()) {
@@ -2607,7 +2741,7 @@ 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);
- Object[] 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,
+ @ApiDoc(
+ method = PUT,
path = "/authn/cred/:days",
params = {"days|string|true"},
expectedCode = 200,
- errorCodes = {300,403,404,406},
+ errorCodes = {300,403,404,406},
text = { "Extend a Credential Expiration Date. The intention of this API is",
"to avoid an outage in PROD due to a Credential expiring before it",
"can be configured correctly. Measures are being put in place ",
@@ -2694,12 +2807,12 @@ public class AuthzCassServiceImpl cred = mapper.cred(trans, from, false);
Organization org = trans.org();
final ServiceValidator v = new ServiceValidator();
- if (v.notOK(cred).err() ||
+ if (v.notOK(cred).err() ||
v.nullOrBlank(cred.value.id, "Invalid ID").err() ||
v.user(org,cred.value.id).err()) {
return Result.err(Status.ERR_BadData,v.errs());
}
-
+
try {
String reason;
if ((reason=org.validate(trans, Policy.MAY_EXTEND_CRED_EXPIRES, new CassExecutor(trans,func)))!=null) {
@@ -2710,20 +2823,24 @@ 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;
@@ -2732,10 +2849,13 @@ 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";
- for (int i = 0; i < value.size(); i++) {
- vars[i+1] = value.get(i).id + " " + value.get(i).type
- + " |" + value.get(i).expires;
- }
- return vars;
- }
-
- private String selectCredFromList(List value, boolean isDelete) {
- StringBuilder errMessage = new StringBuilder();
- String userPrompt = isDelete?"Select which cred to delete (set force=true to delete all):":"Select which cred to update:";
- int numSpaces = value.get(0).id.length() - "Id".length();
-
- errMessage.append(userPrompt + '\n');
- errMessage.append(" Id");
- for (int i = 0; i < numSpaces; i++) {
- errMessage.append(' ');
- }
- errMessage.append(" Type Expires" + '\n');
- for (int i=0;i> rlcd = ques.credDAO.readID(trans, cred.value.id);
+
+ 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 have no user_roles.
- Result> rlurd = ques.userRoleDAO.readByUser(trans, cred.value.id);
- if (rlurd.isOK()) {
+ // 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);
+ 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);
- Object[] 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;
+
+ 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;
+ }
+ }
}
- ++entry;
+ } 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");
}
- } else {
- entry = Integer.parseInt(inputOption) - 1;
}
- } catch (NullPointerException e) {
- return Result.err(Status.ERR_BadData, "Invalid Date Format for Entry");
- } catch (NumberFormatException e) {
+ isLastCred = (entry==-1);
+ } else {
+ isLastCred = true;
+ }
+ if (entry < -1 || entry >= rlcd.value.size()) {
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");
}
}
-
+
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);
+
+ 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 {
+ } else {
return Result.err(rfc);
}
case Status.ACC_Now:
Result>udr = 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);
+ 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);
+ udr = ques.credDAO().delete(trans, rlcd.value.get(entry),false);
} else {
for (CredDAO.Data curr : rlcd.value) {
- udr = ques.credDAO.delete(trans, curr, false);
+ 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);
+ Result> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id);
if (rlurd.isOK()) {
for (UserRoleDAO.Data data : rlurd.value) {
- ques.userRoleDAO.delete(trans, data, false);
+ ques.userRoleDAO().delete(trans, data, false);
}
}
}
@@ -2907,9 +3031,112 @@ public class AuthzCassServiceImpl 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++) {
+ 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, String action) {
+ StringBuilder errMessage = new StringBuilder();
+ 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");
+ for (int i = 0; i < numSpaces; i++) {
+ errMessage.append(' ');
+ }
+ errMessage.append(" Type Expires Tag " + '\n');
+ for (int i=0;i doesCredentialMatch(AuthzTrans trans, REQUEST credReq) {
@@ -2935,28 +3162,12 @@ public class AuthzCassServiceImpl fd = mapper.future(trans,UserRoleDAO.TABLE,from,urr.value,true, // may request Approvals
() -> "Add User [" + userRole.user + "] to Role [" +
@@ -3024,6 +3251,9 @@ 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);
@@ -3031,21 +3261,30 @@ 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);
+ Result rfc = func.createFuture(trans, fd.value, userRole.user+'|'+userRole.ns + '.' + userRole.rname,
+ 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,
userRole.ns,
userRole.rname);
- } else {
+ } else {
return Result.err(rfc);
}
case Status.ACC_Now:
@@ -3057,7 +3296,7 @@ public class AuthzCassServiceImpl rrdd;
rrdd = RoleDAO.Data.decode(trans,ques,role);
if (rrdd.notOK()) {
@@ -3087,20 +3326,20 @@ 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);
}
}
-
+
@SuppressWarnings("unchecked")
USERROLES users = (USERROLES) mapper.newInstance(API.USER_ROLES);
// Checked for permission
@@ -3125,18 +3364,18 @@ public class AuthzCassServiceImpl > rlurd = ques.userRoleDAO.readByUser(trans, user);
- if (rlurd.notOK()) {
+ Result> rlurd = ques.userRoleDAO().readByUser(trans, user);
+ if (rlurd.notOK()) {
return Result.err(rlurd);
}
-
+
/* Check for
- * 1) is User
+ * 1) is User
* 2) is User's Supervisor
* 3) Has special global access =read permission
- *
+ *
* If none of the 3, then filter results to NSs in which Calling User has Ns.access * read
*/
boolean mustFilter;
@@ -3162,11 +3401,11 @@ public class AuthzCassServiceImpl content;
if (mustFilter) {
content = new ArrayList<>(rlurd.value.size()); // avoid multi-memory redos
-
+
for (UserRoleDAO.Data data : rlurd.value) {
ndd.name=data.ns;
Result mur = ques.mayUser(trans, callingUser, ndd, Access.read);
@@ -3174,7 +3413,7 @@ 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",
@@ -3374,19 +3450,19 @@ public class AuthzCassServiceImpl rrdd = RoleDAO.Data.decode(trans,ques,role);
if (rrdd.notOK()) {
return Result.err(rrdd);
}
-
+
Result rcr = ques.mayUser(trans, trans.user(), rrdd.value, Access.write);
boolean mayNotChange;
if ((mayNotChange = rcr.notOK()) && !trans.requested(future)) {
return Result.err(rcr);
}
-
- Result> rr = ques.userRoleDAO.read(trans, user,role);
+
+ Result> rr = ques.userRoleDAO().read(trans, user,role);
if (rr.notOK()) {
return Result.err(rr);
}
@@ -3405,7 +3481,7 @@ public class AuthzCassServiceImpl rfc = func.createFuture(trans, fto,
+ Result rfc = func.createFuture(trans, fto,
userRole.user+'|'+userRole.role, userRole.user, rcr.value, FUTURE_OP.U);
if (rfc.isOK()) {
return Result.err(Status.ACC_Future, "UserRole [%s - %s] is saved for future processing",
@@ -3421,14 +3497,14 @@ public class AuthzCassServiceImpl rns = ques.mayUser(trans, trans.user(), rdd, Access.write);
@@ -3453,7 +3529,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 + " ]");
}
@@ -3475,27 +3551,27 @@ public class AuthzCassServiceImpl rfc = func.createFuture(trans, fto,
+ Result rfc = func.createFuture(trans, fto,
userRole.user+'|'+userRole.role, userRole.user, rns.value, FUTURE_OP.D);
if (rfc.isOK()) {
- return Result.err(Status.ACC_Future, "UserRole [%s - %s] is saved for future processing",
+ return Result.err(Status.ACC_Future, "UserRole [%s - %s] is saved for future processing",
userRole.user,
userRole.role);
- } else {
+ } else {
return Result.err(rfc);
}
} else {
- return ques.userRoleDAO.delete(trans, rulr.value.get(0), false);
+ return ques.userRoleDAO().delete(trans, rulr.value.get(0), false);
}
}
- @ApiDoc(
- method = GET,
+ @ApiDoc(
+ method = GET,
path = "/authz/userRole/:user/:role",
params = {"user|string|true",
"role|string|true"},
expectedCode = 200,
- errorCodes = {403,404,406},
+ errorCodes = {403,404,406},
text = { "Returns the User (with Expiration date from listed User/Role) if it exists"
}
)
@@ -3508,7 +3584,7 @@ public class AuthzCassServiceImpl ns = ques.deriveNs(trans, role);
// if (ns.notOK()) return Result.err(ns);
-//
+//
// Result rnd = ques.mayUser(trans, trans.user(), ns.value, Access.write);
// May calling user see by virtue of the Role
Result rrdd = RoleDAO.Data.decode(trans, ques, role);
@@ -3517,30 +3593,30 @@ public class AuthzCassServiceImpl rnd = ques.mayUser(trans, trans.user(), rrdd.value,Access.read);
if (rnd.notOK()) {
- return Result.err(rnd);
+ return Result.err(rnd);
}
-
+
HashSet 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);
}
}
-
+
@SuppressWarnings("unchecked")
USERS users = (USERS) mapper.newInstance(API.USERS);
mapper.users(trans, userSet, users);
return Result.ok(users);
}
- @ApiDoc(
- method = GET,
+ @ApiDoc(
+ method = GET,
path = "/authz/users/role/:role",
params = {"user|string|true",
"role|string|true"},
expectedCode = 200,
- errorCodes = {403,404,406},
+ errorCodes = {403,404,406},
text = { "Returns the User (with Expiration date from listed User/Role) if it exists"
}
)
@@ -3553,14 +3629,14 @@ public class AuthzCassServiceImpl ns = ques.deriveNs(trans, role);
// if (ns.notOK()) return Result.err(ns);
-//
+//
// Result rnd = ques.mayUser(trans, trans.user(), ns.value, Access.write);
// May calling user see by virtue of the Role
Result rrdd = RoleDAO.Data.decode(trans, ques, role);
if (rrdd.notOK()) {
return Result.err(rrdd);
}
-
+
boolean contactOnly = false;
// Allow the request of any valid user to find the contact of the NS (Owner)
Result rnd = ques.mayUser(trans, trans.user(), rrdd.value,Access.read);
@@ -3571,10 +3647,10 @@ public class AuthzCassServiceImpl userSet = new HashSet<>();
- Result> rlurd = ques.userRoleDAO.readByRole(trans, role);
- if (rlurd.isOK()) {
+ Result> rlurd = ques.userRoleDAO().readByRole(trans, role);
+ if (rlurd.isOK()) {
for (UserRoleDAO.Data data : rlurd.value) {
if (contactOnly) { //scrub data
// Can't change actual object, or will mess up the cache.
@@ -3589,7 +3665,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);
}
-
+
boolean allInstance = ASTERIX.equals(instance);
boolean allAction = ASTERIX.equals(action);
- // Get list of roles per Permission,
+ // Get list of roles per Permission,
// Then loop through Roles to get Users
// Note: Use Sets to avoid processing or responding with Duplicates
Set roleUsed = new HashSet<>();
Set 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)) &&
+ if ((allInstance || pd.instance.equals(instance)) &&
(allAction || pd.action.equals(action))) {
if (ques.mayUser(trans, trans.user(),pd,Access.read).isOK()) {
for (String role : pd.roles) {
if (!roleUsed.contains(role)) { // avoid evaluating Role many times
roleUsed.add(role);
- Result> 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);
@@ -3668,11 +3744,11 @@ public class AuthzCassServiceImpl getHistoryByUser(final AuthzTrans trans, String user, final int[] yyyymm, final int sort) {
+ public Result getHistoryByUser(final AuthzTrans trans, String user, final int[] yyyymm, final int sort) {
final Validator v = new ServiceValidator();
if (v.nullOrBlank("User",user).err()) {
return Result.err(Status.ERR_BadData,v.errs());
@@ -3703,7 +3779,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);
}
@@ -3721,12 +3797,12 @@ public class AuthzCassServiceImpl rnd = ques.mayUser(trans, trans.user(), rrdd.value, Access.read);
if (rnd.notOK()) {
return Result.err(rnd);
}
- Result> resp = ques.historyDAO.readBySubject(trans, role, "role", yyyymm);
+ Result> resp = ques.historyDAO().readBySubject(trans, role, "role", yyyymm);
if (resp.notOK()) {
return Result.err(resp);
}
@@ -3742,16 +3818,21 @@ public class AuthzCassServiceImpl 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);
+ 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);
}
- Result> resp = ques.historyDAO.readBySubject(trans, type, "perm", yyyymm);
+
if (resp.notOK()) {
return Result.err(resp);
}
@@ -3761,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());
}
@@ -3772,10 +3852,26 @@ 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);
}
@@ -3783,7 +3879,7 @@ public class AuthzCassServiceImpl createDelegate(final AuthzTrans trans, REQUEST base) {
@@ -3799,23 +3895,23 @@ public class AuthzCassServiceImpl createOrUpdateDelegate(final AuthzTrans trans, REQUEST base, final Access access) {
final Result rd = mapper.delegate(trans, base);
final ServiceValidator v = new ServiceValidator();
- if (v.delegate(trans.org(),rd).err()) {
+ if (v.delegate(trans.org(),rd).err()) {
return Result.err(Status.ERR_BadData,v.errs());
}
final DelegateDAO.Data dd = rd.value;
-
- Result> 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()) {
+ } else if (access!=Access.create && ddr.notOKorIsEmpty()) {
return Result.err(Status.ERR_NotFound, "[%s] does not have a Delegate Record to [%s].",dd.user,access.name());
}
Result rv = ques.mayUser(trans, dd, access);
if (rv.notOK()) {
return rv;
}
-
+
Result fd = mapper.future(trans,DelegateDAO.TABLE,base, dd, false,
() -> {
StringBuilder sb = new StringBuilder();
@@ -3832,27 +3928,27 @@ public class AuthzCassServiceImpl {
return Result.ok(); // Validate in code above
});
-
+
switch(fd.status) {
case OK:
- Result rfc = func.createFuture(trans, fd.value,
+ Result rfc = func.createFuture(trans, fd.value,
dd.user, trans.user(),null, access==Access.create?FUTURE_OP.C:FUTURE_OP.U);
- if (rfc.isOK()) {
+ if (rfc.isOK()) {
return Result.err(Status.ACC_Future, "Delegate for [%s]",
dd.user);
- } else {
+ } else {
return Result.err(rfc);
}
case Status.ACC_Now:
if (access==Access.create) {
- Result 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);
@@ -3866,9 +3962,9 @@ 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);
@@ -3876,8 +3972,8 @@ public class AuthzCassServiceImpl