Merge "Sonar Fix - AuthzCassServiceImpl.java"
[aaf/authz.git] / auth / auth-service / src / main / java / org / onap / aaf / auth / service / AuthzCassServiceImpl.java
index 81a9d5e..d102b04 100644 (file)
@@ -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;
@@ -109,7 +117,8 @@ import aaf.v2_0.CredRequest;
 public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS>
     implements AuthzService            <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> {
     
-    private Mapper                    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper;
+    private static final String TWO_SPACE = "  ";
+       private Mapper                    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper;
     @Override
     public Mapper                    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper() {return mapper;}
     
@@ -168,6 +177,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(parentNs);
         }
         
+        // Note: Data validate occurs in func.createNS
         if (namespace.name.lastIndexOf('.')<0) { // Root Namespace... Function will check if allowed
             return func.createNS(trans, namespace, false);
         }
@@ -299,7 +309,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             }
 
             // Check if exists already
-            Result<List<Data>> rlnsd = ques.nsDAO.read(trans, ns);
+            Result<List<Data>> rlnsd = ques.nsDAO().read(trans, ns);
             if (rlnsd.notOKorIsEmpty()) {
                 return Result.err(rlnsd);
             }
@@ -318,7 +328,8 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
 
             // Add Attrib
             nsd.attrib.put(key, value);
-            ques.nsDAO.dao().attribAdd(trans,ns,key,value);
+            ques.nsDAO().dao().attribAdd(trans,ns,key,value);
+            ques.nsDAO().invalidate(trans, nsd);
             return Result.ok();
         } finally {
             tt.done();
@@ -349,7 +360,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(Status.ERR_Denied,"%s may not read NS by Attrib '%s'",trans.user(),key);
         }
 
-        Result<Set<String>> rsd = ques.nsDAO.dao().readNsByAttrib(trans, key);
+        Result<Set<String>> rsd = ques.nsDAO().dao().readNsByAttrib(trans, key);
         if (rsd.notOK()) {
             return Result.err(rsd);
         }
@@ -382,7 +393,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             }
 
             // Check if exists already (NS must exist)
-            Result<List<Data>> rlnsd = ques.nsDAO.read(trans, ns);
+            Result<List<Data>> rlnsd = ques.nsDAO().read(trans, ns);
             if (rlnsd.notOKorIsEmpty()) {
                 return Result.err(rlnsd);
             }
@@ -401,8 +412,8 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
 
             // Add Attrib
             nsd.attrib.put(key, value);
-
-            return ques.nsDAO.update(trans,nsd);
+            ques.nsDAO().invalidate(trans, nsd);
+            return ques.nsDAO().update(trans,nsd);
  
         } finally {
             tt.done();
@@ -433,7 +444,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             }
 
             // Check if exists already
-            Result<List<Data>> rlnsd = ques.nsDAO.read(trans, ns);
+            Result<List<Data>> rlnsd = ques.nsDAO().read(trans, ns);
             if (rlnsd.notOKorIsEmpty()) {
                 return Result.err(rlnsd);
             }
@@ -451,7 +462,8 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
 
             // Add Attrib
             nsd.attrib.remove(key);
-            ques.nsDAO.dao().attribRemove(trans,ns,key);
+            ques.nsDAO().dao().attribRemove(trans,ns,key);
+            ques.nsDAO().invalidate(trans, nsd);
             return Result.ok();
         } finally {
             tt.done();
@@ -465,8 +477,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             expectedCode = 200,
             errorCodes = { 404,406 }, 
             text = {     
-                "Lists the Admin(s), Responsible Party(s), Role(s), Permission(s)",
-                "Credential(s) and Expiration of Credential(s) in Namespace :id",
+                "Lists the Owner(s), Admin(s), Description, and Attributes of Namespace :id",
             }
             )
     @Override
@@ -476,7 +487,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(Status.ERR_BadData,v.errs());
         }
         
