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.service.mapper;
24 import java.nio.ByteBuffer;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Comparator;
29 import java.util.Date;
30 import java.util.GregorianCalendar;
31 import java.util.List;
32 import java.util.UUID;
34 import javax.xml.datatype.XMLGregorianCalendar;
36 import org.onap.aaf.auth.dao.Bytification;
37 import org.onap.aaf.auth.dao.cass.ApprovalDAO;
38 import org.onap.aaf.auth.dao.cass.CertDAO;
39 import org.onap.aaf.auth.dao.cass.CredDAO;
40 import org.onap.aaf.auth.dao.cass.DelegateDAO;
41 import org.onap.aaf.auth.dao.cass.FutureDAO;
42 import org.onap.aaf.auth.dao.cass.HistoryDAO;
43 import org.onap.aaf.auth.dao.cass.Namespace;
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.cass.DelegateDAO.Data;
51 import org.onap.aaf.auth.dao.hl.Question;
52 import org.onap.aaf.auth.dao.hl.Question.Access;
53 import org.onap.aaf.auth.env.AuthzTrans;
54 import org.onap.aaf.auth.env.AuthzTrans.REQD_TYPE;
55 import org.onap.aaf.auth.layer.Result;
56 import org.onap.aaf.auth.org.Organization;
57 import org.onap.aaf.auth.org.Organization.Expiration;
58 import org.onap.aaf.auth.rserv.Pair;
59 import org.onap.aaf.auth.service.MayChange;
60 import org.onap.aaf.cadi.aaf.marshal.CertsMarshal;
61 import org.onap.aaf.cadi.util.Vars;
62 import org.onap.aaf.misc.env.Env;
63 import org.onap.aaf.misc.env.TimeTaken;
64 import org.onap.aaf.misc.env.util.Chrono;
65 import org.onap.aaf.misc.rosetta.Marshal;
68 import aaf.v2_0.Approval;
69 import aaf.v2_0.Approvals;
70 import aaf.v2_0.Certs;
71 import aaf.v2_0.Certs.Cert;
72 import aaf.v2_0.CredRequest;
74 import aaf.v2_0.DelgRequest;
75 import aaf.v2_0.Delgs;
76 import aaf.v2_0.Error;
77 import aaf.v2_0.History;
78 import aaf.v2_0.History.Item;
80 import aaf.v2_0.NsRequest;
82 import aaf.v2_0.Nss.Ns;
84 import aaf.v2_0.PermKey;
85 import aaf.v2_0.PermRequest;
86 import aaf.v2_0.Perms;
88 import aaf.v2_0.Request;
90 import aaf.v2_0.RolePermRequest;
91 import aaf.v2_0.RoleRequest;
92 import aaf.v2_0.Roles;
93 import aaf.v2_0.UserRole;
94 import aaf.v2_0.UserRoleRequest;
95 import aaf.v2_0.UserRoles;
96 import aaf.v2_0.Users;
97 import aaf.v2_0.Users.User;
99 public class Mapper_2_0 implements Mapper<Nss, Perms, Pkey, Roles, Users, UserRoles, Delgs, Certs, Keys, Request, History, Error, Approvals> {
102 public Mapper_2_0(Question q) {
107 * @see org.onap.aaf.auth.service.mapper.Mapper#ns(java.lang.Object, org.onap.aaf.auth.service.mapper.Mapper.Holder)
110 public Result<Namespace> ns(AuthzTrans trans, Request base) {
111 NsRequest from = (NsRequest)base;
112 Namespace namespace = new Namespace();
113 namespace.name = from.getName();
114 namespace.admin = from.getAdmin();
115 namespace.owner = from.getResponsible();
116 namespace.description = from.getDescription();
117 trans.checkpoint(namespace.name, Env.ALWAYS);
119 NsType nt = NsType.fromString(from.getType());
120 if (nt.equals(NsType.UNKNOWN)) {
121 String ns = namespace.name;
123 for (int i=ns.indexOf('.');
125 i=ns.indexOf('.',i+1)) {
129 case 0: nt = NsType.ROOT;break;
130 case 1: nt = NsType.COMPANY;break;
131 default: nt = NsType.APP;
134 namespace.type = nt.type;
136 return Result.ok(namespace);
140 public Result<Nss> nss(AuthzTrans trans, Namespace from, Nss to) {
141 List<Ns> nss = to.getNs();
143 ns.setName(from.name);
144 if (from.admin!=null)ns.getAdmin().addAll(from.admin);
145 if (from.owner!=null)ns.getResponsible().addAll(from.owner);
146 if (from.attrib!=null) {
147 for (Pair<String,String> attrib : from.attrib) {
148 Ns.Attrib toAttrib = new Ns.Attrib();
149 toAttrib.setKey(attrib.x);
150 toAttrib.setValue(attrib.y);
151 ns.getAttrib().add(toAttrib);
155 ns.setDescription(from.description);
157 return Result.ok(to);
161 * Note: Prevalidate if NS given is allowed to be seen before calling
164 public Result<Nss> nss(AuthzTrans trans, Collection<Namespace> from, Nss to) {
165 List<Ns> nss = to.getNs();
166 for (Namespace nd : from) {
169 if (nd.admin!=null) {
170 ns.getAdmin().addAll(nd.admin);
172 if (nd.owner!=null) {
173 ns.getResponsible().addAll(nd.owner);
175 ns.setDescription(nd.description);
176 if (nd.attrib!=null) {
177 for (Pair<String,String> attrib : nd.attrib) {
178 Ns.Attrib toAttrib = new Ns.Attrib();
179 toAttrib.setKey(attrib.x);
180 toAttrib.setValue(attrib.y);
181 ns.getAttrib().add(toAttrib);
187 return Result.ok(to);
191 public Result<Perms> perms(AuthzTrans trans, List<PermDAO.Data> from, Perms to, boolean filter) {
192 List<Perm> perms = to.getPerm();
193 final boolean addNS = trans.requested(REQD_TYPE.ns);
194 TimeTaken tt = trans.start("Filter Perms before return", Env.SUB);
197 for (PermDAO.Data data : from) {
198 if (!filter || q.mayUser(trans, trans.user(), data, Access.read).isOK()) {
199 Perm perm = new Perm();
200 perm.setType(data.fullType());
201 perm.setInstance(data.instance);
202 perm.setAction(data.action);
203 perm.setDescription(data.description);
207 for (String role : data.roles(false)) {
208 perm.getRoles().add(role);
218 tt = trans.start("Sort Perms", Env.SUB);
220 Collections.sort(perms, new Comparator<Perm>() {
222 public int compare(Perm perm1, Perm perm2) {
223 int typeCompare = perm1.getType().compareToIgnoreCase(perm2.getType());
224 if (typeCompare == 0) {
225 int instanceCompare = perm1.getInstance().compareToIgnoreCase(perm2.getInstance());
226 if (instanceCompare == 0) {
227 return perm1.getAction().compareToIgnoreCase(perm2.getAction());
229 return instanceCompare;
237 return Result.ok(to);
241 public Result<Perms> perms(AuthzTrans trans, List<PermDAO.Data> from, Perms to, String[] nss, boolean filter) {
242 List<Perm> perms = to.getPerm();
243 TimeTaken tt = trans.start("Filter Perms before return", Env.SUB);
247 for (PermDAO.Data data : from) {
249 for (int i=0;!inNSS && i<nss.length;++i) {
250 if (nss[i].equals(data.ns)) {
254 if (inNSS && (!filter || q.mayUser(trans, trans.user(), data, Access.read).isOK())) {
255 Perm perm = new Perm();
256 perm.setType(data.fullType());
257 perm.setInstance(data.instance);
258 perm.setAction(data.action);
259 for (String role : data.roles(false)) {
260 perm.getRoles().add(role);
262 perm.setDescription(data.description);
271 tt = trans.start("Sort Perms", Env.SUB);
273 Collections.sort(perms, new Comparator<Perm>() {
275 public int compare(Perm perm1, Perm perm2) {
276 int typeCompare = perm1.getType().compareToIgnoreCase(perm2.getType());
277 if (typeCompare == 0) {
278 int instanceCompare = perm1.getInstance().compareToIgnoreCase(perm2.getInstance());
279 if (instanceCompare == 0) {
280 return perm1.getAction().compareToIgnoreCase(perm2.getAction());
282 return instanceCompare;
290 return Result.ok(to);
294 public Result<List<PermDAO.Data>> perms(AuthzTrans trans, Perms perms) {
295 List<PermDAO.Data> lpd = new ArrayList<>();
296 for (Perm p : perms.getPerm()) {
297 Result<NsSplit> nss = q.deriveNsSplit(trans, p.getType());
298 PermDAO.Data pd = new PermDAO.Data();
301 pd.type = nss.value.name;
302 pd.instance = p.getInstance();
303 pd.action = p.getAction();
304 for (String role : p.getRoles()) {
305 pd.roles(true).add(role);
309 return Result.err(nss);
312 return Result.ok(lpd);
317 public Result<PermDAO.Data> permkey(AuthzTrans trans, Pkey from) {
318 return q.permFrom(trans, from.getType(),from.getInstance(),from.getAction());
322 public Result<PermDAO.Data> permFromRPRequest(AuthzTrans trans, Request req) {
323 RolePermRequest from = (RolePermRequest)req;
324 Pkey perm = from.getPerm();
325 if (perm==null)return Result.err(Status.ERR_NotFound, "Permission not found");
326 Result<NsSplit> nss = q.deriveNsSplit(trans, perm.getType());
327 PermDAO.Data pd = new PermDAO.Data();
330 pd.type = nss.value.name;
331 pd.instance = from.getPerm().getInstance();
332 pd.action = from.getPerm().getAction();
333 trans.checkpoint(pd.fullPerm(), Env.ALWAYS);
337 if (from.getRole() != null) {
338 roles = from.getRole().split(",");
340 for (String role : roles) {
341 pd.roles(true).add(role);
343 return Result.ok(pd);
345 return Result.err(nss);
350 public Result<RoleDAO.Data> roleFromRPRequest(AuthzTrans trans, Request req) {
351 RolePermRequest from = (RolePermRequest)req;
352 Result<NsSplit> nss = q.deriveNsSplit(trans, from.getRole());
353 RoleDAO.Data rd = new RoleDAO.Data();
355 rd.ns = nss.value.ns;
356 rd.name = nss.value.name;
357 trans.checkpoint(rd.fullName(), Env.ALWAYS);
358 return Result.ok(rd);
360 return Result.err(nss);
365 public Result<PermDAO.Data> perm(AuthzTrans trans, Request req) {
366 PermRequest from = (PermRequest)req;
367 Result<NsSplit> nss = q.deriveNsSplit(trans, from.getType());
368 PermDAO.Data pd = new PermDAO.Data();
371 pd.type = nss.value.name;
372 pd.instance = from.getInstance();
373 pd.action = from.getAction();
374 pd.description = from.getDescription();
375 trans.checkpoint(pd.fullPerm(), Env.ALWAYS);
376 return Result.ok(pd);
378 return Result.err(nss);
383 public Request ungrantRequest(AuthzTrans trans, String role, String type, String instance, String action) {
384 RolePermRequest rpr = new RolePermRequest();
385 Pkey pkey = new Pkey();
387 pkey.setInstance(instance);
388 pkey.setAction(action);
396 public Result<RoleDAO.Data> role(AuthzTrans trans, Request base) {
397 RoleRequest from = (RoleRequest)base;
398 Result<NsSplit> nss = q.deriveNsSplit(trans, from.getName());
400 RoleDAO.Data to = new RoleDAO.Data();
401 to.ns = nss.value.ns;
402 to.name = nss.value.name;
403 to.description = from.getDescription();
404 trans.checkpoint(to.fullName(), Env.ALWAYS);
406 return Result.ok(to);
408 return Result.err(nss);
413 * @see org.onap.aaf.auth.service.mapper.Mapper#roles(java.util.List)
416 public Result<Roles> roles(AuthzTrans trans, List<RoleDAO.Data> from, Roles to, boolean filter) {
417 final boolean needNS = trans.requested(REQD_TYPE.ns);
418 for (RoleDAO.Data frole : from) {
419 // Only Add Data to view if User is allowed to see this Role
420 if (!filter || q.mayUser(trans, trans.user(), frole,Access.read).isOK()) {
421 Role role = new Role();
422 role.setName(frole.ns + '.' + frole.name);
423 role.setDescription(frole.description);
425 role.setNs(frole.ns);
427 for (String p : frole.perms(false)) { // can see any Perms in the Role he has permission for
428 Result<String[]> rpa = PermDAO.Data.decodeToArray(trans,q,p);
430 return Result.err(rpa);
432 String[] pa = rpa.value;
433 Pkey pKey = new Pkey();
434 pKey.setType(pa[0]+'.'+pa[1]);
435 pKey.setInstance(pa[2]);
436 pKey.setAction(pa[3]);
437 role.getPerms().add(pKey);
439 to.getRole().add(role);
442 return Result.ok(to);
447 * @see org.onap.aaf.auth.service.mapper.Mapper#users(java.util.Collection, java.lang.Object)
449 * Note: Prevalidate all data for permission to view
452 public Result<Users> users(AuthzTrans trans, Collection<UserRoleDAO.Data> from, Users to) {
453 List<User> cu = to.getUser();
454 for (UserRoleDAO.Data urd : from) {
455 User user = new User();
456 user.setId(urd.user);
457 if (urd.expires!=null) {
458 user.setExpires(Chrono.timeStamp(urd.expires));
462 return Result.ok(to);
467 * @see org.onap.aaf.auth.service.mapper.Mapper#users(java.util.Collection, java.lang.Object)
469 * Note: Prevalidate all data for permission to view
472 public Result<UserRoles> userRoles(AuthzTrans trans, Collection<UserRoleDAO.Data> from, UserRoles to) {
473 List<UserRole> cu = to.getUserRole();
474 for (UserRoleDAO.Data urd : from) {
475 UserRole ur = new UserRole();
476 ur.setUser(urd.user);
477 ur.setRole(urd.role);
478 ur.setExpires(Chrono.timeStamp(urd.expires));
481 return Result.ok(to);
485 public Result<UserRoleDAO.Data> userRole(AuthzTrans trans, Request base) {
487 UserRoleRequest from = (UserRoleRequest)base;
489 // Setup UserRoleData, either for immediate placement, or for futureIt i
490 UserRoleDAO.Data to = new UserRoleDAO.Data();
491 if (from.getUser() != null) {
492 to.user = from.getUser();
494 if (from.getRole() != null) {
495 to.role(trans,q,from.getRole());
497 to.expires = getExpires(trans.org(),Expiration.UserInRole,base,from.getUser());
498 trans.checkpoint(to.toString(), Env.ALWAYS);
500 return Result.ok(to);
501 } catch (Exception t) {
502 return Result.err(Status.ERR_BadData,t.getMessage());
507 public Result<CredDAO.Data> cred(AuthzTrans trans, Request base, boolean requiresPass) {
508 CredRequest from = (CredRequest)base;
509 CredDAO.Data to = new CredDAO.Data();
511 to.ns = Question.domain2ns(to.id);
512 String passwd = from.getPassword();
514 String ok = trans.org().isValidPassword(trans, to.id,passwd);
516 return Result.err(Status.ERR_BadData,ok);
521 if (passwd != null) {
522 to.cred = ByteBuffer.wrap(passwd.getBytes());
523 to.type = CredDAO.RAW;
528 // Note: Ensure requested EndDate created will match Organization Password Rules
529 // P.S. Do not apply TempPassword rule here. Do that when you know you are doing a Create/Reset (see Service)
530 to.expires = getExpires(trans.org(),Expiration.Password,base,from.getId());
531 trans.checkpoint(to.id, Env.ALWAYS);
533 return Result.ok(to);
537 public Result<Users> cred(List<CredDAO.Data> from, Users to) {
538 List<User> cu = to.getUser();
539 for (CredDAO.Data cred : from) {
540 User user = new User();
542 user.setExpires(Chrono.timeStamp(cred.expires));
543 user.setType(cred.type);
544 user.setTag(cred.tag);
547 return Result.ok(to);
551 public Result<Certs> cert(List<CertDAO.Data> from, Certs to) {
552 List<Cert> lc = to.getCert();
553 for (CertDAO.Data fcred : from) {
554 Cert cert = new Cert();
555 cert.setId(fcred.id);
556 cert.setX500(fcred.x500);
557 /**TODO - change Interface
559 cert.setFingerprint(fcred.serial.toByteArray());
562 return Result.ok(to);
566 * Analyze whether Requests should be acted on now, or in the future, based on Start Date, and whether the requester
567 * is allowed to change this value directly
569 * Returning Result.OK means it should be done in the future.
570 * Returning Result.ACC_Now means to act on table change now.
573 public Result<FutureDAO.Data> future(AuthzTrans trans, String table, Request from,
574 Bytification content, boolean enableApproval, Memo memo, MayChange mc) {
575 Result<?> rMayChange;
576 boolean needsAppr = enableApproval?trans.requested(REQD_TYPE.future):false;
577 if (!needsAppr && (needsAppr = (rMayChange=mc.mayChange()).notOK())) {
578 if (enableApproval) {
579 if (!trans.requested(AuthzTrans.REQD_TYPE.future)) {
580 return Result.err(rMayChange);
583 return Result.err(rMayChange);
586 GregorianCalendar now = new GregorianCalendar();
587 GregorianCalendar start = from.getStart()==null?now:from.getStart().toGregorianCalendar();
589 GregorianCalendar expires = trans.org().expiration(start, Expiration.Future);
590 XMLGregorianCalendar xgc;
591 if ((xgc=from.getEnd())!=null) {
592 GregorianCalendar fgc = xgc.toGregorianCalendar();
593 expires = expires.before(fgc)?expires:fgc; // Min of desired expiration, and Org expiration
596 //TODO needs two answers from this. What's the NSS, and may Change.
598 if (start.after(now) || needsAppr ) {
599 //String user = trans.user();
600 fto = new FutureDAO.Data();
602 fto.memo = memo.get();
603 fto.start = start.getTime();
604 fto.expires = expires.getTime();
605 if (needsAppr) { // Need to add Approvers...
607 Result<Data> rslt = mc.getNsd();
608 if (rslt.notOKorIsEmpty())return Result.err(rslt);
609 appr.addAll(mc.getNsd().value.responsible);
611 //Note from 2013 Is this getting Approvers for user only? What about Delegates?
612 // 3/25/2014. Approvers are set by Corporate policy. We don't have to worry here about what that means.
613 // It is important to get Delegates, if necessary, at notification time
614 // If we add delegates now, it will get all confused as to who is actually responsible.
615 for (Organization.User ou : org.getApprovers(trans, user)) {
618 } catch (Exception e) {
619 return Result.err(Status.ERR_Policy,org.getName() + " did not respond with Approvers: " + e.getLocalizedMessage());
624 fto.construct = content.bytify();
625 } catch (Exception e) {
626 return Result.err(Status.ERR_BadData,"Data cannot be saved for Future.");
629 return Result.err(Status.ACC_Now, "Make Data changes now.");
631 return Result.ok(fto);
636 * @see org.onap.aaf.auth.service.mapper.Mapper#history(java.util.List)
639 public Result<History> history(AuthzTrans trans, List<HistoryDAO.Data> history, final int sort) {
640 History hist = new History();
641 List<Item> items = hist.getItem();
642 for (HistoryDAO.Data data : history) {
643 History.Item item = new History.Item();
644 item.setYYYYMM(Integer.toString(data.yr_mon));
645 Date date = Chrono.uuidToDate(data.id);
646 item.setTimestamp(Chrono.timeStamp(date));
647 item.setAction(data.action);
648 item.setMemo(data.memo);
649 item.setSubject(data.subject);
650 item.setTarget(data.target);
651 item.setUser(data.user);
656 TimeTaken tt = trans.start("Sort ", Env.SUB);
658 java.util.Collections.sort(items, new Comparator<Item>() {
660 public int compare(Item o1, Item o2) {
661 return sort*(o1.getTimestamp().compare(o2.getTimestamp()));
668 return Result.ok(hist);
672 public Error errorFromMessage(StringBuilder holder, String msgID, String text, String... var) {
673 Error err = new Error();
674 err.setMessageId(msgID);
675 // AT&T Restful Error Format requires numbers "%" placements
676 err.setText(Vars.convert(holder, text, (Object[])var));
677 for (String s : var) {
678 err.getVariables().add(s);
684 public Class<?> getClass(API api) {
686 case NSS: return Nss.class;
687 case NS_REQ: return NsRequest.class;
688 case PERMS: return Perms.class;
689 case PERM_KEY: return PermKey.class;
690 case ROLES: return Roles.class;
691 case ROLE: return Role.class;
692 case USERS: return Users.class;
693 case DELGS: return Delgs.class;
694 case CERTS: return Certs.class;
695 case DELG_REQ: return DelgRequest.class;
696 case PERM_REQ: return PermRequest.class;
697 case ROLE_REQ: return RoleRequest.class;
698 case CRED_REQ: return CredRequest.class;
699 case USER_ROLE_REQ: return UserRoleRequest.class;
700 case USER_ROLES: return UserRoles.class;
701 case ROLE_PERM_REQ: return RolePermRequest.class;
702 case APPROVALS: return Approvals.class;
703 case KEYS: return Keys.class;
704 case HISTORY: return History.class;
705 // case MODEL: return Model.class;
706 case ERROR: return Error.class;
707 case API: return Api.class;
708 case VOID: return Void.class;
713 @SuppressWarnings("unchecked")
715 public <A> A newInstance(API api) {
717 case NS_REQ: return (A) new NsRequest();
718 case NSS: return (A) new Nss();
719 case PERMS: return (A)new Perms();
720 case PERM_KEY: return (A)new PermKey();
721 case ROLES: return (A)new Roles();
722 case ROLE: return (A)new Role();
723 case USERS: return (A)new Users();
724 case DELGS: return (A)new Delgs();
725 case CERTS: return (A)new Certs();
726 case PERM_REQ: return (A)new PermRequest();
727 case CRED_REQ: return (A)new CredRequest();
728 case ROLE_REQ: return (A)new RoleRequest();
729 case USER_ROLE_REQ: return (A)new UserRoleRequest();
730 case USER_ROLES: return (A)new UserRoles();
731 case ROLE_PERM_REQ: return (A)new RolePermRequest();
732 case HISTORY: return (A)new History();
733 case KEYS: return (A)new Keys();
734 //case MODEL: return (A)new Model();
735 case ERROR: return (A)new Error();
736 case API: return (A)new Api();
737 case VOID: return null;
739 case APPROVALS: return (A) new Approvals();
740 case DELG_REQ: return (A) new DelgRequest();
745 @SuppressWarnings("unchecked")
747 * Get Typed Marshaler as they are defined
752 public <A> Marshal<A> getMarshal(API api) {
754 case CERTS: return (Marshal<A>) new CertsMarshal();
761 public Result<Approvals> approvals(List<ApprovalDAO.Data> lAppr) {
762 Approvals apprs = new Approvals();
763 List<Approval> lappr = apprs.getApprovals();
765 for (ApprovalDAO.Data appr : lAppr) {
767 a.setId(appr.id.toString());
768 if (appr.ticket==null) {
771 a.setTicket(appr.ticket.toString());
773 a.setUser(appr.user);
774 a.setApprover(appr.approver);
775 a.setType(appr.type);
776 a.setStatus(appr.status);
777 a.setMemo(appr.memo);
778 a.setOperation(appr.operation);
779 a.setUpdated(Chrono.timeStamp(appr.updated));
782 return Result.ok(apprs);
786 public Result<List<ApprovalDAO.Data>> approvals(Approvals apprs) {
787 List<ApprovalDAO.Data> lappr = new ArrayList<>();
788 for (Approval a : apprs.getApprovals()) {
789 ApprovalDAO.Data ad = new ApprovalDAO.Data();
790 String str = a.getId();
791 if (str!=null)ad.id=UUID.fromString(str);
793 if (str!=null)ad.ticket=UUID.fromString(str);
795 ad.approver=a.getApprover();
797 ad.status=a.getStatus();
798 ad.operation=a.getOperation();
801 XMLGregorianCalendar xgc = a.getUpdated();
802 if (xgc!=null)ad.updated=xgc.toGregorianCalendar().getTime();
805 return Result.ok(lappr);
809 public Result<Delgs> delegate(List<DelegateDAO.Data> lDelg) {
810 Delgs delgs = new Delgs();
811 List<Delg> ldelg = delgs.getDelgs();
813 for (DelegateDAO.Data del: lDelg) {
816 d.setDelegate(del.delegate);
817 if (del.expires!=null)d.setExpires(Chrono.timeStamp(del.expires));
820 return Result.ok(delgs);
824 public Result<Data> delegate(AuthzTrans trans, Request base) {
826 DelgRequest from = (DelgRequest)base;
827 DelegateDAO.Data to = new DelegateDAO.Data();
828 String user = from.getUser();
830 String delegate = from.getDelegate();
831 to.delegate = delegate;
832 to.expires = getExpires(trans.org(),Expiration.UserDelegate,base,from.getUser());
833 trans.checkpoint(to.user+"=>"+to.delegate, Env.ALWAYS);
835 return Result.ok(to);
836 } catch (Exception t) {
837 return Result.err(Status.ERR_BadData,t.getMessage());
842 * We want "Expired" dates to start at a specified time set by the Organization, and consistent wherever
843 * the date is created from.
845 private Date getExpires(Organization org, Expiration exp, Request base, String id) {
846 XMLGregorianCalendar end = base.getEnd();
847 GregorianCalendar gc = end==null?new GregorianCalendar():end.toGregorianCalendar();
848 GregorianCalendar orggc;
849 orggc = org.expiration(gc,exp,id);
851 // We'll choose the lesser of dates to ensure Policy Compliance...
853 GregorianCalendar endgc = end==null||gc.after(orggc)?orggc:gc;
854 // Allow the Organization to determine when official "day Start" begins, Specifically when to consider something Expired.
855 endgc = Chrono.firstMomentOfDay(endgc);
856 endgc.set(GregorianCalendar.HOUR_OF_DAY, org.startOfDay());
857 return endgc.getTime();
862 public Result<Keys> keys(Collection<String> from) {
863 Keys keys = new Keys();
864 keys.getKey().addAll(from);
865 return Result.ok(keys).emptyList(from.isEmpty());