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.DelegateDAO.Data;
42 import org.onap.aaf.auth.dao.cass.FutureDAO;
43 import org.onap.aaf.auth.dao.cass.HistoryDAO;
44 import org.onap.aaf.auth.dao.cass.Namespace;
45 import org.onap.aaf.auth.dao.cass.NsSplit;
46 import org.onap.aaf.auth.dao.cass.NsType;
47 import org.onap.aaf.auth.dao.cass.PermDAO;
48 import org.onap.aaf.auth.dao.cass.RoleDAO;
49 import org.onap.aaf.auth.dao.cass.Status;
50 import org.onap.aaf.auth.dao.cass.UserRoleDAO;
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.Split;
62 import org.onap.aaf.cadi.util.Vars;
63 import org.onap.aaf.misc.env.Env;
64 import org.onap.aaf.misc.env.TimeTaken;
65 import org.onap.aaf.misc.env.util.Chrono;
66 import org.onap.aaf.misc.rosetta.Marshal;
69 import aaf.v2_0.Approval;
70 import aaf.v2_0.Approvals;
71 import aaf.v2_0.Certs;
72 import aaf.v2_0.Certs.Cert;
73 import aaf.v2_0.CredRequest;
75 import aaf.v2_0.DelgRequest;
76 import aaf.v2_0.Delgs;
77 import aaf.v2_0.Error;
78 import aaf.v2_0.History;
79 import aaf.v2_0.History.Item;
81 import aaf.v2_0.NsRequest;
83 import aaf.v2_0.Nss.Ns;
85 import aaf.v2_0.PermKey;
86 import aaf.v2_0.PermRequest;
87 import aaf.v2_0.Perms;
89 import aaf.v2_0.Request;
91 import aaf.v2_0.RolePermRequest;
92 import aaf.v2_0.RoleRequest;
93 import aaf.v2_0.Roles;
94 import aaf.v2_0.UserRole;
95 import aaf.v2_0.UserRoleRequest;
96 import aaf.v2_0.UserRoles;
97 import aaf.v2_0.Users;
98 import aaf.v2_0.Users.User;
100 public class Mapper_2_0 implements Mapper<Nss, Perms, Pkey, Roles, Users, UserRoles, Delgs, Certs, Keys, Request, History, Error, Approvals> {
103 public Mapper_2_0(Question q) {
108 * @see org.onap.aaf.auth.service.mapper.Mapper#ns(java.lang.Object, org.onap.aaf.auth.service.mapper.Mapper.Holder)
111 public Result<Namespace> ns(AuthzTrans trans, Request base) {
112 NsRequest from = (NsRequest)base;
113 Namespace namespace = new Namespace();
114 namespace.name = from.getName();
115 namespace.admin = from.getAdmin();
116 namespace.owner = from.getResponsible();
117 namespace.description = from.getDescription();
118 trans.checkpoint(namespace.name, Env.ALWAYS);
120 NsType nt = NsType.fromString(from.getType());
121 if (nt.equals(NsType.UNKNOWN)) {
122 String ns = namespace.name;
124 for (int i=ns.indexOf('.');
126 i=ns.indexOf('.',i+1)) {
130 case 0: nt = NsType.ROOT;break;
131 case 1: nt = NsType.COMPANY;break;
132 default: nt = NsType.APP;
135 namespace.type = nt.type;
137 return Result.ok(namespace);
141 public Result<Nss> nss(AuthzTrans trans, Namespace from, Nss to) {
142 List<Ns> nss = to.getNs();
144 ns.setName(from.name);
145 if (from.admin!=null)ns.getAdmin().addAll(from.admin);
146 if (from.owner!=null)ns.getResponsible().addAll(from.owner);
147 if (from.attrib!=null) {
148 for (Pair<String,String> attrib : from.attrib) {
149 Ns.Attrib toAttrib = new Ns.Attrib();
150 toAttrib.setKey(attrib.x);
151 toAttrib.setValue(attrib.y);
152 ns.getAttrib().add(toAttrib);
156 ns.setDescription(from.description);
158 return Result.ok(to);
162 * Note: Prevalidate if NS given is allowed to be seen before calling
165 public Result<Nss> nss(AuthzTrans trans, Collection<Namespace> from, Nss to) {
166 List<Ns> nss = to.getNs();
167 for (Namespace nd : from) {
170 if (nd.admin!=null) {
171 ns.getAdmin().addAll(nd.admin);
173 if (nd.owner!=null) {
174 ns.getResponsible().addAll(nd.owner);
176 ns.setDescription(nd.description);
177 if (nd.attrib!=null) {
178 for (Pair<String,String> attrib : nd.attrib) {
179 Ns.Attrib toAttrib = new Ns.Attrib();
180 toAttrib.setKey(attrib.x);
181 toAttrib.setValue(attrib.y);
182 ns.getAttrib().add(toAttrib);
188 return Result.ok(to);
192 public Result<Perms> perms(AuthzTrans trans, List<PermDAO.Data> from, Perms to, boolean filter) {
193 List<Perm> perms = to.getPerm();
194 final boolean addNS = trans.requested(REQD_TYPE.ns);
195 TimeTaken tt = trans.start("Filter Perms before return", Env.SUB);
198 for (PermDAO.Data data : from) {
199 if (!filter || q.mayUser(trans, trans.user(), data, Access.read).isOK()) {
200 Perm perm = new Perm();
201 perm.setType(data.fullType());
202 perm.setInstance(data.instance);
203 perm.setAction(data.action);
204 perm.setDescription(data.description);
208 for (String role : data.roles(false)) {
209 perm.getRoles().add(role);
219 tt = trans.start("Sort Perms", Env.SUB);
221 Collections.sort(perms, new Comparator<Perm>() {
223 public int compare(Perm perm1, Perm perm2) {
224 int typeCompare = perm1.getType().compareToIgnoreCase(perm2.getType());
225 if (typeCompare == 0) {
226 int instanceCompare = perm1.getInstance().compareToIgnoreCase(perm2.getInstance());
227 if (instanceCompare == 0) {
228 return perm1.getAction().compareToIgnoreCase(perm2.getAction());
230 return instanceCompare;
238 return Result.ok(to);
242 public Result<Perms> perms(AuthzTrans trans, List<PermDAO.Data> from, Perms to, String[] nss, boolean filter) {
243 List<Perm> perms = to.getPerm();
244 TimeTaken tt = trans.start("Filter Perms before return", Env.SUB);
248 for (PermDAO.Data data : from) {
250 for (int i=0;!inNSS && i<nss.length;++i) {
251 if (nss[i].equals(data.ns)) {
255 if (inNSS && (!filter || q.mayUser(trans, trans.user(), data, Access.read).isOK())) {
256 Perm perm = new Perm();
257 perm.setType(data.fullType());
258 perm.setInstance(data.instance);
259 perm.setAction(data.action);
260 for (String role : data.roles(false)) {
261 perm.getRoles().add(role);
263 perm.setDescription(data.description);
272 tt = trans.start("Sort Perms", Env.SUB);
274 Collections.sort(perms, new Comparator<Perm>() {
276 public int compare(Perm perm1, Perm perm2) {
277 int typeCompare = perm1.getType().compareToIgnoreCase(perm2.getType());
278 if (typeCompare == 0) {
279 int instanceCompare = perm1.getInstance().compareToIgnoreCase(perm2.getInstance());
280 if (instanceCompare == 0) {
281 return perm1.getAction().compareToIgnoreCase(perm2.getAction());
283 return instanceCompare;
291 return Result.ok(to);
295 public Result<List<PermDAO.Data>> perms(AuthzTrans trans, Perms perms) {
296 List<PermDAO.Data> lpd = new ArrayList<>();
297 for (Perm p : perms.getPerm()) {
298 Result<NsSplit> nss = q.deriveNsSplit(trans, p.getType());
299 PermDAO.Data pd = new PermDAO.Data();
302 pd.type = nss.value.name;
303 pd.instance = p.getInstance();
304 pd.action = p.getAction();
305 for (String role : p.getRoles()) {
306 pd.roles(true).add(role);
310 return Result.err(nss);
313 return Result.ok(lpd);
318 public Result<PermDAO.Data> permkey(AuthzTrans trans, Pkey from) {
319 return q.permFrom(trans, from.getType(),from.getInstance(),from.getAction());
323 public Result<PermDAO.Data> permFromRPRequest(AuthzTrans trans, Request req) {
324 RolePermRequest from = (RolePermRequest)req;
325 Pkey perm = from.getPerm();
326 if (perm==null)return Result.err(Status.ERR_NotFound, "Permission not found");
327 Result<NsSplit> nss = q.deriveNsSplit(trans, perm.getType());
328 PermDAO.Data pd = new PermDAO.Data();
331 pd.type = nss.value.name;
332 pd.instance = from.getPerm().getInstance();
333 pd.action = from.getPerm().getAction();
334 trans.checkpoint(pd.fullPerm(), Env.ALWAYS);
338 if (from.getRole() != null) {
339 roles = from.getRole().split(",");
341 for (String role : roles) {
342 pd.roles(true).add(role);
344 return Result.ok(pd);
346 return Result.err(nss);
351 public Result<RoleDAO.Data> roleFromRPRequest(AuthzTrans trans, Request req) {
352 RolePermRequest from = (RolePermRequest)req;
353 Result<NsSplit> nss = q.deriveNsSplit(trans, from.getRole());
354 RoleDAO.Data rd = new RoleDAO.Data();
356 rd.ns = nss.value.ns;
357 rd.name = nss.value.name;
358 trans.checkpoint(rd.fullName(), Env.ALWAYS);
359 return Result.ok(rd);
361 return Result.err(nss);
366 public Result<PermDAO.Data> perm(AuthzTrans trans, Request req) {
367 PermRequest from = (PermRequest)req;
368 String type = from.getType();
370 return Result.err(Result.ERR_BadData, "Invalid Perm Type");
372 PermDAO.Data pd = new PermDAO.Data();
373 if(type.contains("@")) {
374 String[] split = Split.splitTrim(':', type);
376 pd.type=split.length>1?split[1]:"";
377 pd.instance = from.getInstance();
378 pd.action = from.getAction();
379 pd.description = from.getDescription();
380 return Result.ok(pd);
382 Result<NsSplit> nss = q.deriveNsSplit(trans, from.getType());
385 pd.type = nss.value.name;
386 pd.instance = from.getInstance();
387 pd.action = from.getAction();
388 pd.description = from.getDescription();
389 trans.checkpoint(pd.fullPerm(), Env.ALWAYS);
390 return Result.ok(pd);
392 return Result.err(nss);
398 public Request ungrantRequest(AuthzTrans trans, String role, String type, String instance, String action) {
399 RolePermRequest rpr = new RolePermRequest();
400 Pkey pkey = new Pkey();
402 pkey.setInstance(instance);
403 pkey.setAction(action);
411 public Result<RoleDAO.Data> role(AuthzTrans trans, Request base) {
412 RoleRequest from = (RoleRequest)base;
413 Result<NsSplit> nss = q.deriveNsSplit(trans, from.getName());
415 RoleDAO.Data to = new RoleDAO.Data();
416 to.ns = nss.value.ns;
417 to.name = nss.value.name;
418 to.description = from.getDescription();
419 trans.checkpoint(to.fullName(), Env.ALWAYS);
421 return Result.ok(to);
423 return Result.err(nss);
428 * @see org.onap.aaf.auth.service.mapper.Mapper#roles(java.util.List)
431 public Result<Roles> roles(AuthzTrans trans, List<RoleDAO.Data> from, Roles to, boolean filter) {
432 final boolean needNS = trans.requested(REQD_TYPE.ns);
433 for (RoleDAO.Data frole : from) {
434 // Only Add Data to view if User is allowed to see this Role
435 if (!filter || q.mayUser(trans, trans.user(), frole,Access.read).isOK()) {
436 Role role = new Role();
437 role.setName(frole.ns + '.' + frole.name);
438 role.setDescription(frole.description);
440 role.setNs(frole.ns);
442 for (String p : frole.perms(false)) { // can see any Perms in the Role he has permission for
443 Result<String[]> rpa = PermDAO.Data.decodeToArray(trans,q,p);
445 return Result.err(rpa);
447 String[] pa = rpa.value;
448 Pkey pKey = new Pkey();
449 pKey.setType(pa[0]+'.'+pa[1]);
450 pKey.setInstance(pa[2]);
451 pKey.setAction(pa[3]);
452 role.getPerms().add(pKey);
454 to.getRole().add(role);
457 return Result.ok(to);
462 * @see org.onap.aaf.auth.service.mapper.Mapper#users(java.util.Collection, java.lang.Object)
464 * Note: Prevalidate all data for permission to view
467 public Result<Users> users(AuthzTrans trans, Collection<UserRoleDAO.Data> from, Users to) {
468 List<User> cu = to.getUser();
469 for (UserRoleDAO.Data urd : from) {
470 User user = new User();
471 user.setId(urd.user);
472 if (urd.expires!=null) {
473 user.setExpires(Chrono.timeStamp(urd.expires));
477 return Result.ok(to);
482 * @see org.onap.aaf.auth.service.mapper.Mapper#users(java.util.Collection, java.lang.Object)
484 * Note: Prevalidate all data for permission to view
487 public Result<UserRoles> userRoles(AuthzTrans trans, Collection<UserRoleDAO.Data> from, UserRoles to) {
488 List<UserRole> cu = to.getUserRole();
489 for (UserRoleDAO.Data urd : from) {
490 UserRole ur = new UserRole();
491 ur.setUser(urd.user);
492 ur.setRole(urd.role);
493 ur.setExpires(Chrono.timeStamp(urd.expires));
496 return Result.ok(to);
500 public Result<UserRoleDAO.Data> userRole(AuthzTrans trans, Request base) {
502 UserRoleRequest from = (UserRoleRequest)base;
504 // Setup UserRoleData, either for immediate placement, or for futureIt i
505 UserRoleDAO.Data to = new UserRoleDAO.Data();
506 if (from.getUser() != null) {
507 to.user = from.getUser();
509 if (from.getRole() != null) {
510 to.role(trans,q,from.getRole());
512 to.expires = getExpires(trans.org(),Expiration.UserInRole,base,from.getUser());
513 trans.checkpoint(to.toString(), Env.ALWAYS);
515 return Result.ok(to);
516 } catch (Exception t) {
517 return Result.err(Status.ERR_BadData,t.getMessage());
522 public Result<CredDAO.Data> cred(AuthzTrans trans, Request base, boolean requiresPass) {
523 CredRequest from = (CredRequest)base;
524 CredDAO.Data to = new CredDAO.Data();
526 to.ns = Question.domain2ns(to.id);
527 to.type = from.getType();
528 if(to.type!=null && to.type==CredDAO.FQI) {
531 String passwd = from.getPassword();
533 String ok = trans.org().isValidPassword(trans, to.id,passwd);
535 return Result.err(Status.ERR_BadData,ok);
538 if (passwd != null) {
539 to.cred = ByteBuffer.wrap(passwd.getBytes());
540 to.type = CredDAO.RAW;
542 to.type = CredDAO.NONE;
546 // Note: Ensure requested EndDate created will match Organization Password Rules
547 // P.S. Do not apply TempPassword rule here. Do that when you know you are doing a Create/Reset (see Service)
548 to.expires = getExpires(trans.org(),Expiration.Password,base,from.getId());
549 trans.checkpoint(to.id, Env.ALWAYS);
551 return Result.ok(to);
555 public Result<Users> cred(List<CredDAO.Data> from, Users to) {
556 List<User> cu = to.getUser();
557 for (CredDAO.Data cred : from) {
558 User user = new User();
560 user.setExpires(Chrono.timeStamp(cred.expires));
561 user.setType(cred.type);
562 user.setTag(cred.tag);
565 return Result.ok(to);
569 public Result<Certs> cert(List<CertDAO.Data> from, Certs to) {
570 List<Cert> lc = to.getCert();
571 for (CertDAO.Data fcred : from) {
572 Cert cert = new Cert();
573 cert.setId(fcred.id);
574 cert.setX500(fcred.x500);
575 /**TODO - change Interface
577 cert.setFingerprint(fcred.serial.toByteArray());
580 return Result.ok(to);
584 * Analyze whether Requests should be acted on now, or in the future, based on Start Date, and whether the requester
585 * is allowed to change this value directly
587 * Returning Result.OK means it should be done in the future.
588 * Returning Result.ACC_Now means to act on table change now.
591 public Result<FutureDAO.Data> future(AuthzTrans trans, String table, Request from,
592 Bytification content, boolean enableApproval, Memo memo, MayChange mc) {
593 Result<?> rMayChange;
594 boolean needsAppr = enableApproval?trans.requested(REQD_TYPE.future):false;
595 if (!needsAppr && (needsAppr = (rMayChange=mc.mayChange()).notOK())) {
596 if (enableApproval) {
597 if (!trans.requested(AuthzTrans.REQD_TYPE.future)) {
598 return Result.err(rMayChange);
601 return Result.err(rMayChange);
604 GregorianCalendar now = new GregorianCalendar();
605 GregorianCalendar start = from.getStart()==null?now:from.getStart().toGregorianCalendar();
607 GregorianCalendar expires = trans.org().expiration(start, Expiration.Future);
608 XMLGregorianCalendar xgc;
609 if ((xgc=from.getEnd())!=null) {
610 GregorianCalendar fgc = xgc.toGregorianCalendar();
611 expires = expires.before(fgc)?expires:fgc; // Min of desired expiration, and Org expiration
614 //TODO needs two answers from this. What's the NSS, and may Change.
616 if (start.after(now) || needsAppr ) {
617 //String user = trans.user();
618 fto = new FutureDAO.Data();
620 fto.memo = memo.get();
621 fto.start = start.getTime();
622 fto.expires = expires.getTime();
623 if (needsAppr) { // Need to add Approvers...
625 Result<Data> rslt = mc.getNsd();
626 if (rslt.notOKorIsEmpty())return Result.err(rslt);
627 appr.addAll(mc.getNsd().value.responsible);
629 //Note from 2013 Is this getting Approvers for user only? What about Delegates?
630 // 3/25/2014. Approvers are set by Corporate policy. We don't have to worry here about what that means.
631 // It is important to get Delegates, if necessary, at notification time
632 // If we add delegates now, it will get all confused as to who is actually responsible.
633 for (Organization.User ou : org.getApprovers(trans, user)) {
636 } catch (Exception e) {
637 return Result.err(Status.ERR_Policy,org.getName() + " did not respond with Approvers: " + e.getLocalizedMessage());
642 fto.construct = content.bytify();
643 } catch (Exception e) {
644 return Result.err(Status.ERR_BadData,"Data cannot be saved for Future.");
647 return Result.err(Status.ACC_Now, "Make Data changes now.");
649 return Result.ok(fto);
654 * @see org.onap.aaf.auth.service.mapper.Mapper#history(java.util.List)
657 public Result<History> history(AuthzTrans trans, List<HistoryDAO.Data> history, final int sort) {
658 History hist = new History();
659 List<Item> items = hist.getItem();
660 for (HistoryDAO.Data data : history) {
661 History.Item item = new History.Item();
662 item.setYYYYMM(Integer.toString(data.yr_mon));
663 Date date = Chrono.uuidToDate(data.id);
664 item.setTimestamp(Chrono.timeStamp(date));
665 item.setAction(data.action);
666 item.setMemo(data.memo);
667 item.setSubject(data.subject);
668 item.setTarget(data.target);
669 item.setUser(data.user);
674 TimeTaken tt = trans.start("Sort ", Env.SUB);
676 java.util.Collections.sort(items, new Comparator<Item>() {
678 public int compare(Item o1, Item o2) {
679 return sort*(o1.getTimestamp().compare(o2.getTimestamp()));
686 return Result.ok(hist);
690 public Error errorFromMessage(StringBuilder holder, String msgID, String text, String... var) {
691 Error err = new Error();
692 err.setMessageId(msgID);
693 // AT&T Restful Error Format requires numbers "%" placements
694 err.setText(Vars.convert(holder, text, (Object[])var));
695 for (String s : var) {
696 err.getVariables().add(s);
702 public Class<?> getClass(API api) {
704 case NSS: return Nss.class;
705 case NS_REQ: return NsRequest.class;
706 case PERMS: return Perms.class;
707 case PERM_KEY: return PermKey.class;
708 case ROLES: return Roles.class;
709 case ROLE: return Role.class;
710 case USERS: return Users.class;
711 case DELGS: return Delgs.class;
712 case CERTS: return Certs.class;
713 case DELG_REQ: return DelgRequest.class;
714 case PERM_REQ: return PermRequest.class;
715 case ROLE_REQ: return RoleRequest.class;
716 case CRED_REQ: return CredRequest.class;
717 case USER_ROLE_REQ: return UserRoleRequest.class;
718 case USER_ROLES: return UserRoles.class;
719 case ROLE_PERM_REQ: return RolePermRequest.class;
720 case APPROVALS: return Approvals.class;
721 case KEYS: return Keys.class;
722 case HISTORY: return History.class;
723 // case MODEL: return Model.class;
724 case ERROR: return Error.class;
725 case API: return Api.class;
726 case VOID: return Void.class;
731 @SuppressWarnings("unchecked")
733 public <A> A newInstance(API api) {
735 case NS_REQ: return (A) new NsRequest();
736 case NSS: return (A) new Nss();
737 case PERMS: return (A)new Perms();
738 case PERM_KEY: return (A)new PermKey();
739 case ROLES: return (A)new Roles();
740 case ROLE: return (A)new Role();
741 case USERS: return (A)new Users();
742 case DELGS: return (A)new Delgs();
743 case CERTS: return (A)new Certs();
744 case PERM_REQ: return (A)new PermRequest();
745 case CRED_REQ: return (A)new CredRequest();
746 case ROLE_REQ: return (A)new RoleRequest();
747 case USER_ROLE_REQ: return (A)new UserRoleRequest();
748 case USER_ROLES: return (A)new UserRoles();
749 case ROLE_PERM_REQ: return (A)new RolePermRequest();
750 case HISTORY: return (A)new History();
751 case KEYS: return (A)new Keys();
752 //case MODEL: return (A)new Model();
753 case ERROR: return (A)new Error();
754 case API: return (A)new Api();
755 case VOID: return null;
757 case APPROVALS: return (A) new Approvals();
758 case DELG_REQ: return (A) new DelgRequest();
763 @SuppressWarnings("unchecked")
765 * Get Typed Marshaler as they are defined
770 public <A> Marshal<A> getMarshal(API api) {
772 case CERTS: return (Marshal<A>) new CertsMarshal();
779 public Result<Approvals> approvals(List<ApprovalDAO.Data> lAppr) {
780 Approvals apprs = new Approvals();
781 List<Approval> lappr = apprs.getApprovals();
783 for (ApprovalDAO.Data appr : lAppr) {
785 a.setId(appr.id.toString());
786 if (appr.ticket==null) {
789 a.setTicket(appr.ticket.toString());
791 a.setUser(appr.user);
792 a.setApprover(appr.approver);
793 a.setType(appr.type);
794 a.setStatus(appr.status);
795 a.setMemo(appr.memo);
796 a.setOperation(appr.operation);
797 a.setUpdated(Chrono.timeStamp(appr.updated));
800 return Result.ok(apprs);
804 public Result<List<ApprovalDAO.Data>> approvals(Approvals apprs) {
805 List<ApprovalDAO.Data> lappr = new ArrayList<>();
806 for (Approval a : apprs.getApprovals()) {
807 ApprovalDAO.Data ad = new ApprovalDAO.Data();
808 String str = a.getId();
809 if (str!=null)ad.id=UUID.fromString(str);
811 if (str!=null)ad.ticket=UUID.fromString(str);
813 ad.approver=a.getApprover();
815 ad.status=a.getStatus();
816 ad.operation=a.getOperation();
819 XMLGregorianCalendar xgc = a.getUpdated();
820 if (xgc!=null)ad.updated=xgc.toGregorianCalendar().getTime();
823 return Result.ok(lappr);
827 public Result<Delgs> delegate(List<DelegateDAO.Data> lDelg) {
828 Delgs delgs = new Delgs();
829 List<Delg> ldelg = delgs.getDelgs();
831 for (DelegateDAO.Data del: lDelg) {
834 d.setDelegate(del.delegate);
835 if (del.expires!=null)d.setExpires(Chrono.timeStamp(del.expires));
838 return Result.ok(delgs);
842 public Result<Data> delegate(AuthzTrans trans, Request base) {
844 DelgRequest from = (DelgRequest)base;
845 DelegateDAO.Data to = new DelegateDAO.Data();
846 String user = from.getUser();
848 String delegate = from.getDelegate();
849 to.delegate = delegate;
850 to.expires = getExpires(trans.org(),Expiration.UserDelegate,base,from.getUser());
851 trans.checkpoint(to.user+"=>"+to.delegate, Env.ALWAYS);
853 return Result.ok(to);
854 } catch (Exception t) {
855 return Result.err(Status.ERR_BadData,t.getMessage());
860 * We want "Expired" dates to start at a specified time set by the Organization, and consistent wherever
861 * the date is created from.
863 private Date getExpires(Organization org, Expiration exp, Request base, String id) {
864 XMLGregorianCalendar end = base.getEnd();
865 GregorianCalendar gc = end==null?new GregorianCalendar():end.toGregorianCalendar();
866 GregorianCalendar orggc;
867 orggc = org.expiration(gc,exp,id);
869 // We'll choose the lesser of dates to ensure Policy Compliance...
871 GregorianCalendar endgc = end==null||gc.after(orggc)?orggc:gc;
872 // Allow the Organization to determine when official "day Start" begins, Specifically when to consider something Expired.
873 endgc = Chrono.firstMomentOfDay(endgc);
874 endgc.set(GregorianCalendar.HOUR_OF_DAY, org.startOfDay());
875 return endgc.getTime();
880 public Result<Keys> keys(Collection<String> from) {
881 Keys keys = new Keys();
882 keys.getKey().addAll(from);
883 return Result.ok(keys).emptyList(from.isEmpty());