-        Result<List<NsDAO.Data>> rlnd = ques.nsDAO.read(trans, ns);
+        Result<List<NsDAO.Data>> rlnd = ques.nsDAO().read(trans, ns);
         if (rlnd.isOK()) {
             if (rlnd.isEmpty()) {
                 return Result.err(Status.ERR_NotFound, "No data found for %s",ns);
@@ -563,7 +574,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
     }
 
     private Result<Collection<Namespace>> loadNamepace(AuthzTrans trans, String user, String endsWith, boolean full) {
-        Result<List<UserRoleDAO.Data>> urd = ques.userRoleDAO.readByUser(trans, user);
+        Result<List<UserRoleDAO.Data>> urd = ques.userRoleDAO().readByUser(trans, user);
         if (urd.notOKorIsEmpty()) {
             return Result.err(urd);
         }
@@ -679,7 +690,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
 
         Set<Namespace> lm = new HashSet<>();
-        Result<List<NsDAO.Data>> rlnd = ques.nsDAO.dao().getChildren(trans, parent);
+        Result<List<NsDAO.Data>> 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);
@@ -727,7 +738,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
 
         Namespace namespace = nsd.value;
-        Result<List<NsDAO.Data>> rlnd = ques.nsDAO.read(trans, namespace.name);
+        Result<List<NsDAO.Data>> rlnd = ques.nsDAO().read(trans, namespace.name);
         
         if (rlnd.notOKorIsEmpty()) {
             return Result.err(Status.ERR_NotFound, "Namespace [%s] does not exist",namespace.name);
@@ -737,7 +748,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(Status.ERR_Denied, "You do not have approval to change %s",namespace.name);
         }
 
-        Result<Void> rdr = ques.nsDAO.dao().addDescription(trans, namespace.name, namespace.description);
+        Result<Void> rdr = ques.nsDAO().dao().addDescription(trans, namespace.name, namespace.description);
         if (rdr.isOK()) {
             return Result.ok();
         } else {
@@ -797,56 +808,129 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
     @Override
     public Result<Void> createPerm(final AuthzTrans trans,REQUEST rreq) {        
         final Result<PermDAO.Data> newPd = mapper.perm(trans, rreq);
+
         final ServiceValidator v = new ServiceValidator();
         if (v.perm(newPd).err()) {
             return Result.err(Status.ERR_BadData,v.errs());
         }
-        
-        Result<FutureDAO.Data> 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<NsDAO.Data> nsd;
-                @Override
-                public Result<?> mayChange() {
-                    if (nsd==null) {
-                        nsd = ques.mayUser(trans, trans.user(), newPd.value, Access.write);
-                    }
-                    return nsd;
-                }
-            });
-        Result<List<NsDAO.Data>> 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<List<PermDAO.Data>> 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<PermDAO.Data> rpdd = permDAO.create(trans, pdd);
+                               if(rpdd.notOK()) {
+                                       return Result.err(rpdd);
+                               }
+                               
+                       CachedRoleDAO roleDAO = ques.roleDAO();
+                       Result<List<RoleDAO.Data>> 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<Void> 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<List<UserRoleDAO.Data>> 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<UserRoleDAO.Data> 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<FutureDAO.Data> 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<NsDAO.Data> nsd;
+                       @Override
+                       public Result<?> mayChange() {
+                           if (nsd==null) {
+                               nsd = ques.mayUser(trans, trans.user(), newPd.value, Access.write);
+                           }
+                           return nsd;
+                       }
+                   });
+               
+               Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, newPd.value.ns);
+               if (nsr.notOKorIsEmpty()) {
+                   return Result.err(nsr);
+               }
+               switch(fd.status) {
+                   case OK:
+                       Result<String> 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<String> 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( 
@@ -929,8 +1013,8 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(Status.ERR_BadData,v.errs());
         }
 
-        Result<List<PermDAO.Data>> rlpd = ques.getPermsByUser(trans, user, 
-                trans.requested(force));
+        PermLookup pl = PermLookup.get(trans,ques,user);
+        Result<List<PermDAO.Data>> rlpd = pl.getPerms(trans.requested(force));
         if (rlpd.notOK()) {
             return Result.err(rlpd);
         }
@@ -1018,7 +1102,8 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
         
         //////////////
-        Result<List<PermDAO.Data>> rlpd = ques.getPermsByUser(trans, user,trans.requested(force));
+        PermLookup pl = PermLookup.get(trans,ques,user);
+        Result<List<PermDAO.Data>> rlpd = pl.getPerms(trans.requested(force));
         if (rlpd.notOK()) {
             return Result.err(rlpd);
         }
@@ -1138,7 +1223,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(rnd);     
         }
         
-        Result<List<PermDAO.Data>> rlpd = ques.permDAO.readNS(trans, ns);
+        Result<List<PermDAO.Data>> rlpd = ques.permDAO().readNS(trans, ns);
         if (rlpd.notOK()) {
             return Result.err(rlpd);
         }
@@ -1176,7 +1261,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
         
         Result<NsSplit> nss = ques.deriveNsSplit(trans, origType);
-        Result<List<PermDAO.Data>> origRlpd = ques.permDAO.read(trans, nss.value.ns, nss.value.name, origInstance, origAction); 
+        Result<List<PermDAO.Data>> origRlpd = ques.permDAO().read(trans, nss.value.ns, nss.value.name, origInstance, origAction); 
         
         if (origRlpd.notOKorIsEmpty()) {
             return Result.err(Status.ERR_PermissionNotFound, 
@@ -1235,7 +1320,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(Status.ERR_BadData,v.errs());
         }
         final PermDAO.Data perm = pd.value;
-        if (ques.permDAO.read(trans, perm.ns, perm.type, perm.instance,perm.action).notOKorIsEmpty()) {
+        if (ques.permDAO().read(trans, perm.ns, perm.type, perm.instance,perm.action).notOKorIsEmpty()) {
             return Result.err(Status.ERR_NotFound, "Permission [%s.%s|%s|%s] does not exist",
                 perm.ns,perm.type,perm.instance,perm.action);
         }
@@ -1245,12 +1330,12 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                     perm.ns,perm.type,perm.instance,perm.action);
         }
 
-        Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, pd.value.ns);
+        Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, pd.value.ns);
         if (nsr.notOKorIsEmpty()) {
             return Result.err(nsr);
         }
 
