2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6 * ===========================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END====================================================
22 package org.onap.aaf.auth.dao.hl;
24 import static org.onap.aaf.auth.layer.Result.OK;
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import java.util.Date;
29 import java.util.GregorianCalendar;
30 import java.util.HashSet;
31 import java.util.List;
33 import java.util.UUID;
35 import org.onap.aaf.auth.common.Define;
36 import org.onap.aaf.auth.dao.DAOException;
37 import org.onap.aaf.auth.dao.cass.ApprovalDAO;
38 import org.onap.aaf.auth.dao.cass.CredDAO;
39 import org.onap.aaf.auth.dao.cass.DelegateDAO;
40 import org.onap.aaf.auth.dao.cass.FutureDAO;
41 import org.onap.aaf.auth.dao.cass.Namespace;
42 import org.onap.aaf.auth.dao.cass.NsDAO;
43 import org.onap.aaf.auth.dao.cass.NsDAO.Data;
44 import org.onap.aaf.auth.dao.cass.NsSplit;
45 import org.onap.aaf.auth.dao.cass.NsType;
46 import org.onap.aaf.auth.dao.cass.PermDAO;
47 import org.onap.aaf.auth.dao.cass.RoleDAO;
48 import org.onap.aaf.auth.dao.cass.Status;
49 import org.onap.aaf.auth.dao.cass.UserRoleDAO;
50 import org.onap.aaf.auth.dao.hl.Question.Access;
51 import org.onap.aaf.auth.env.AuthzTrans;
52 import org.onap.aaf.auth.env.AuthzTrans.REQD_TYPE;
53 import org.onap.aaf.auth.layer.Result;
54 import org.onap.aaf.auth.org.Executor;
55 import org.onap.aaf.auth.org.Organization;
56 import org.onap.aaf.auth.org.Organization.Expiration;
57 import org.onap.aaf.auth.org.Organization.Identity;
58 import org.onap.aaf.auth.org.Organization.Policy;
59 import org.onap.aaf.auth.org.OrganizationException;
61 public class Function {
63 private static final String CANNOT_BE_THE_OWNER_OF_A_NAMESPACE = "%s(%s) cannot be the owner of the namespace '%s'. Owners %s.";
65 public enum FUTURE_OP {
66 C("Create"),U("Update"),D("Delete"),G("Grant"),UG("UnGrant"),A("Approval");
70 private FUTURE_OP(String desc) {
74 public String desc() {
79 * Same as valueOf(), but passes back null instead of throwing Exception
83 public static FUTURE_OP toFO(String value) {
85 for (FUTURE_OP fo : values()) {
86 if (fo.name().equals(value)){
95 public enum OP_STATUS {
96 E("Executed"),D("Denied"),P("Pending"),L("Lapsed");
99 public final static Result<OP_STATUS> RE = Result.ok(OP_STATUS.E);
100 public final static Result<OP_STATUS> RD = Result.ok(OP_STATUS.D);
101 public final static Result<OP_STATUS> RP = Result.ok(OP_STATUS.P);
102 public final static Result<OP_STATUS> RL = Result.ok(OP_STATUS.L);
104 private OP_STATUS(String desc) {
108 public String desc() {
114 public static final String FOP_CRED = "cred";
115 public static final String FOP_DELEGATE = "delegate";
116 public static final String FOP_NS = "ns";
117 public static final String FOP_PERM = "perm";
118 public static final String FOP_ROLE = "role";
119 public static final String FOP_USER_ROLE = "user_role";
120 private static final List<Identity> NO_ADDL_APPROVE = new ArrayList<>();
121 private static final String ROOT_NS = Define.ROOT_NS();
122 // First Action should ALWAYS be "write", see "CreateRole"
123 public final Question q;
125 public Function(AuthzTrans trans, Question question) {
129 private class ErrBuilder {
130 private StringBuilder sb;
131 private List<String> ao;
133 public void log(Result<?> result) {
134 if (result.notOK()) {
136 sb = new StringBuilder();
137 ao = new ArrayList<>();
139 sb.append(String.format(result.details,result.variables));
144 public String[] vars() {
145 String[] rv = new String[ao.size()];
150 public boolean hasErr() {
155 public String toString() {
156 return sb == null ? "" : String.format(sb.toString(), ao);
170 * @throws DAOException
172 * To create an NS, you need to: 1) validate permission to
173 * modify parent NS 2) Does NS exist already? 3) Create NS with
174 * a) "user" as owner. NOTE: Per 10-15 request for AAF 1.0 4)
175 * Loop through Roles with Parent NS, and map any that start
176 * with this NS into this one 5) Loop through Perms with Parent
177 * NS, and map any that start with this NS into this one
179 public Result<Void> createNS(AuthzTrans trans, Namespace namespace, boolean fromApproval) {
183 for (String u : namespace.owner) {
184 Organization org = trans.org();
185 Identity orgUser = org.getIdentity(trans, u);
187 if (orgUser == null) {
188 return Result.err(Status.ERR_Policy,"%s is not a valid user at %s",u,org.getName());
189 } else if ((reason=orgUser.mayOwn())!=null) {
190 if (org.isTestEnv()) {
192 if ((reason2=org.validate(trans, Policy.AS_RESPONSIBLE,new CassExecutor(trans, this), u))!=null) { // can masquerade as responsible
193 trans.debug().log(reason2);
194 return Result.err(Status.ERR_Policy,CANNOT_BE_THE_OWNER_OF_A_NAMESPACE,orgUser.fullName(),orgUser.id(),namespace.name,reason);
198 if (orgUser.isFound()) {
199 return Result.err(Status.ERR_Policy,CANNOT_BE_THE_OWNER_OF_A_NAMESPACE,orgUser.fullName(),orgUser.id(),namespace.name, reason);
201 return Result.err(Status.ERR_Policy,u + " is an invalid Identity");
206 } catch (Exception e) {
208 "Could not contact Organization for User Validation");
211 String user = trans.user();
212 // 1) May Change Parent?
213 int idx = namespace.name.lastIndexOf('.');
216 if (!q.isGranted(trans, user, ROOT_NS,Question.NS, ".", "create")) {
217 return Result.err(Result.ERR_Security,
218 "%s may not create Root Namespaces", user);
223 parent = namespace.name.substring(0, idx); // get Parent String
226 Result<NsDAO.Data> rparent = q.deriveNs(trans, parent);
227 if (rparent.notOK()) {
228 return Result.err(rparent);
230 parent = rparent.value.parent;
232 rparent = q.mayUser(trans, user, rparent.value, Access.write);
233 if (rparent.notOK()) {
234 return Result.err(rparent);
237 parent = namespace.parent = rparent.value.name; // Correct Namespace from real data
238 String cname = parent.length()<1 || namespace.name.equals(parent)?null:namespace.name.substring(parent.length()+1);
240 // 2) Does requested NS exist
241 if (q.nsDAO().read(trans, namespace.name).isOKhasData()) {
242 return Result.err(Status.ERR_ConflictAlreadyExists,
243 "Target Namespace already exists");
246 // 2.1) Does role exist with that name
247 if(cname!=null && q.roleDAO().read(trans, parent, cname).isOKhasData()) {
248 return Result.err(Status.ERR_ConflictAlreadyExists,
249 "Role exists with that name");
252 // 2.2) Do perms exist with that name
253 if(cname!=null && q.permDAO().readByType(trans, parent, cname).isOKhasData()) {
254 return Result.err(Status.ERR_ConflictAlreadyExists,
255 "Perms exist with that name");
258 // Someone must be responsible.
259 if (namespace.owner == null || namespace.owner.isEmpty()) {
261 .err(Status.ERR_Policy,
262 "Namespaces must be assigned at least one responsible party");
266 Date now = new Date();
272 // Originally, added the enterer as Admin, but that's not necessary,
273 // or helpful for Operations folks..
274 // Admins can be empty, because they can be changed by lower level
276 if (namespace.admin != null) {
277 for (String u : namespace.admin) {
278 if ((r = checkValidID(trans, now, u)).notOK()) {
285 Organization org = trans.org();
286 for (String u : namespace.owner) {
287 Identity orgUser = org.getIdentity(trans, u);
288 if (orgUser == null) {
290 .err(Status.ERR_BadData,
291 "NS must be created with an %s approved Responsible Party",
295 } catch (Exception e) {
296 return Result.err(Status.ERR_UserNotFound, e.getMessage());
299 // VALIDATIONS done... Add NS
300 if ((rq = q.nsDAO().create(trans, namespace.data())).notOK()) {
301 return Result.err(rq);
304 // Since Namespace is now created, we need to grab all subsequent errors
305 ErrBuilder eb = new ErrBuilder();
308 UserRoleDAO.Data urdd = new UserRoleDAO.Data();
309 urdd.expires = trans.org().expiration(null, Expiration.UserInRole).getTime();
310 urdd.role(namespace.name, Question.ADMIN);
311 for (String admin : namespace.admin) {
313 eb.log(q.userRoleDAO().create(trans, urdd));
315 urdd.role(namespace.name,Question.OWNER);
316 for (String owner : namespace.owner) {
318 eb.log(q.userRoleDAO().create(trans, urdd));
321 addNSAdminRolesPerms(trans, eb, namespace.name);
323 addNSOwnerRolesPerms(trans, eb, namespace.name);
325 if (parent != null) {
326 // Build up with any errors
328 String targetNs = rparent.value.name; // Get the Parent Namespace,
330 String targetName = namespace.name.substring(targetNs.length() + 1); // Remove the Parent Namespace from the
331 // Target + a dot, and you'll get the name
332 int targetNameDot = targetName.length() + 1;
334 // 4) Change any roles with children matching this NS, and
335 Result<List<RoleDAO.Data>> rrdc = q.roleDAO().readChildren(trans, targetNs, targetName);
336 if (rrdc.isOKhasData()) {
337 for (RoleDAO.Data rdd : rrdc.value) {
338 // Remove old Role from Perms, save them off
339 List<PermDAO.Data> lpdd = new ArrayList<>();
340 for (String p : rdd.perms(false)) {
341 Result<PermDAO.Data> rpdd = PermDAO.Data.decode(trans,q,p);
342 if (rpdd.isOKhasData()) {
343 PermDAO.Data pdd = rpdd.value;
345 q.permDAO().delRole(trans, pdd, rdd);
347 trans.error().log(rpdd.errorString());
352 String delP1 = rdd.ns;
353 String delP2 = rdd.name;
356 rdd.ns = namespace.name;
357 rdd.name = (delP2.length() > targetNameDot) ? delP2
358 .substring(targetNameDot) : "";
360 // Need to use non-cached, because switching namespaces, not
362 if ((rq = q.roleDAO().create(trans, rdd)).isOK()) {
363 // Put Role back into Perm, with correct info
364 for (PermDAO.Data pdd : lpdd) {
365 q.permDAO().addRole(trans, pdd, rdd);
367 // Change data for User Roles
368 Result<List<UserRoleDAO.Data>> rurd = q.userRoleDAO().readByRole(trans, rdd.fullName());
369 if (rurd.isOKhasData()) {
370 for (UserRoleDAO.Data urd : rurd.value) {
372 urd.rname = rdd.name;
373 q.userRoleDAO().update(trans, urd);
376 // Now delete old one
379 if ((rq = q.roleDAO().delete(trans, rdd, false)).notOK()) {
388 // 4) Change any Permissions with children matching this NS, and
389 Result<List<PermDAO.Data>> rpdc = q.permDAO().readChildren(trans,targetNs, targetName);
390 if (rpdc.isOKhasData()) {
391 for (PermDAO.Data pdd : rpdc.value) {
392 // Remove old Perm from Roles, save them off
393 List<RoleDAO.Data> lrdd = new ArrayList<>();
395 for (String rl : pdd.roles(false)) {
396 Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans,q,rl);
397 if (rrdd.isOKhasData()) {
398 RoleDAO.Data rdd = rrdd.value;
400 q.roleDAO().delPerm(trans, rdd, pdd);
402 trans.error().log(rrdd.errorString());
407 String delP1 = pdd.ns;
408 String delP2 = pdd.type;
409 pdd.ns = namespace.name;
410 pdd.type = (delP2.length() > targetNameDot) ? delP2
411 .substring(targetNameDot) : "";
412 if ((rq = q.permDAO().create(trans, pdd)).isOK()) {
413 // Put Role back into Perm, with correct info
414 for (RoleDAO.Data rdd : lrdd) {
415 q.roleDAO().addPerm(trans, rdd, pdd);
420 if ((rq = q.permDAO().delete(trans, pdd, false)).notOK()) {
422 // Need to invalidate directly, because we're
423 // switching places in NS, not normal cache behavior
431 return Result.err(Status.ERR_ActionNotCompleted,eb.sb.toString(), (Object[])eb.vars());
437 private void addNSAdminRolesPerms(AuthzTrans trans, ErrBuilder eb, String ns) {
439 RoleDAO.Data rd = new RoleDAO.Data();
442 rd.description = "AAF Namespace Administrators";
444 PermDAO.Data pd = new PermDAO.Data();
447 pd.instance = Question.ASTERIX;
448 pd.action = Question.ASTERIX;
449 pd.description = "AAF Namespace Write Access";
451 rd.perms = new HashSet<>();
452 rd.perms.add(pd.encode());
453 eb.log(q.roleDAO().create(trans, rd));
455 pd.roles = new HashSet<>();
456 pd.roles.add(rd.encode());
457 eb.log(q.permDAO().create(trans, pd));
460 private void addNSOwnerRolesPerms(AuthzTrans trans, ErrBuilder eb, String ns) {
461 RoleDAO.Data rd = new RoleDAO.Data();
464 rd.description = "AAF Namespace Owners";
466 PermDAO.Data pd = new PermDAO.Data();
469 pd.instance = Question.ASTERIX;
470 pd.action = Question.READ;
471 pd.description = "AAF Namespace Read Access";
473 rd.perms = new HashSet<>();
474 rd.perms.add(pd.encode());
475 eb.log(q.roleDAO().create(trans, rd));
477 pd.roles = new HashSet<>();
478 pd.roles.add(rd.encode());
479 eb.log(q.permDAO().create(trans, pd));
493 * @throws DAOException
496 * To delete an NS, you need to: 1) validate permission to
497 * modify this NS 2) Find all Roles with this NS, and 2a) if
498 * Force, delete them, else modify to Parent NS 3) Find all
499 * Perms with this NS, and modify to Parent NS 3a) if Force,
500 * delete them, else modify to Parent NS 4) Find all IDs
501 * associated to this NS, and deny if exists. 5) Remove NS
503 public Result<Void> deleteNS(AuthzTrans trans, String ns) {
504 boolean force = trans.requested(REQD_TYPE.force);
505 boolean move = trans.requested(REQD_TYPE.move);
507 Result<List<NsDAO.Data>> nsl;
508 if ((nsl = q.nsDAO().read(trans, ns)).notOKorIsEmpty()) {
509 return Result.err(Status.ERR_NsNotFound, "%s does not exist", ns);
511 NsDAO.Data nsd = nsl.value.get(0);
513 if (move && !q.canMove(nt = NsType.fromType(nsd.type))) {
514 return Result.err(Status.ERR_Denied, "Namespace Force=move not permitted for Type %s",nt.name());
517 Result<NsDAO.Data> dnr = q.mayUser(trans, trans.user(), nsd, Access.write);
518 if (dnr.status != Status.OK) {
519 return Result.err(dnr);
523 String user = trans.user();
524 int idx = ns.lastIndexOf('.');
527 if (!q.isGranted(trans, user, ROOT_NS,Question.NS, ".", "delete")) {
528 return Result.err(Result.ERR_Security,
529 "%s may not delete Root Namespaces", user);
533 Result<NsDAO.Data> rlparent = q.deriveNs(trans, ns.substring(0, idx));
534 if (rlparent.notOKorIsEmpty()) {
535 return Result.err(rlparent);
537 parent = rlparent.value;
540 // Build up with any errors
541 // If sb != null below is an indication of error
542 StringBuilder sb = null;
543 ErrBuilder er = new ErrBuilder();
545 // 2a) Deny if any IDs on Namespace
546 Result<List<CredDAO.Data>> creds = q.credDAO().readNS(trans, ns);
547 if (creds.isOKhasData()) {
549 for (CredDAO.Data cd : creds.value) {
550 er.log(q.credDAO().delete(trans, cd, false));
551 // Since we're deleting all the creds, we should delete all
552 // the user Roles for that Cred
553 Result<List<UserRoleDAO.Data>> rlurd = q.userRoleDAO()
554 .readByUser(trans, cd.id);
556 for (UserRoleDAO.Data data : rlurd.value) {
557 q.userRoleDAO().delete(trans, data, false);
563 // first possible StringBuilder Create.
564 sb = new StringBuilder();
567 sb.append("] contains users");
571 // 2b) Find (or delete if forced flag is set) dependencies
572 // First, find if NS Perms are the only ones
573 Result<List<PermDAO.Data>> rpdc = q.permDAO().readNS(trans, ns);
574 if (rpdc.isOKhasData()) {
575 // Since there are now NS perms, we have to count NON-NS perms.
576 // FYI, if we delete them now, and the NS is not deleted, it is in
577 // an inconsistent state.
578 boolean nonaccess = false;
579 for (PermDAO.Data pdd : rpdc.value) {
580 if (!"access".equals(pdd.type)) {
585 if (nonaccess && !force && !move) {
587 sb = new StringBuilder();
590 sb.append("] contains ");
594 sb.append("permissions");
598 Result<List<RoleDAO.Data>> rrdc = q.roleDAO().readNS(trans, ns);
599 if (rrdc.isOKhasData()) {
600 // Since there are now NS roles, we have to count NON-NS roles.
601 // FYI, if we delete th)em now, and the NS is not deleted, it is in
602 // an inconsistent state.
603 int count = rrdc.value.size();
604 for (RoleDAO.Data rdd : rrdc.value) {
605 if ("admin".equals(rdd.name) || "owner".equals(rdd.name)) {
609 if (count > 0 && !force && !move) {
611 sb = new StringBuilder();
614 sb.append("] contains ");
622 // 2c) Deny if dependencies exist that would be moved to root level
623 // parent is root level parent here. Need to find closest parent ns that
626 if (!force && !move) {
627 sb.append(".\n Delete dependencies and try again. Note: using \"force=true\" will delete all. \"force=move\" will delete Creds, but move Roles and Perms to parent.");
628 return Result.err(Status.ERR_DependencyExists, sb.toString());
631 if (move && parent == null) {
633 .err(Status.ERR_DependencyExists,
634 "Cannot move users, roles or permissions - parent is missing.\nDelete dependencies and try again");
636 else if (move && parent.type == NsType.COMPANY.type) {
638 .err(Status.ERR_DependencyExists,
639 "Cannot move users, roles or permissions to [%s].\nDelete dependencies and try again",
642 } else if (move && parent != null) {
643 sb = new StringBuilder();
644 // 3) Change any roles with children matching this NS, and
645 moveRoles(trans, parent, sb, rrdc);
646 // 4) Change any Perms with children matching this NS, and
647 movePerms(trans, parent, sb, rpdc);
650 if (sb != null && sb.length() > 0) {
651 return Result.err(Status.ERR_DependencyExists, sb.toString());
655 if (trans.debug().isLoggable()) {
656 trans.debug().log(er.toString());
658 return Result.err(Status.ERR_DependencyExists,
659 "Namespace members cannot be deleted for %s", ns);
662 // 5) OK... good to go for NS Deletion...
663 if (!rpdc.isEmpty()) {
664 for (PermDAO.Data perm : rpdc.value) {
665 deletePerm(trans, perm, true, true);
668 if (!rrdc.isEmpty()) {
669 for (RoleDAO.Data role : rrdc.value) {
670 deleteRole(trans, role, true, true);
674 return q.nsDAO().delete(trans, nsd, false);
677 public Result<List<String>> getOwners(AuthzTrans trans, String ns,
678 boolean includeExpired) {
679 return getUsersByRole(trans, ns + Question.DOT_OWNER, includeExpired);
682 private Result<Void> mayAddOwner(AuthzTrans trans, String ns, String id) {
683 Result<NsDAO.Data> rq = q.deriveNs(trans, ns);
685 return Result.err(rq);
688 rq = q.mayUser(trans, trans.user(), rq.value, Access.write);
690 return Result.err(rq);
694 Organization org = trans.org();
696 if ((user = org.getIdentity(trans, id)) == null) {
697 return Result.err(Status.ERR_Policy,
698 "%s reports that this is not a valid credential",
702 if ((reason=user.mayOwn())==null) {
705 if (org.isTestEnv()) {
707 if ((reason2 = org.validate(trans, Policy.AS_RESPONSIBLE, new CassExecutor(trans, this), id))==null) {
710 trans.debug().log(reason2);
713 return Result.err(Status.ERR_Policy,CANNOT_BE_THE_OWNER_OF_A_NAMESPACE,user.fullName(),user.id(),ns, reason);
715 } catch (Exception e) {
716 return Result.err(e);
720 private Result<Void> mayAddAdmin(AuthzTrans trans, String ns, String id) {
722 Result<Void> r = checkValidID(trans, new Date(), id);
726 // Is id able to be an Admin
727 Result<NsDAO.Data> rq = q.deriveNs(trans, ns);
729 return Result.err(rq);
732 rq = q.mayUser(trans, trans.user(), rq.value, Access.write);
734 Result<List<UserRoleDAO.Data>> ruinr = q.userRoleDAO().readUserInRole(trans, trans.user(),ns+".owner");
735 if (!(ruinr.isOKhasData() && ruinr.value.get(0).expires.after(new Date()))) {
736 return Result.err(rq);
742 private Result<Void> checkValidID(AuthzTrans trans, Date now, String user) {
743 Organization org = trans.org();
744 if (org.supportsRealm(user)) {
746 if (org.getIdentity(trans, user) == null) {
747 return Result.err(Status.ERR_Denied,
748 "%s reports that %s is an invalid ID", org.getName(),
752 } catch (Exception e) {
753 return Result.err(Result.ERR_Security,
754 "%s is not a valid %s Credential", user, org.getName());
756 //TODO find out how to make sure good ALTERNATE OAUTH DOMAIN USER
757 // } else if (user.endsWith(ALTERNATE OAUTH DOMAIN)) {
758 // return Result.ok();
760 Result<List<CredDAO.Data>> cdr = q.credDAO().readID(trans, user);
761 if (cdr.notOKorIsEmpty()) {
762 return Result.err(Status.ERR_Security,
763 "%s is not a valid AAF Credential", user);
766 for (CredDAO.Data cd : cdr.value) {
767 if (cd.expires.after(now)) {
772 return Result.err(Result.ERR_Security, "%s has expired", user);
775 public Result<Void> delOwner(AuthzTrans trans, String ns, String id) {
776 Result<NsDAO.Data> rq = q.deriveNs(trans, ns);
778 return Result.err(rq);
781 rq = q.mayUser(trans, trans.user(), rq.value, Access.write);
783 return Result.err(rq);
786 return delUserRole(trans, id, ns,Question.OWNER);
789 public Result<List<String>> getAdmins(AuthzTrans trans, String ns, boolean includeExpired) {
790 return getUsersByRole(trans, ns + Question.DOT_ADMIN, includeExpired);
793 public Result<Void> delAdmin(AuthzTrans trans, String ns, String id) {
794 Result<NsDAO.Data> rq = q.deriveNs(trans, ns);
796 return Result.err(rq);
799 rq = q.mayUser(trans, trans.user(), rq.value, Access.write);
801 // Even though not a "writer", Owners still determine who gets to be an Admin
802 Result<List<UserRoleDAO.Data>> ruinr = q.userRoleDAO().readUserInRole(trans, trans.user(),ns+".owner");
803 if (!(ruinr.isOKhasData() && ruinr.value.get(0).expires.after(new Date()))) {
804 return Result.err(rq);
808 return delUserRole(trans, id, ns, Question.ADMIN);
812 * Helper function that moves permissions from a namespace being deleted to
813 * its parent namespace
819 * - list of permissions in namespace being deleted
821 private void movePerms(AuthzTrans trans, NsDAO.Data parent,
822 StringBuilder sb, Result<List<PermDAO.Data>> rpdc) {
825 Result<PermDAO.Data> pd;
827 if (rpdc.isOKhasData()) {
828 for (PermDAO.Data pdd : rpdc.value) {
829 String delP2 = pdd.type;
830 if ("access".equals(delP2)) {
833 // Remove old Perm from Roles, save them off
834 List<RoleDAO.Data> lrdd = new ArrayList<>();
836 for (String rl : pdd.roles(false)) {
837 Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans,q,rl);
838 if (rrdd.isOKhasData()) {
839 RoleDAO.Data rdd = rrdd.value;
841 q.roleDAO().delPerm(trans, rdd, pdd);
843 trans.error().log(rrdd.errorString());
848 String delP1 = pdd.ns;
849 NsSplit nss = new NsSplit(parent, pdd.fullType());
852 // Use direct Create/Delete, because switching namespaces
853 if ((pd = q.permDAO().create(trans, pdd)).isOK()) {
854 // Put Role back into Perm, with correct info
855 for (RoleDAO.Data rdd : lrdd) {
856 q.roleDAO().addPerm(trans, rdd, pdd);
861 if ((rv = q.permDAO().delete(trans, pdd, false)).notOK()) {
862 sb.append(rv.details);
865 // Need to invalidate directly, because we're switching
866 // places in NS, not normal cache behavior
867 // q.permDAO().invalidate(trans,pdd);
870 sb.append(pd.details);
878 * Helper function that moves roles from a namespace being deleted to its
885 * - list of roles in namespace being deleted
887 private void moveRoles(AuthzTrans trans, NsDAO.Data parent,
888 StringBuilder sb, Result<List<RoleDAO.Data>> rrdc) {
891 Result<RoleDAO.Data> rd;
893 if (rrdc.isOKhasData()) {
894 for (RoleDAO.Data rdd : rrdc.value) {
895 String delP2 = rdd.name;
896 if ("admin".equals(delP2) || "owner".equals(delP2)) {
899 // Remove old Role from Perms, save them off
900 List<PermDAO.Data> lpdd = new ArrayList<>();
901 for (String p : rdd.perms(false)) {
902 Result<PermDAO.Data> rpdd = PermDAO.Data.decode(trans,q,p);
903 if (rpdd.isOKhasData()) {
904 PermDAO.Data pdd = rpdd.value;
906 q.permDAO().delRole(trans, pdd, rdd);
908 trans.error().log(rpdd.errorString());
913 String delP1 = rdd.ns;
915 NsSplit nss = new NsSplit(parent, rdd.fullName());
918 // Use direct Create/Delete, because switching namespaces
919 if ((rd = q.roleDAO().create(trans, rdd)).isOK()) {
920 // Put Role back into Perm, with correct info
921 for (PermDAO.Data pdd : lpdd) {
922 q.permDAO().addRole(trans, pdd, rdd);
927 if ((rv = q.roleDAO().delete(trans, rdd, true)).notOK()) {
928 sb.append(rv.details);
931 // Need to invalidate directly, because we're switching
932 // places in NS, not normal cache behavior
933 // q.roleDAO().invalidate(trans,rdd);
936 sb.append(rd.details);
944 * Create Permission (and any missing Permission between this and Parent) if
947 * Pass in the desired Management Permission for this Permission
949 * If Force is set, then Roles listed will be created, if allowed,
952 public Result<Void> createPerm(AuthzTrans trans, PermDAO.Data perm, boolean fromApproval) {
953 String user = trans.user();
954 // Next, see if User is allowed to Manage Parent Permission
956 Result<NsDAO.Data> rnsd;
958 rnsd = q.mayUser(trans, user, perm, Access.write);
960 return Result.err(rnsd);
963 q.deriveNs(trans, perm.ns);
967 if (!trans.requested(REQD_TYPE.force)) {
968 if (q.permDAO().read(trans, perm).isOKhasData()) {
969 return Result.err(Status.ERR_ConflictAlreadyExists,
970 "Permission [%s.%s|%s|%s] already exists.", perm.ns,
971 perm.type, perm.instance, perm.action);
975 // Attempt to add perms to roles, creating as possible
977 String pstring = perm.encode();
980 for (String role : roles = perm.roles(true)) {
981 Result<RoleDAO.Data> rdd = RoleDAO.Data.decode(trans,q,role);
982 if (rdd.isOKhasData()) {
983 RoleDAO.Data rd = rdd.value;
985 // May User write to the Role in question.
986 Result<NsDAO.Data> rns = q.mayUser(trans, user, rd,
989 // Remove the role from Add, because
990 roles.remove(role); // Don't allow adding
992 .log("User [%s] does not have permission to relate Permissions to Role [%s]",
997 Result<List<RoleDAO.Data>> rlrd;
998 if ((rlrd = q.roleDAO().read(trans, rd)).notOKorIsEmpty()) {
999 rd.perms(true).add(pstring);
1000 if (q.roleDAO().create(trans, rd).notOK()) {
1001 roles.remove(role); // Role doesn't exist, and can't be
1005 rd = rlrd.value.get(0);
1006 if (!rd.perms.contains(pstring)) {
1007 q.roleDAO().addPerm(trans, rd, perm);
1013 Result<PermDAO.Data> pdr = q.permDAO().create(trans, perm);
1017 return Result.err(pdr);
1021 public Result<Void> deletePerm(final AuthzTrans trans, final PermDAO.Data perm, boolean force, boolean fromApproval) {
1022 String user = trans.user();
1024 // Next, see if User is allowed to Manage Permission
1025 Result<NsDAO.Data> rnsd;
1026 if (!fromApproval) {
1027 rnsd = q.mayUser(trans, user, perm, Access.write);
1029 return Result.err(rnsd);
1033 Result<List<PermDAO.Data>> pdr = q.permDAO().read(trans, perm);
1034 if (pdr.notOKorIsEmpty()) {
1035 return Result.err(Status.ERR_PermissionNotFound,"Permission [%s.%s|%s|%s] does not exist.",
1036 perm.ns,perm.type, perm.instance, perm.action);
1038 // Get perm, but with rest of data.
1039 PermDAO.Data fullperm = pdr.value.get(0);
1041 // Attached to any Roles?
1042 if (fullperm.roles != null) {
1044 for (String role : fullperm.roles) {
1045 Result<Void> rv = null;
1046 Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans, q, role);
1047 if (rrdd.isOKhasData()) {
1048 trans.debug().log("Removing", role, "from", fullperm, "on Perm Delete");
1049 if ((rv = q.roleDAO().delPerm(trans, rrdd.value, fullperm)).notOK()) {
1051 trans.error().log("Error removing Role during delFromPermRole: ",
1052 trans.getUserPrincipal(),
1057 return Result.err(rrdd);
1060 } else if (!fullperm.roles.isEmpty()) {
1062 .err(Status.ERR_DependencyExists,
1063 "Permission [%s] cannot be deleted as it is attached to 1 or more roles.",
1064 fullperm.fullPerm());
1068 return q.permDAO().delete(trans, fullperm, false);
1071 public Result<Void> deleteRole(final AuthzTrans trans, final RoleDAO.Data role, boolean force, boolean fromApproval) {
1072 String user = trans.user();
1074 // Next, see if User is allowed to Manage Role
1075 Result<NsDAO.Data> rnsd;
1076 if (!fromApproval) {
1077 rnsd = q.mayUser(trans, user, role, Access.write);
1079 return Result.err(rnsd);
1083 // Are there any Users Attached to Role?
1084 Result<List<UserRoleDAO.Data>> urdr = q.userRoleDAO().readByRole(trans,role.fullName());
1086 if (urdr.isOKhasData()) {
1087 for (UserRoleDAO.Data urd : urdr.value) {
1088 q.userRoleDAO().delete(trans, urd, false);
1091 } else if (urdr.isOKhasData()) {
1092 return Result.err(Status.ERR_DependencyExists,
1093 "Role [%s.%s] cannot be deleted as it is used by 1 or more Users.",
1094 role.ns, role.name);
1098 Result<List<RoleDAO.Data>> rdr = q.roleDAO().read(trans, role);
1099 if (rdr.notOKorIsEmpty()) {
1100 return Result.err(Status.ERR_RoleNotFound,
1101 "Role [%s.%s] does not exist", role.ns, role.name);
1103 RoleDAO.Data fullrole = rdr.value.get(0); // full key search
1105 // Remove Self from Permissions... always, force or not. Force only applies to Dependencies (Users)
1106 if (fullrole.perms != null) {
1107 for (String perm : fullrole.perms(false)) {
1108 Result<PermDAO.Data> rpd = PermDAO.Data.decode(trans,q,perm);
1110 trans.debug().log("Removing", perm, "from", fullrole,"on Role Delete");
1112 Result<?> r = q.permDAO().delRole(trans, rpd.value, fullrole);
1114 trans.error().log("ERR_FDR1 unable to remove",fullrole,"from",perm,':',r.status,'-',r.details);
1117 trans.error().log("ERR_FDR2 Could not remove",perm,"from",fullrole);
1121 return q.roleDAO().delete(trans, fullrole, false);
1125 * Only owner of Permission may add to Role
1127 * If force set, however, Role will be created before Grant, if User is
1128 * allowed to create.
1135 public Result<Void> addPermToRole(AuthzTrans trans, RoleDAO.Data role,PermDAO.Data pd, boolean fromApproval) {
1136 String user = trans.user();
1138 if (!fromApproval) {
1139 Result<NsDAO.Data> rRoleCo = q.deriveFirstNsForType(trans, role.ns, NsType.COMPANY);
1140 if (rRoleCo.notOK()) {
1141 return Result.err(rRoleCo);
1143 Result<NsDAO.Data> rPermCo = q.deriveFirstNsForType(trans, pd.ns, NsType.COMPANY);
1144 if (rPermCo.notOK()) {
1145 return Result.err(rPermCo);
1148 // Not from same company
1149 if (!rRoleCo.value.name.equals(rPermCo.value.name)) {
1151 // Only grant if User ALSO has Write ability in Other Company
1152 if ((r = q.mayUser(trans, user, role, Access.write)).notOK()) {
1153 return Result.err(r);
1158 // Must be Perm Admin, or Granted Special Permission
1159 Result<NsDAO.Data> ucp = q.mayUser(trans, user, pd, Access.write);
1161 // Don't allow CLI potential Grantees to change their own AAF
1163 if ((ROOT_NS.equals(pd.ns) && Question.NS.equals(pd.type))
1164 || !q.isGranted(trans, trans.user(),ROOT_NS,Question.PERM, rPermCo.value.name, "grant")) {
1165 // Not otherwise granted
1167 return Result.err(ucp);
1169 // Final Check... Don't allow Grantees to add to Roles they are
1171 Result<List<UserRoleDAO.Data>> rlurd = q.userRoleDAO()
1172 .readByUser(trans, trans.user());
1174 for (UserRoleDAO.Data ur : rlurd.value) {
1175 if (role.ns.equals(ur.ns) && role.name.equals(ur.rname)) {
1176 return Result.err(ucp);
1183 Result<List<PermDAO.Data>> rlpd = q.permDAO().read(trans, pd);
1184 if (rlpd.notOKorIsEmpty()) {
1185 return Result.err(Status.ERR_PermissionNotFound,
1186 "Permission must exist to add to Role");
1189 Result<List<RoleDAO.Data>> rlrd = q.roleDAO().read(trans, role); // Already
1197 if (rlrd.notOKorIsEmpty()) {
1198 if (trans.requested(REQD_TYPE.force)) {
1199 Result<NsDAO.Data> ucr = q.mayUser(trans, user, role,
1203 .err(Status.ERR_Denied,
1204 "Role [%s.%s] does not exist. User [%s] cannot create.",
1205 role.ns, role.name, user);
1208 role.perms(true).add(pd.encode());
1209 Result<RoleDAO.Data> rdd = q.roleDAO().create(trans, role);
1213 rv = Result.err(rdd);
1216 return Result.err(Status.ERR_RoleNotFound,
1217 "Role [%s.%s] does not exist.", role.ns, role.name);
1220 role = rlrd.value.get(0);
1221 if (role.perms(false).contains(pd.encode())) {
1222 return Result.err(Status.ERR_ConflictAlreadyExists,
1223 "Permission [%s.%s] is already a member of role [%s,%s]",
1224 pd.ns, pd.type, role.ns, role.name);
1226 role.perms(true).add(pd.encode()); // this is added for Caching
1227 // access purposes... doesn't
1229 rv = q.roleDAO().addPerm(trans, role, pd);
1231 if (rv.status == Status.OK) {
1232 return q.permDAO().addRole(trans, pd, role);
1233 // exploring how to add information message to successful http
1240 * Either Owner of Role or Permission may delete from Role
1247 public Result<Void> delPermFromRole(AuthzTrans trans, RoleDAO.Data role,PermDAO.Data pd, boolean fromApproval) {
1248 String user = trans.user();
1249 if (!fromApproval) {
1250 Result<NsDAO.Data> ucr = q.mayUser(trans, user, role, Access.write);
1251 Result<NsDAO.Data> ucp = q.mayUser(trans, user, pd, Access.write);
1253 // If Can't change either Role or Perm, then deny
1254 if (ucr.notOK() && ucp.notOK()) {
1255 return Result.err(Status.ERR_Denied,
1256 "User [" + trans.user()
1257 + "] does not have permission to delete ["
1258 + pd.encode() + "] from Role ["
1259 + role.fullName() + ']');
1263 Result<List<RoleDAO.Data>> rlr = q.roleDAO().read(trans, role);
1264 if (rlr.notOKorIsEmpty()) {
1265 // If Bad Data, clean out
1266 Result<List<PermDAO.Data>> rlp = q.permDAO().read(trans, pd);
1267 if (rlp.isOKhasData()) {
1268 for (PermDAO.Data pv : rlp.value) {
1269 q.permDAO().delRole(trans, pv, role);
1272 return Result.err(rlr);
1274 String perm1 = pd.encode();
1276 if (trans.requested(REQD_TYPE.force)) {
1278 } else { // only check if force not set.
1280 for (RoleDAO.Data r : rlr.value) {
1281 if (r.perms != null) {
1282 for (String perm : r.perms) {
1283 if (perm1.equals(perm)) {
1294 if (notFound) { // Need to check both, in case of corruption
1295 return Result.err(Status.ERR_PermissionNotFound,
1296 "Permission [%s.%s|%s|%s] not associated with any Role",
1297 pd.ns,pd.type,pd.instance,pd.action);
1300 // Read Perm for full data
1301 Result<List<PermDAO.Data>> rlp = q.permDAO().read(trans, pd);
1302 Result<Void> rv = null;
1303 if (rlp.isOKhasData()) {
1304 for (PermDAO.Data pv : rlp.value) {
1305 if ((rv = q.permDAO().delRole(trans, pv, role)).isOK()) {
1306 if ((rv = q.roleDAO().delPerm(trans, role, pv)).notOK()) {
1308 "Error removing Perm during delFromPermRole:",
1309 trans.getUserPrincipal(), rv.errorString());
1313 "Error removing Role during delFromPermRole:",
1314 trans.getUserPrincipal(), rv.errorString());
1318 rv = q.roleDAO().delPerm(trans, role, pd);
1320 trans.error().log("Error removing Role during delFromPermRole",
1324 return rv == null ? Result.ok() : rv;
1327 public Result<Void> delPermFromRole(AuthzTrans trans, String role,PermDAO.Data pd) {
1328 Result<NsSplit> nss = q.deriveNsSplit(trans, role);
1330 return Result.err(nss);
1332 RoleDAO.Data rd = new RoleDAO.Data();
1333 rd.ns = nss.value.ns;
1334 rd.name = nss.value.name;
1335 return delPermFromRole(trans, rd, pd, false);
1339 * Add a User to Role
1341 * 1) Role must exist 2) User must be a known Credential (i.e. mechID ok if
1342 * Credential) or known Organizational User
1348 * @throws DAOException
1350 public Result<Void> addUserRole(AuthzTrans trans,UserRoleDAO.Data urData) {
1352 if (Question.ADMIN.equals(urData.rname)) {
1353 rv = mayAddAdmin(trans, urData.ns, urData.user);
1354 } else if (Question.OWNER.equals(urData.rname)) {
1355 rv = mayAddOwner(trans, urData.ns, urData.user);
1357 rv = checkValidID(trans, new Date(), urData.user);
1363 // Check if record exists
1364 if (q.userRoleDAO().read(trans, urData).isOKhasData()) {
1365 return Result.err(Status.ERR_ConflictAlreadyExists,
1366 "User Role exists");
1368 if (q.roleDAO().read(trans, urData.ns, urData.rname).notOKorIsEmpty()) {
1369 return Result.err(Status.ERR_RoleNotFound,
1370 "Role [%s.%s] does not exist", urData.ns, urData.rname);
1373 urData.expires = trans.org().expiration(null, Expiration.UserInRole, urData.user).getTime();
1376 Result<UserRoleDAO.Data> udr = q.userRoleDAO().create(trans, urData);
1377 if (udr.status == OK) {
1380 return Result.err(udr);
1383 public Result<Void> addUserRole(AuthzTrans trans, String user, String ns, String rname) {
1385 if (trans.org().getIdentity(trans, user)==null) {
1386 return Result.err(Result.ERR_BadData,user+" is an Invalid Identity for " + trans.org().getName());
1388 } catch (OrganizationException e) {
1389 return Result.err(e);
1391 UserRoleDAO.Data urdd = new UserRoleDAO.Data();
1393 urdd.role(ns, rname);
1395 return addUserRole(trans,urdd);
1401 * extend the Expiration data, according to Organization rules.
1408 public Result<Void> extendUserRole(AuthzTrans trans, UserRoleDAO.Data urData, boolean checkForExist) {
1409 // Check if record still exists
1410 if (checkForExist && q.userRoleDAO().read(trans, urData).notOKorIsEmpty()) {
1411 return Result.err(Status.ERR_UserRoleNotFound,
1412 "User Role does not exist");
1415 if (q.roleDAO().read(trans, urData.ns, urData.rname).notOKorIsEmpty()) {
1416 return Result.err(Status.ERR_RoleNotFound,
1417 "Role [%s.%s] does not exist", urData.ns,urData.rname);
1419 // Special case for "Admin" roles. Issue brought forward with Prod
1421 Date now = new Date();
1422 GregorianCalendar gc = new GregorianCalendar();
1423 gc.setTime(now.after(urData.expires)?now:urData.expires);
1424 urData.expires = trans.org().expiration(gc, Expiration.UserInRole).getTime(); // get
1429 return q.userRoleDAO().update(trans, urData);
1432 // ////////////////////////////////////////////////////
1433 // Special User Role Functions
1434 // These exist, because User Roles have Expiration dates, which must be
1436 // Also, as of July, 2015, Namespace Owners and Admins are now regular User
1438 // ////////////////////////////////////////////////////
1439 public Result<List<String>> getUsersByRole(AuthzTrans trans, String role, boolean includeExpired) {
1440 Result<List<UserRoleDAO.Data>> rurdd = q.userRoleDAO().readByRole(trans,role);
1441 if (rurdd.notOK()) {
1442 return Result.err(rurdd);
1444 Date now = new Date();
1445 List<UserRoleDAO.Data> list = rurdd.value;
1446 List<String> rv = new ArrayList<>(list.size()); // presize
1447 for (UserRoleDAO.Data urdd : rurdd.value) {
1448 if (includeExpired || urdd.expires.after(now)) {
1452 return Result.ok(rv);
1455 public Result<Void> delUserRole(AuthzTrans trans, String user, String ns, String rname) {
1456 UserRoleDAO.Data urdd = new UserRoleDAO.Data();
1458 urdd.role(ns,rname);
1459 Result<List<UserRoleDAO.Data>> r = q.userRoleDAO().read(trans, urdd);
1460 if (r.status == 404 || r.isEmpty()) {
1461 return Result.err(Status.ERR_UserRoleNotFound,
1462 "UserRole [%s] [%s.%s]", user, ns, rname);
1465 return Result.err(r);
1468 return q.userRoleDAO().delete(trans, urdd, false);
1471 public Result<String> createFuture(AuthzTrans trans, FutureDAO.Data data, String id, String user,
1472 NsDAO.Data nsd, FUTURE_OP op) {
1473 StringBuilder sb = new StringBuilder();
1475 Organization org = trans.org();
1476 // For Reapproval, only check Owners.. Do Supervisors, etc, separately
1477 List<Identity> approvers = op.equals(FUTURE_OP.A)?NO_ADDL_APPROVE:org.getApprovers(trans, user);
1478 List<Identity> owners = new ArrayList<>();
1480 Result<List<UserRoleDAO.Data>> rrbr = q.userRoleDAO()
1481 .readByRole(trans, nsd.name + Question.DOT_OWNER);
1482 if (rrbr.isOKhasData()) {
1483 for (UserRoleDAO.Data urd : rrbr.value) {
1484 Identity owner = org.getIdentity(trans, urd.user);
1486 return Result.err(Result.ERR_NotFound,urd.user + " is not a Valid Owner of " + nsd.name);
1494 if (owners.isEmpty()) {
1495 return Result.err(Result.ERR_NotFound,"No Owners found for " + nsd.name);
1498 // Create Future Object
1500 Result<FutureDAO.Data> fr = q.futureDAO().create(trans, data, id);
1502 sb.append("Created Future: ");
1504 // User Future ID as ticket for Approvals
1505 final UUID ticket = fr.value.id;
1506 sb.append(", Approvals: ");
1507 Boolean[] first = new Boolean[]{true};
1508 if (op!=FUTURE_OP.A) {
1509 for (Identity u : approvers) {
1510 Result<ApprovalDAO.Data> r = addIdentity(trans,sb,first,user,data.memo,op,u,ticket,org.getApproverType());
1512 return Result.err(r);
1516 for (Identity u : owners) {
1517 Result<ApprovalDAO.Data> r = addIdentity(trans,sb,first,user,data.memo,op,u,ticket,"owner");
1519 return Result.err(r);
1523 } catch (Exception e) {
1524 return Result.err(e);
1527 return Result.ok(sb.toString());
1531 * This interface is to allow performFutureOps with either Realtime Data, or Batched lookups (See Expiring)
1533 public interface Lookup<T> {
1534 T get(AuthzTrans trans, Object ... keys);
1537 public Lookup<UserRoleDAO.Data> urDBLookup = new Lookup<UserRoleDAO.Data>() {
1539 public UserRoleDAO.Data get(AuthzTrans trans, Object ... keys) {
1540 Result<List<UserRoleDAO.Data>> r = q.userRoleDAO().read(trans, keys);
1541 if (r.isOKhasData()) {
1542 return r.value.get(0);
1550 * Note: if "allApprovals for Ticket is null, it will be looked up.
1551 * if "fdd" is null, it will be looked up, but
1553 * They can be passed for performance reasons.
1557 * @param allApprovalsForTicket
1560 public Result<OP_STATUS> performFutureOp(final AuthzTrans trans, FUTURE_OP fop, FutureDAO.Data curr, Lookup<List<ApprovalDAO.Data>> la, Lookup<UserRoleDAO.Data> lur) {
1561 // Pre-Evaluate if ReApproval is already done.
1562 UserRoleDAO.Data urdd = null;
1563 if (fop.equals(FUTURE_OP.A) && curr.target.equals(FOP_USER_ROLE) && curr.construct!=null) {
1565 // Get Expected UserRole from Future
1566 urdd = new UserRoleDAO.Data();
1567 urdd.reconstitute(curr.construct);
1568 // Get Current UserRole from lookup
1569 UserRoleDAO.Data lurdd = lur.get(trans, urdd.user,urdd.role);
1571 q.futureDAO().delete(trans, curr, false);
1572 return OP_STATUS.RL;
1574 if (curr.expires.compareTo(lurdd.expires)<0) {
1575 q.futureDAO().delete(trans, curr, false);
1576 return OP_STATUS.RL;
1579 } catch (IOException e) {
1580 return Result.err(Result.ERR_BadData,"Cannot reconstitute %1",curr.memo);
1584 boolean aDenial = false;
1585 int cntSuper=0, appSuper=0,cntOwner=0, appOwner=0;
1586 for (ApprovalDAO.Data add : la.get(trans)) {
1587 switch(add.status) {
1589 if ("owner".equals(add.type)) {
1592 } else if ("supervisor".equals(add.type)) {
1598 if ("owner".equals(add.type)) {
1600 } else if ("supervisor".equals(add.type)) {
1612 Result<OP_STATUS> ros=null;
1615 if (q.futureDAO().delete(trans, curr, false).notOK()) {
1616 trans.info().printf("Future %s could not be deleted", curr.id.toString());
1618 if (FOP_USER_ROLE.equalsIgnoreCase(curr.target)) {
1619 // A Denial means we must remove UserRole
1620 if (fop.equals(FUTURE_OP.U) || fop.equals(FUTURE_OP.A)) {
1621 UserRoleDAO.Data data = new UserRoleDAO.Data();
1623 data.reconstitute(curr.construct);
1624 } catch (IOException e) {
1625 trans.error().log("Cannot reconstitue",curr.memo);
1627 ros = set(OP_STATUS.RD,delUserRole(trans, data.user, data.ns, data.rname));
1633 // Decision: If not Denied, and at least owner, if exists, and at least one Super, if exists
1634 boolean goDecision = (cntOwner>0?appOwner>0:true) && (cntSuper>0?appSuper>0:true);
1637 // should check if any other pendings before performing
1640 if (FOP_ROLE.equalsIgnoreCase(curr.target)) {
1641 RoleDAO.Data data = new RoleDAO.Data();
1642 data.reconstitute(curr.construct);
1645 ros = set(OP_STATUS.RE,q.roleDAO().dao().create(trans, data));
1648 ros = set(OP_STATUS.RE,deleteRole(trans, data, true, true));
1652 } else if (FOP_PERM.equalsIgnoreCase(curr.target)) {
1653 PermDAO.Data pdd = new PermDAO.Data();
1654 pdd.reconstitute(curr.construct);
1656 Result<RoleDAO.Data> rrdd;
1659 ros = set(OP_STATUS.RE,createPerm(trans, pdd, true));
1662 ros = set(OP_STATUS.RE,deletePerm(trans, pdd, true, true));
1665 roles = pdd.roles(true);
1666 for (String roleStr : roles) {
1667 rrdd = RoleDAO.Data.decode(trans, q, roleStr);
1668 if (rrdd.isOKhasData()) {
1669 ros = set(OP_STATUS.RE,addPermToRole(trans, rrdd.value, pdd, true));
1671 trans.error().log(rrdd.errorString());
1676 roles = pdd.roles(true);
1677 for (String roleStr : roles) {
1678 rrdd = RoleDAO.Data.decode(trans, q, roleStr);
1679 if (rrdd.isOKhasData()) {
1680 ros = set(OP_STATUS.RE,delPermFromRole(trans, rrdd.value, pdd, true));
1682 trans.error().log(rrdd.errorString());
1688 } else if (FOP_USER_ROLE.equalsIgnoreCase(curr.target)) {
1690 urdd = new UserRoleDAO.Data();
1691 urdd.reconstitute(curr.construct);
1693 // if I am the last to approve, create user role
1696 ros = set(OP_STATUS.RE,addUserRole(trans, urdd));
1700 ros = set(OP_STATUS.RE,extendUserRole(trans,urdd,true));
1704 } else if (FOP_NS.equalsIgnoreCase(curr.target)) {
1705 Namespace namespace = new Namespace();
1706 namespace.reconstitute(curr.construct);
1707 if (fop == FUTURE_OP.C) {
1708 ros = set(OP_STATUS.RE, createNS(trans, namespace, true));
1710 } else if (FOP_DELEGATE.equalsIgnoreCase(curr.target)) {
1711 DelegateDAO.Data data = new DelegateDAO.Data();
1712 data.reconstitute(curr.construct);
1715 ros = set(OP_STATUS.RE,q.delegateDAO().create(trans, data));
1718 ros = set(OP_STATUS.RE,q.delegateDAO().update(trans, data));
1722 } else if (FOP_CRED.equalsIgnoreCase(curr.target)) {
1723 CredDAO.Data data = new CredDAO.Data();
1724 data.reconstitute(curr.construct);
1725 if (fop == FUTURE_OP.C) {
1726 ros = set(OP_STATUS.RE, q.credDAO().dao().create(trans, data));
1729 } catch (Exception e) {
1730 trans.error().log("Exception: ", e.getMessage(),
1731 " \n occurred while performing", curr.memo,
1732 " from Ticket ", curr.id.toString());
1734 q.futureDAO().delete(trans, curr, false);
1735 } // end for goDecision
1737 //return Result.err(Status.ACC_Future, "Full Approvals not obtained: No action taken");
1744 // Convenience method for setting OPSTatus Results
1745 private Result<OP_STATUS> set(Result<OP_STATUS> rs, Result<?> orig) {
1749 return Result.err(orig);
1753 private Result<ApprovalDAO.Data> addIdentity(AuthzTrans trans, StringBuilder sb,
1754 Boolean[] first, String user, String memo, FUTURE_OP op, Identity u, UUID ticket, String type) throws OrganizationException {
1755 ApprovalDAO.Data ad = new ApprovalDAO.Data();
1756 // Note ad.id is set by ApprovalDAO Create
1759 ad.approver = u.fullID();
1760 ad.status = ApprovalDAO.PENDING;
1763 ad.operation = op.name();
1764 // Note ad.updated is created in System
1765 Result<ApprovalDAO.Data> r = q.approvalDAO().create(trans,ad);
1772 sb.append(r.value.user);
1774 sb.append(r.value.ticket);
1777 return Result.err(Status.ERR_ActionNotCompleted,
1778 "Approval for %s, %s could not be created: %s",
1779 ad.user, ad.approver,
1780 r.details, sb.toString());
1784 public Executor newExecutor(AuthzTrans trans) {
1785 return new CassExecutor(trans, this);