-        Result<Void> rdr = ques.permDAO.addDescription(trans, perm.ns, perm.type, perm.instance,
+        Result<Void> rdr = ques.permDAO().addDescription(trans, perm.ns, perm.type, perm.instance,
                 perm.action, perm.description);
         if (rdr.isOK()) {
             return Result.ok();
@@ -1287,7 +1372,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
 
         // Read full set to get CURRENT values
-        Result<List<PermDAO.Data>> rcurr = ques.permDAO.read(trans, 
+        Result<List<PermDAO.Data>> rcurr = ques.permDAO().read(trans, 
                 updt.value.ns, 
                 updt.value.type, 
                 updt.value.instance, 
@@ -1321,7 +1406,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                 if (!currRoles.contains(role)) {
                     Result<RoleDAO.Data> key = RoleDAO.Data.decode(trans, ques, role);
                     if (key.isOKhasData()) {
-                        Result<List<RoleDAO.Data>> rrd = ques.roleDAO.read(trans, key.value);
+                        Result<List<RoleDAO.Data>> 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    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                 if (!updtRoles.contains(role)) {
                     Result<RoleDAO.Data> key = RoleDAO.Data.decode(trans, ques, role);
                     if (key.isOKhasData()) {
-                        Result<List<RoleDAO.Data>> rdd = ques.roleDAO.read(trans, key.value);
+                        Result<List<RoleDAO.Data>> rdd = ques.roleDAO().read(trans, key.value);
                         if (rdd.isOKhasData()) {
                             for (RoleDAO.Data r : rdd.value) {
                                 rv = func.delPermFromRole(trans, r, curr, true);
@@ -1380,11 +1465,11 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(Status.ERR_BadData,v.errs());
         }
         final PermDAO.Data perm = pd.value;
-        if (ques.permDAO.read(trans, perm).notOKorIsEmpty()) {
+        if (ques.permDAO().read(trans, perm).notOKorIsEmpty()) {
             return Result.err(Status.ERR_PermissionNotFound, "Permission [%s.%s|%s|%s] does not exist",
                     perm.ns,perm.type,perm.instance,perm.action    );
         }
-
+        
         Result<FutureDAO.Data> fd = mapper.future(trans,PermDAO.TABLE,from,perm,false,
                 new Mapper.Memo() {
                     @Override
@@ -1405,7 +1490,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         
         switch(fd.status) {
         case OK:
-            Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, perm.ns);
+            Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, perm.ns);
             if (nsr.notOKorIsEmpty()) {
                 return Result.err(nsr);
             }
@@ -1483,12 +1568,17 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
     @Override
     public Result<Void> createRole(final AuthzTrans trans, REQUEST from) {
         final Result<RoleDAO.Data> 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");
         }
 
@@ -1512,7 +1602,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                 }
             });
         
-        Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, rd.value.ns);
+        Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, rd.value.ns);
         if (nsr.notOKorIsEmpty()) {
             return Result.err(nsr);
         }
@@ -1529,7 +1619,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                     return Result.err(rfc);
                 }
             case Status.ACC_Now:
-                Result<RoleDAO.Data> rdr = ques.roleDAO.create(trans, role);
+                Result<RoleDAO.Data> rdr = ques.roleDAO().create(trans, role);
                 if (rdr.isOK()) {
                     return Result.ok();
                 } else {
@@ -1608,10 +1698,10 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         ROLES roles = mapper.newInstance(API.ROLES);
         // Get list of roles per user, then add to Roles as we go
         Result<List<RoleDAO.Data>> rlrd;
-        Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByUser(trans, user);
+        Result<List<UserRoleDAO.Data>> 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()) {
@@ -1658,7 +1748,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         try {
             ROLES roles = mapper.newInstance(API.ROLES);
             // Get list of roles per user, then add to Roles as we go
-            Result<List<RoleDAO.Data>> rlrd = ques.roleDAO.readNS(trans, ns);
+            Result<List<RoleDAO.Data>> 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.
@@ -1700,7 +1790,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         try {
             ROLES roles = mapper.newInstance(API.ROLES);
             // Get list of roles per user, then add to Roles as we go
-            Result<List<RoleDAO.Data>> rlrd = ques.roleDAO.readName(trans, name);
+            Result<List<RoleDAO.Data>> rlrd = ques.roleDAO().readName(trans, name);
             if (rlrd.isOK()) {
                 if (!rlrd.isEmpty()) {
                     // Note: Mapper will restrict what can be viewed
@@ -1757,13 +1847,13 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                     return Result.err(res);
                 }
                 
-                Result<List<PermDAO.Data>> pdlr = ques.permDAO.read(trans, pdd);
+                Result<List<PermDAO.Data>> pdlr = ques.permDAO().read(trans, pdd);
                 if (pdlr.isOK())for (PermDAO.Data pd : pdlr.value) {
                     Result<List<RoleDAO.Data>> rlrd;
                     for (String r : pd.roles) {
                         Result<String[]> 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    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
         }
         final RoleDAO.Data role = rd.value;
-        if (ques.roleDAO.read(trans, role.ns, role.name).notOKorIsEmpty()) {
+        if (ques.roleDAO().read(trans, role.ns, role.name).notOKorIsEmpty()) {
             return Result.err(Status.ERR_NotFound, "Role [" + role.fullName() + "] does not exist");
         }
 
@@ -1807,12 +1897,12 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(Status.ERR_Denied, "You do not have approval to change " + role.fullName());
         }
 
-        Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, rd.value.ns);
+        Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, rd.value.ns);
         if (nsr.notOKorIsEmpty()) {
             return Result.err(nsr);
         }
 
-        Result<Void> rdr = ques.roleDAO.addDescription(trans, role.ns, role.name, role.description);
+        Result<Void> rdr = ques.roleDAO().addDescription(trans, role.ns, role.name, role.description);
         if (rdr.isOK()) {
             return Result.ok();
         } else {
@@ -1861,13 +1951,13 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(Status.ERR_BadData,v.errs());
         }
 
-        Result<List<RoleDAO.Data>> rlrd = ques.roleDAO.read(trans, rrd.value.ns, rrd.value.name);
+        Result<List<RoleDAO.Data>> 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<List<PermDAO.Data>> rlpd = ques.permDAO.read(trans, rpd.value.ns, 
+        Result<List<PermDAO.Data>> 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
@@ -1904,41 +1994,44 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                     public Result<?> 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<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, rpd.value.ns);
+        Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, rpd.value.ns);
         if (nsr.notOKorIsEmpty()) {
             return Result.err(nsr);
         }
         switch(fd.status) {
-        case OK:
-            Result<String> 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<Void> 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<String> 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<Void> 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);
         }
         
     }
@@ -1980,7 +2073,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
     }
         
     private Result<Void> delPermFromRole(final AuthzTrans trans, PermDAO.Data pdd, RoleDAO.Data rdd, REQUEST rreq) {        
-        Result<List<PermDAO.Data>> rlpd = ques.permDAO.read(trans, pdd.ns, pdd.type, 
+        Result<List<PermDAO.Data>> rlpd = ques.permDAO().read(trans, pdd.ns, pdd.type, 
                 pdd.instance, pdd.action);
         
         if (rlpd.notOKorIsEmpty()) {
@@ -2007,7 +2100,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                         return nsd;
                     }
                 });
-        Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, pdd.ns);
+        Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, pdd.ns);
         if (nsr.notOKorIsEmpty()) {
             return Result.err(nsr);
         }
@@ -2070,12 +2163,12 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                 return Result.err(rrns);
             }
             
-        final Result<List<RoleDAO.Data>> rrd = ques.roleDAO.read(trans, rrns.value.parent, rrns.value.name);
+        final Result<List<RoleDAO.Data>> rrd = ques.roleDAO().read(trans, rrns.value.parent, rrns.value.name);
         if (rrd.notOKorIsEmpty()) {
             return Result.err(rrd);
         }
         
-        final Result<List<PermDAO.Data>> rpd = ques.permDAO.read(trans, rpns.value.parent, rpns.value.name, instance, action);
+        final Result<List<PermDAO.Data>> rpd = ques.permDAO().read(trans, rpns.value.parent, rpns.value.name, instance, action);
         if (rpd.notOKorIsEmpty()) {
             return Result.err(rpd);
         }
@@ -2131,7 +2224,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(Status.ERR_BadData,v.errs());
         }
         final RoleDAO.Data role = rd.value;
-        if (ques.roleDAO.read(trans, role).notOKorIsEmpty() && !trans.requested(force)) {
+        if (ques.roleDAO().read(trans, role).notOKorIsEmpty() && !trans.requested(force)) {
             return Result.err(Status.ERR_RoleNotFound, "Role [" + role.fullName() + "] does not exist");
         }
 
@@ -2151,7 +2244,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         
         switch(fd.status) {
         case OK:
-            Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, rd.value.ns);
+            Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, rd.value.ns);
             if (nsr.notOKorIsEmpty()) {
                 return Result.err(nsr);
             }
@@ -2216,40 +2309,59 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
     }
 
     private class MayChangeCred implements MayChange {
-        
-        private Result<NsDAO.Data> nsd;
+        private static final String EXTEND = "extend";
+               private static final String RESET = "reset";
+               private static final String DELETE = "delete";
+               private Result<NsDAO.Data> 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;
@@ -2277,7 +2389,6 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         try {
             Result<CredDAO.Data> 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();
@@ -2299,7 +2410,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                     return Result.err(Status.ERR_Policy,"MechIDs must be registered with %s before provisioning in AAF",org.getName());
                 }
 
-                Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, rcred.value.ns);
+                Result<List<NsDAO.Data>> 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);
                 }
@@ -2309,7 +2420,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                 MayChange mc;
                 
                 CassExecutor exec = new CassExecutor(trans, func);
-                Result<List<CredDAO.Data>> rlcd = ques.credDAO.readID(trans, rcred.value.id);
+                Result<List<CredDAO.Data>> 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");
@@ -2320,14 +2431,28 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                         // Note: ASPR specifies character differences, but we don't actually store the
                         // password to validate char differences.
                         
-                        rb = ques.userCredCheck(trans, curr, rawCred);
-                        if (rb.notOK()) {
-                            return Result.err(rb);
-                        } else if (rb.value){
-                            return Result.err(Status.ERR_Policy, "Credential content cannot be reused.");
-                        } else if (Chrono.dateOnlyStamp(curr.expires).equals(Chrono.dateOnlyStamp(rcred.value.expires)) && curr.type==rcred.value.type) {
-                            return Result.err(Status.ERR_ConflictAlreadyExists, "Credential with same Expiration Date exists, use 'reset'");
-                        }
+//                      byte[] rawCred = rcred.value.type==CredDAO.RAW?null:;                            return Result.err(Status.ERR_ConflictAlreadyExists, "Credential with same Expiration Date exists");
+                       if(rcred.value.type==CredDAO.FQI ) {
+                               if(curr.type==CredDAO.FQI) {
+                               return Result.err(Status.ERR_ConflictAlreadyExists, "Credential with same Expiration Date exists");
+                               }
+                       } else {
+       
+                               rb = ques.userCredCheck(trans, curr, rcred.value.cred!=null?rcred.value.cred.array():null);
+                               if (rb.notOK()) {
+                                   return Result.err(rb);
+                               } else if (rb.value){
+                                   return Result.err(Status.ERR_Policy, "Credential content cannot be reused.");
+                               } else if(Chrono.dateOnlyStamp(curr.expires).equals(Chrono.dateOnlyStamp(rcred.value.expires)) 
+                                               && curr.type==rcred.value.type 
+                                               ) {
+                                       // Allow if expiring differential is greater than 1 day (for TEMP)
+                                       // Unless expiring in 1 day
+                                       if(System.currentTimeMillis() - rcred.value.expires.getTime() > TimeUnit.DAYS.toMillis(1)) {
+                                               return Result.err(Status.ERR_ConflictAlreadyExists, "Credential with same Expiration Date exists");
+                                       }
+                               }
+                       }
                     }    
                 } else {
                     try {
@@ -2335,7 +2460,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                         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;
@@ -2383,20 +2508,27 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                     case Status.ACC_Now:
                         try {
                             if (firstID) {
-    //                            && !nsr.value.get(0).isAdmin(trans.getUserPrincipal().getName())) {
-                                Result<List<String>> 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();
                         }
@@ -2442,7 +2574,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         TimeTaken tt = trans.start("MAP Creds by NS to Creds", Env.SUB);
         try {            
             USERS users = mapper.newInstance(API.USERS);
-            Result<List<CredDAO.Data>> rlcd = ques.credDAO.readNS(trans, ns);
+            Result<List<CredDAO.Data>> rlcd = ques.credDAO().readNS(trans, ns);
                     
             if (rlcd.isOK()) {
                 if (!rlcd.isEmpty()) {
@@ -2489,7 +2621,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         TimeTaken tt = trans.start("MAP Creds by ID to Creds", Env.SUB);
         try {            
             USERS users = mapper.newInstance(API.USERS);
-            Result<List<CredDAO.Data>> rlcd = ques.credDAO.readID(trans, id);
+            Result<List<CredDAO.Data>> rlcd = ques.credDAO().readID(trans, id);
                     
             if (rlcd.isOK()) {
                 if (!rlcd.isEmpty()) {
@@ -2519,7 +2651,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         TimeTaken tt = trans.start("Get Cert Info by ID", Env.SUB);
         try {            
             CERTS certs = mapper.newInstance(API.CERTS);
-            Result<List<CertDAO.Data>> rlcd = ques.certDAO.readID(trans, id);
+            Result<List<CertDAO.Data>> rlcd = ques.certDAO().readID(trans, id);
                     
             if (rlcd.isOK()) {
                 if (!rlcd.isEmpty()) {
@@ -2547,7 +2679,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                      }
             )
     @Override
-    public Result<Void> changeUserCred(final AuthzTrans trans, REQUEST from) {
+    public Result<Void> 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    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                 if (v.cred(trans, trans.org(),rcred,false).err()) {// Note: Creates have stricter Validations 
                     return Result.err(Status.ERR_BadData,v.errs());
                 }
-                Result<List<CredDAO.Data>> rlcd = ques.credDAO.readID(trans, rcred.value.id);
+                Result<List<CredDAO.Data>> 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<Integer> ri = selectEntryIfMultiple((CredRequest)from, rlcd.value);
+                List<CredDAO.Data> lcdd = filterList(rlcd.value,CredDAO.BASIC_AUTH, CredDAO.BASIC_AUTH_SHA256);
+                
+                Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, lcdd, MayChangeCred.RESET);
                 if (ri.notOK()) {
                     return Result.err(ri);
                 }
@@ -2592,7 +2726,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                 },
                 mc);
                 
-                Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, rcred.value.ns);
+                Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, rcred.value.ns);
                 if (nsr.notOKorIsEmpty()) {
                     return Result.err(nsr);
                 }
@@ -2634,9 +2768,9 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                             rcred.value.expires = org.expiration(null,exp).getTime();
                         }
 
-                        udr = ques.credDAO.create(trans, rcred.value);
+                        udr = ques.credDAO().create(trans, rcred.value);
                         if (udr.isOK()) {
-                            udr = ques.credDAO.delete(trans, rlcd.value.get(entry),false);
+                            udr = ques.credDAO().delete(trans, rlcd.value.get(entry),false);
                         }
                         if (udr.isOK()) {
                             return Result.ok();
@@ -2654,27 +2788,6 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
     }
 
-    /*
-     * Codify the way to get Either Choice Needed or actual Integer from Credit Request
-     */
-    private Result<Integer> selectEntryIfMultiple(final CredRequest cr, List<CredDAO.Data> 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,  
             path = "/authn/cred/:days",
@@ -2712,18 +2825,22 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             }
     
             // Get the list of Cred Entries
-            Result<List<CredDAO.Data>> rlcd = ques.credDAO.readID(trans, cred.value.id);
+            Result<List<CredDAO.Data>> 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<CredDAO.Data> lcdd = filterList(rlcd.value,CredDAO.BASIC_AUTH, CredDAO.BASIC_AUTH_SHA256);
 
             //Need to do the "Pick Entry" mechanism
-            Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, rlcd.value);
+            // Note, this sorts
+            Result<Integer> 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    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             cd.type = found.type;
             cd.ns = found.ns;
             cd.notes = "Extended";
-            cd.expires = org.expiration(null, Expiration.ExtendPassword,days).getTime();
             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();
             }
@@ -2745,172 +2865,279 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
     }    
 
-    private String[] buildVariables(List<CredDAO.Data> 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<Void> deleteUserCred(AuthzTrans trans, REQUEST from)  {
+           final Result<CredDAO.Data> 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<List<CredDAO.Data>> rlcd = ques.credDAO().readID(trans, cred.value.id);
+           if (rlcd.notOKorIsEmpty()) {
+               // Empty Creds should not have user_roles.
+               Result<List<UserRoleDAO.Data>> 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<CredDAO.Data> 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<FutureDAO.Data> fd = mapper.future(trans,CredDAO.TABLE,from,cred.value,false,
+               () -> "Delete Credential [" +
+                   cred.value.id +
+                   ']',
+               mc);
+       
+           Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, cred.value.ns);
+           if (nsr.notOKorIsEmpty()) {
+               return Result.err(nsr);
+           }
+       
+           switch(fd.status) {
+               case OK:
+                   Result<String> 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:
+                   Result<?>udr = 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<List<UserRoleDAO.Data>> 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<Integer> selectEntryIfMultiple(final CredRequest cr, List<CredDAO.Data> 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<CredDAO.Data> filterList(List<CredDAO.Data> orig, Integer ... types) {
+       List<CredDAO.Data> 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<CredDAO.Data> 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<CredDAO.Data> value, boolean isDelete) {
+    private String selectCredFromList(List<CredDAO.Data> 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<value.size();++i) {
             errMessage.append("    %s\n");
         }
-        errMessage.append("Run same command again with chosen entry as last parameter");
-        
-        return errMessage.toString();
-        
-    }
-
-    @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<Void> deleteUserCred(AuthzTrans trans, REQUEST from)  {
-        final Result<CredDAO.Data> 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<List<CredDAO.Data>> rlcd = ques.credDAO.readID(trans, cred.value.id);
-        if (rlcd.notOKorIsEmpty()) {
-            // Empty Creds should have no user_roles.
-            Result<List<UserRoleDAO.Data>> 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);
-                    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;
-                                }
-                                ++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<FutureDAO.Data> fd = mapper.future(trans,CredDAO.TABLE,from,cred.value,false,
-            () -> "Delete Credential [" +
-                cred.value.id +
-                ']',
-            mc);
-    
-        Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, cred.value.ns);
-        if (nsr.notOKorIsEmpty()) {
-            return Result.err(nsr);
-        }
-    
-        switch(fd.status) {
-            case OK:
-                Result<String> 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:
-                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);
-                    }
-                    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<List<UserRoleDAO.Data>> 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<Date> doesCredentialMatch(AuthzTrans trans, REQUEST credReq) {
         TimeTaken tt = trans.start("Does Credential Match", Env.SUB);
@@ -2935,22 +3162,6 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
     }
 
-    @ApiDoc( 
-            method = GET,  
-            path = "/authn/basicAuth",
-            params = {},
-            expectedCode = 200,
-            errorCodes = { 403 }, 
-            text = { "!!!! DEPRECATED without X509 Authentication STOP USING THIS API BY DECEMBER 2017, or use Certificates !!!!\n" 
-                    + "Use /authn/validate instead\n"
-                    + "Note: Validate a Password using BasicAuth Base64 encoded Header. This HTTP/S call is intended as a fast"
-                    + " User/Password lookup for Security Frameworks, and responds 200 if it passes BasicAuth "
-                + "security, and 403 if it does not." }
-            )
-    private void basicAuth() {
-        // This is a place holder for Documentation.  The real BasicAuth API does not call Service.
-    }
-    
     @ApiDoc( 
             method = POST,  
             path = "/authn/validate",
@@ -2981,6 +3192,22 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         return Result.err(Status.ERR_Denied,"Bad Basic Auth");
     }
 
+@ApiDoc( 
+               method = GET,  
+               path = "/authn/basicAuth",
+               params = {},
+               expectedCode = 200,
+               errorCodes = { 403 }, 
+               text = { "!!!! DEPRECATED without X509 Authentication STOP USING THIS API BY DECEMBER 2017, or use Certificates !!!!\n" 
+                       + "Use /authn/validate instead\n"
+                       + "Note: Validate a Password using BasicAuth Base64 encoded Header. This HTTP/S call is intended as a fast"
+                       + " User/Password lookup for Security Frameworks, and responds 200 if it passes BasicAuth "
+                   + "security, and 403 if it does not." }
+               )
+       private void basicAuth() {
+           // This is a place holder for Documentation.  The real BasicAuth API does not call Service.
+       }
+
 /***********************************
  * USER-ROLE 
  ***********************************/
@@ -3008,7 +3235,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             final UserRoleDAO.Data userRole = urr.value;
             
             final ServiceValidator v = new ServiceValidator();
-            if (v.user_role(userRole).err() ||
+            if (v.user_role(trans.user(),userRole).err() ||
                v.user(trans.org(), userRole.user).err()) {
                 return Result.err(Status.ERR_BadData,v.errs());
             }
@@ -3024,6 +3251,9 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                     private Result<NsDAO.Data> 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,15 +3261,24 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                         return nsd;
                     }
                 });
-            Result<NsDAO.Data> 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<NsDAO.Data> nsr = ques.deriveNs(trans, userRole.role);
+                   if (nsr.notOK()) {
+                       return Result.err(nsr);
+                   }
+                   ndd = nsr.value;
             }
 
             switch(fd.status) {
                 case OK:
                     Result<String> 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,
@@ -3094,7 +3333,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             
             // Get list of roles per user, then add to Roles as we go
             HashSet<UserRoleDAO.Data> userSet = new HashSet<>();
-            Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByRole(trans, role);
+            Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readByRole(trans, role);
             if (rlurd.isOK()) {
                 for (UserRoleDAO.Data data : rlurd.value) {
                     userSet.add(data);
@@ -3127,7 +3366,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             }
             
             // Get list of roles per user, then add to Roles as we go
-            Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByUser(trans, user);
+            Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readByUser(trans, user);
             if (rlurd.notOK()) { 
                 return Result.err(rlurd);
             }
@@ -3188,172 +3427,9 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
 
         
-    @ApiDoc( 
-            method = PUT,  
-            path = "/authz/userRole/user",
-            params = {},
-            expectedCode = 200,
-            errorCodes = {403,404,406}, 
-            text = { "Set a User's roles to the roles specified in the UserRoleRequest object.",
-                        "WARNING: Roles supplied will be the ONLY roles attached to this user",
-                        "If no roles are supplied, user's roles are reset."
-                   }
-            )
-    @Override
-    public Result<Void> resetRolesForUser(AuthzTrans trans, REQUEST rreq) {
-        Result<UserRoleDAO.Data> 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<String> currRoles = new HashSet<>();
-        Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByUser(trans, rurdd.value.user);
-        if (rlurd.isOK()) {
-            for (UserRoleDAO.Data data : rlurd.value) {
-                currRoles.add(data.role);
-            }
-        }
-        
-        Result<Void> 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<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans, ques, role);
-            if (rrdd.notOK()) {
-                return Result.err(rrdd);
-            }
-            
-            rurdd.value.role(rrdd.value);
-            
-            Result<NsDAO.Data> nsd = ques.mayUser(trans, trans.user(), rrdd.value,Access.write);
-            if (nsd.notOK()) {
-                return Result.err(nsd);
-            }
-            Result<NsDAO.Data> 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<Void> resetUsersForRole(AuthzTrans trans, REQUEST rreq) {
-        Result<UserRoleDAO.Data> 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<NsDAO.Data> nsd = ques.mayUser(trans, trans.user(), rd, Access.write);
-        if (nsd.notOK()) {
-            return Result.err(nsd);
-        }
-
-        Result<NsDAO.Data> nsr = ques.deriveNs(trans, rurdd.value.role);
-        if (nsr.notOKorIsEmpty()) {
-            return Result.err(nsr);    
-        }
-
-        Set<String> currUsers = new HashSet<>();
-        Result<List<UserRoleDAO.Data>> 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<Void> 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",
@@ -3386,7 +3462,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(rcr);
         }
         
-        Result<List<UserRoleDAO.Data>> rr = ques.userRoleDAO.read(trans, user,role);
+        Result<List<UserRoleDAO.Data>> rr = ques.userRoleDAO().read(trans, user,role);
         if (rr.notOK()) {
             return Result.err(rr);
         }
@@ -3461,7 +3537,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
 
         Result<List<UserRoleDAO.Data>> 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 + " ]");
         }
@@ -3485,7 +3561,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                 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);
         }
     }
 
@@ -3521,7 +3597,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
         
         HashSet<UserRoleDAO.Data> userSet = new HashSet<>();
-        Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readUserInRole(trans, user, role);
+        Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readUserInRole(trans, user, role);
         if (rlurd.isOK()) {
             for (UserRoleDAO.Data data : rlurd.value) {
                 userSet.add(data);
@@ -3573,7 +3649,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
         
         HashSet<UserRoleDAO.Data> userSet = new HashSet<>();
-        Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByRole(trans, role);
+        Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readByRole(trans, role);
         if (rlurd.isOK()) { 
             for (UserRoleDAO.Data data : rlurd.value) {
                 if (contactOnly) { //scrub data
@@ -3626,7 +3702,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(nss);
         }
         
-        Result<List<NsDAO.Data>> nsd = ques.nsDAO.read(trans, nss.value.ns);
+        Result<List<NsDAO.Data>> nsd = ques.nsDAO().read(trans, nss.value.ns);
         if (nsd.notOK()) {
             return Result.err(nsd);
         }
@@ -3640,7 +3716,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         Set<UserRoleDAO.Data> userSet = new HashSet<>();
         
         if (!nss.isEmpty()) {
-            Result<List<PermDAO.Data>> rlp = ques.permDAO.readByType(trans, nss.value.ns, nss.value.name);
+            Result<List<PermDAO.Data>> 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)) && 
@@ -3649,7 +3725,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                             for (String role : pd.roles) {
                                 if (!roleUsed.contains(role)) { // avoid evaluating Role many times
                                     roleUsed.add(role);
-                                    Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByRole(trans, role.replace('|', '.'));
+                                    Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readByRole(trans, role.replace('|', '.'));
                                     if (rlurd.isOKhasData()) {
                                         for (UserRoleDAO.Data urd : rlurd.value) {
                                             userSet.add(urd);
@@ -3668,7 +3744,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         return Result.ok(users);
     }
 
-    /***********************************
+/***********************************
  * HISTORY 
  ***********************************/    
     @Override
@@ -3703,7 +3779,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                 }
             }
          }
-        Result<List<HistoryDAO.Data>> resp = ques.historyDAO.readByUser(trans, user, yyyymm);
+        Result<List<HistoryDAO.Data>> resp = ques.historyDAO().readByUser(trans, user, yyyymm);
         if (resp.notOK()) {
             return Result.err(resp);
         }
@@ -3726,7 +3802,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         if (rnd.notOK()) {
             return Result.err(rnd);
         }
-        Result<List<HistoryDAO.Data>> resp = ques.historyDAO.readBySubject(trans, role, "role", yyyymm); 
+        Result<List<HistoryDAO.Data>> resp = ques.historyDAO().readBySubject(trans, role, "role", yyyymm); 
         if (resp.notOK()) {
             return Result.err(resp);
         }
@@ -3742,16 +3818,21 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
 
         // May user see Namespace of Permission (since it's only one piece... we can't check for "is permission part of")
-        Result<NsDAO.Data> rnd = ques.deriveNs(trans,type);
-        if (rnd.notOK()) {
-            return Result.err(rnd);
+        Result<List<HistoryDAO.Data>> resp;
+        if(type.startsWith(trans.user())) {
+               resp = ques.historyDAO().readBySubject(trans, type, "perm", yyyymm);
+        } else {
+            Result<NsDAO.Data> 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<List<HistoryDAO.Data>> resp = ques.historyDAO.readBySubject(trans, type, "perm", yyyymm);
         if (resp.notOK()) {
             return Result.err(resp);
         }
@@ -3761,8 +3842,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
     @Override
     public Result<HISTORY> 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());
         }
 
@@ -3775,7 +3855,23 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(rnd);    
         }
 
-        Result<List<HistoryDAO.Data>> resp = ques.historyDAO.readBySubject(trans, ns, "ns", yyyymm);
+        Result<List<HistoryDAO.Data>> 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<HISTORY> getHistoryBySubject(AuthzTrans trans, String subject, String target, int[] yyyymm, final int sort) {
+       NsDAO.Data ndd = new NsDAO.Data();
+       ndd.name = FQI.reverseDomain(subject);
+        Result<Data> rnd = ques.mayUser(trans, trans.user(), ndd, Access.read);
+        if (rnd.notOK()) {
+            return Result.err(rnd);    
+        }
+
+        Result<List<HistoryDAO.Data>> resp = ques.historyDAO().readBySubject(trans, subject, target, yyyymm);
         if (resp.notOK()) {
             return Result.err(resp);
         }
@@ -3805,7 +3901,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
 
         final DelegateDAO.Data dd = rd.value;
         
-        Result<List<DelegateDAO.Data>> ddr = ques.delegateDAO.read(trans, dd);
+        Result<List<DelegateDAO.Data>> 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()) { 
@@ -3845,14 +3941,14 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                 }
             case Status.ACC_Now:
                 if (access==Access.create) {
-                    Result<DelegateDAO.Data> rdr = ques.delegateDAO.create(trans, dd);
+                    Result<DelegateDAO.Data> 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);
@@ -3868,7 +3964,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
         
         Result<List<DelegateDAO.Data>> 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);
@@ -3877,7 +3973,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return rv;
         }
         
-        return ques.delegateDAO.delete(trans, dd, false);
+        return ques.delegateDAO().delete(trans, dd, false);
     }
 
     @Override
@@ -3889,7 +3985,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         }
         dd.user = userName;
         Result<List<DelegateDAO.Data>> 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);
@@ -3898,7 +3994,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return rv;
         }
         
-        return ques.delegateDAO.delete(trans, dd, false);
+        return ques.delegateDAO().delete(trans, dd, false);
     }
     
     @Override
@@ -3918,7 +4014,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         
         TimeTaken tt = trans.start("Get delegates for a user", Env.SUB);
 
-        Result<List<DelegateDAO.Data>> dbDelgs = ques.delegateDAO.read(trans, user);
+        Result<List<DelegateDAO.Data>> dbDelgs = ques.delegateDAO().read(trans, user);
         try {
             if (dbDelgs.isOKhasData()) {
                 return mapper.delegate(dbDelgs.value);
@@ -3946,7 +4042,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
 
         TimeTaken tt = trans.start("Get users for a delegate", Env.SUB);
 
-        Result<List<DelegateDAO.Data>> dbDelgs = ques.delegateDAO.readByDelegate(trans, delegate);
+        Result<List<DelegateDAO.Data>> dbDelgs = ques.delegateDAO().readByDelegate(trans, delegate);
         try {
             if (dbDelgs.isOKhasData()) {
                 return mapper.delegate(dbDelgs.value);
@@ -3979,16 +4075,16 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         Lookup<List<ApprovalDAO.Data>> 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<ApprovalDAO.Data> 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");
             }
@@ -4024,7 +4120,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                                 if (cd.ticket!=null) {
                                     FutureDAO.Data fdd = futureCache.get(cd.ticket);
                                     if (fdd==null) { // haven't processed ticket yet
-                                        Result<FutureDAO.Data> rfdd = ques.futureDAO.readPrimKey(trans, cd.ticket);
+                                        Result<FutureDAO.Data> rfdd = ques.futureDAO().readPrimKey(trans, cd.ticket);
                                         if (rfdd.isOK()) {
                                             fdd = rfdd.value; // null is ok
                                         } else {
@@ -4067,7 +4163,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                                     ++numProcessed;
                                 }
                                 if (ch.hasChanged()) {
-                                    ques.approvalDAO.update(trans, cd, true);
+                                    ques.approvalDAO().update(trans, cd, true);
                                 }
                             }
                         }
@@ -4110,7 +4206,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(Status.ERR_BadData,v.errs());
         }
 
-        Result<List<ApprovalDAO.Data>> rapd = ques.approvalDAO.readByUser(trans, user);
+        Result<List<ApprovalDAO.Data>> rapd = ques.approvalDAO().readByUser(trans, user);
         if (rapd.isOK()) {
             return mapper.approvals(rapd.value);
         } else {
@@ -4131,7 +4227,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
             return Result.err(Status.ERR_BadData,e.getMessage());
         }
     
-        Result<List<ApprovalDAO.Data>> rapd = ques.approvalDAO.readByTicket(trans, uuid);
+        Result<List<ApprovalDAO.Data>> rapd = ques.approvalDAO().readByTicket(trans, uuid);
         if (rapd.isOK()) {
             return mapper.approvals(rapd.value);
         } else {
@@ -4148,19 +4244,19 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
         
         List<ApprovalDAO.Data> listRapds = new ArrayList<>();
         
-        Result<List<ApprovalDAO.Data>> myRapd = ques.approvalDAO.readByApprover(trans, approver);
+        Result<List<ApprovalDAO.Data>> myRapd = ques.approvalDAO().readByApprover(trans, approver);
         if (myRapd.notOK()) {
             return Result.err(myRapd);
         }
         
         listRapds.addAll(myRapd.value);
         
-        Result<List<DelegateDAO.Data>> delegatedFor = ques.delegateDAO.readByDelegate(trans, approver);
+        Result<List<DelegateDAO.Data>> 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<List<ApprovalDAO.Data>> rapd = ques.approvalDAO.readByApprover(trans, delegator);
+                    Result<List<ApprovalDAO.Data>> rapd = ques.approvalDAO().readByApprover(trans, delegator);
                     if (rapd.isOK()) {
                         for (ApprovalDAO.Data d : rapd.value) { 
                             if (!d.user.equals(trans.user())) {
@@ -4210,7 +4306,7 @@ public class AuthzCassServiceImpl    <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
      */
     @Override
     public void dbReset(AuthzTrans trans) {
-        ques.historyDAO.reportPerhapsReset(trans, null);
+        ques.historyDAO().reportPerhapsReset(trans, null);
     }
 
 }