f414a9fdf011639a60f225cbf531a5a99a6a3e2f
[aaf/authz.git] / auth / auth-service / src / main / java / org / onap / aaf / auth / service / mapper / Mapper_2_0.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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====================================================
19  *
20  */
21
22 package org.onap.aaf.auth.service.mapper;
23
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;
33
34 import javax.xml.datatype.XMLGregorianCalendar;
35
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;
66
67 import aaf.v2_0.Api;
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;
73 import aaf.v2_0.Delg;
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;
79 import aaf.v2_0.Keys;
80 import aaf.v2_0.NsRequest;
81 import aaf.v2_0.Nss;
82 import aaf.v2_0.Nss.Ns;
83 import aaf.v2_0.Perm;
84 import aaf.v2_0.PermKey;
85 import aaf.v2_0.PermRequest;
86 import aaf.v2_0.Perms;
87 import aaf.v2_0.Pkey;
88 import aaf.v2_0.Request;
89 import aaf.v2_0.Role;
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;
98
99 public class Mapper_2_0 implements Mapper<Nss, Perms, Pkey, Roles, Users, UserRoles, Delgs, Certs, Keys, Request, History, Error, Approvals> {
100         private Question q;
101
102         public Mapper_2_0(Question q) {
103                 this.q = q;
104         }
105         
106         /* (non-Javadoc)
107          * @see org.onap.aaf.auth.service.mapper.Mapper#ns(java.lang.Object, org.onap.aaf.auth.service.mapper.Mapper.Holder)
108          */
109         @Override
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);
118                 
119                 NsType nt = NsType.fromString(from.getType());
120                 if(nt.equals(NsType.UNKNOWN)) {
121                         String ns = namespace.name;
122                         int count = 0;
123                         for(int i=ns.indexOf('.');
124                                         i>=0;
125                                         i=ns.indexOf('.',i+1)) {
126                                 ++count;
127                         }
128                         switch(count) {
129                                 case 0: nt = NsType.ROOT;break;
130                                 case 1: nt = NsType.COMPANY;break;
131                                 default: nt = NsType.APP;
132                         }
133                 }
134                 namespace.type = nt.type;
135                 
136                 return Result.ok(namespace);
137         }
138
139         @Override
140         public Result<Nss> nss(AuthzTrans trans, Namespace from, Nss to) {
141                 List<Ns> nss = to.getNs();
142                 Ns ns = new Ns();
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);
152                         }
153                 }
154
155                 ns.setDescription(from.description);
156                 nss.add(ns);
157                 return Result.ok(to);
158         }
159
160         /**
161          * Note: Prevalidate if NS given is allowed to be seen before calling
162          */
163         @Override
164         public Result<Nss> nss(AuthzTrans trans, Collection<Namespace> from, Nss to) {
165                 List<Ns> nss = to.getNs();
166                 for(Namespace nd : from) {
167                         Ns ns = new Ns();
168                         ns.setName(nd.name);
169                         if(nd.admin!=null) {
170                                 ns.getAdmin().addAll(nd.admin);
171                         }
172                         if(nd.owner!=null) {
173                                 ns.getResponsible().addAll(nd.owner);
174                         }
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);
182                                 }
183                         }
184
185                         nss.add(ns);
186                 }
187                 return Result.ok(to);
188         }
189
190         @Override
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);
195                 try {
196                         if(from!=null) {
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);
204                                                 if(addNS) {
205                                                         perm.setNs(data.ns);
206                                                 }
207                                                 for(String role : data.roles(false)) {
208                                                         perm.getRoles().add(role);
209                                                 }
210                                                 perms.add(perm);
211                                         }
212                                 }
213                         }
214                 } finally {
215                         tt.done();
216                 }
217                  
218                 tt = trans.start("Sort Perms", Env.SUB);
219                 try {
220                         Collections.sort(perms, new Comparator<Perm>() {
221                                 @Override
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());
228                                                 }
229                                                 return instanceCompare;
230                                         }
231                                         return typeCompare;
232                                 }       
233                         });
234                 } finally {
235                         tt.done();
236                 }
237                 return Result.ok(to);
238         }
239         
240         @Override
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);
244                 try {
245                         if(from!=null) {
246                                 boolean inNSS;
247                                 for (PermDAO.Data data : from) {
248                                         inNSS=false;
249                                         for(int i=0;!inNSS && i<nss.length;++i) {
250                                                 if(nss[i].equals(data.ns)) {
251                                                         inNSS=true;
252                                                 }
253                                         }
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);
261                                                 }
262                                                 perm.setDescription(data.description);
263                                                 perms.add(perm);
264                                         }
265                                 }
266                         }
267                 } finally {
268                         tt.done();
269                 }
270                  
271                 tt = trans.start("Sort Perms", Env.SUB);
272                 try {
273                         Collections.sort(perms, new Comparator<Perm>() {
274                                 @Override
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());
281                                                 }
282                                                 return instanceCompare;
283                                         }
284                                         return typeCompare;
285                                 }       
286                         });
287                 } finally {
288                         tt.done();
289                 }
290                 return Result.ok(to);
291         }
292
293         @Override
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();
299                         if(nss.isOK()) { 
300                                 pd.ns=nss.value.ns;
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);
306                                 }
307                                 lpd.add(pd);
308                         } else {
309                                 return Result.err(nss);
310                         }
311                 }
312                 return Result.ok(lpd);
313         }
314
315         
316         @Override
317         public Result<PermDAO.Data> permkey(AuthzTrans trans, Pkey from) {
318                 return q.permFrom(trans, from.getType(),from.getInstance(),from.getAction());
319         }
320         
321         @Override
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();
328                 if(nss.isOK()) { 
329                         pd.ns=nss.value.ns;
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);
334                         
335                         String[] roles = {};
336                         
337                         if (from.getRole() != null) {
338                                 roles = from.getRole().split(",");
339                         }
340                         for (String role : roles) { 
341                                 pd.roles(true).add(role);
342                         }
343                         return Result.ok(pd);
344                 } else {
345                         return Result.err(nss);
346                 }
347         }
348         
349         @Override
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();
354                 if(nss.isOK()) { 
355                         rd.ns = nss.value.ns;
356                         rd.name = nss.value.name;
357                         trans.checkpoint(rd.fullName(), Env.ALWAYS);
358                         return Result.ok(rd);
359                 } else {
360                         return Result.err(nss);
361                 }
362         }
363         
364         @Override
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();
369                 if(nss.isOK()) { 
370                         pd.ns=nss.value.ns;
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);
377                 } else {
378                         return Result.err(nss);
379                 }
380         }
381         
382         @Override
383         public Request ungrantRequest(AuthzTrans trans, String role, String type, String instance, String action) {
384                 RolePermRequest rpr = new RolePermRequest();
385                 Pkey pkey = new Pkey();
386                 pkey.setType(type);
387                 pkey.setInstance(instance);
388                 pkey.setAction(action);
389                 rpr.setPerm(pkey);
390                 
391                 rpr.setRole(role);
392                 return rpr;
393         }
394
395         @Override
396         public Result<RoleDAO.Data> role(AuthzTrans trans, Request base) {
397                 RoleRequest from = (RoleRequest)base;
398                 Result<NsSplit> nss = q.deriveNsSplit(trans, from.getName());
399                 if(nss.isOK()) {
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);
405
406                         return Result.ok(to);
407                 } else {
408                         return Result.err(nss);
409                 }
410         }
411
412         /* (non-Javadoc)
413          * @see org.onap.aaf.auth.service.mapper.Mapper#roles(java.util.List)
414          */
415         @Override
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);
424                                 if(needNS) {
425                                         role.setNs(frole.ns);
426                                 }
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);
429                                         if(rpa.notOK())
430                                                 return Result.err(rpa);
431                                         
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);
438                                 }
439                                 to.getRole().add(role);
440                         }
441                 }
442                 return Result.ok(to);
443         }
444
445         /*
446          * (non-Javadoc)
447          * @see org.onap.aaf.auth.service.mapper.Mapper#users(java.util.Collection, java.lang.Object)
448          * 
449          * Note: Prevalidate all data for permission to view
450          */
451         @Override
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));
459                         }
460                         cu.add(user);
461                 }
462                 return Result.ok(to);
463         }
464
465         /*
466          * (non-Javadoc)
467          * @see org.onap.aaf.auth.service.mapper.Mapper#users(java.util.Collection, java.lang.Object)
468          * 
469          * Note: Prevalidate all data for permission to view
470          */
471         @Override
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));
479                         cu.add(ur);
480                 }
481                 return Result.ok(to);
482         }
483
484         @Override
485         public Result<UserRoleDAO.Data> userRole(AuthzTrans trans, Request base) {
486                 try {
487                         UserRoleRequest from = (UserRoleRequest)base;
488
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();
493                         }
494                         if (from.getRole() != null) {
495                                 to.role(trans,q,from.getRole());
496                         }
497                         to.expires = getExpires(trans.org(),Expiration.UserInRole,base,from.getUser());
498                         trans.checkpoint(to.toString(), Env.ALWAYS);
499
500                         return Result.ok(to);
501                 } catch (Exception t) {
502                         return Result.err(Status.ERR_BadData,t.getMessage());
503                 }
504         }
505
506         @Override
507         public Result<CredDAO.Data> cred(AuthzTrans trans, Request base, boolean requiresPass) {
508                 CredRequest from = (CredRequest)base;
509                 CredDAO.Data to = new CredDAO.Data();
510                 to.id=from.getId();
511                 to.ns = Question.domain2ns(to.id);
512                 String passwd = from.getPassword();
513                 if(requiresPass) {
514                         String ok = trans.org().isValidPassword(trans, to.id,passwd);
515                         if(ok.length()>0) {
516                                 return Result.err(Status.ERR_BadData,ok);
517                         }
518                 } else {
519                         to.type=0;
520                 }
521                 if(passwd != null) {
522                         to.cred = ByteBuffer.wrap(passwd.getBytes());
523                         to.type = CredDAO.RAW; 
524                 } else {
525                         to.type = 0;
526                 }
527                 
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);
532
533                 return Result.ok(to);
534         }
535         
536         @Override
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();
541                         user.setId(cred.id);
542                         user.setExpires(Chrono.timeStamp(cred.expires));
543                         user.setType(cred.type);
544                         cu.add(user);
545                 }
546                 return Result.ok(to);
547         }
548         
549         @Override
550         public Result<Certs> cert(List<CertDAO.Data> from, Certs to) {
551                 List<Cert> lc = to.getCert();
552                 for(CertDAO.Data fcred : from) {
553                         Cert cert = new Cert();
554                         cert.setId(fcred.id);
555                         cert.setX500(fcred.x500);
556                         /**TODO - change Interface 
557                          * @deprecated */
558                         cert.setFingerprint(fcred.serial.toByteArray());
559                         lc.add(cert);
560                 }
561                 return Result.ok(to);
562         }
563
564         /**
565          * Analyze whether Requests should be acted on now, or in the future, based on Start Date, and whether the requester
566          * is allowed to change this value directly
567          * 
568          * Returning Result.OK means it should be done in the future.
569          * Returning Result.ACC_Now means to act on table change now.
570          */
571         @Override
572         public Result<FutureDAO.Data> future(AuthzTrans trans, String table, Request from, 
573                                 Bytification content, boolean enableApproval,  Memo memo, MayChange mc) {
574                 Result<?> rMayChange;
575                 boolean needsAppr = enableApproval?trans.requested(REQD_TYPE.future):false; 
576                 if(!needsAppr && (needsAppr = (rMayChange=mc.mayChange()).notOK())) {
577                         if(enableApproval) {
578                                 if(!trans.requested(AuthzTrans.REQD_TYPE.future)) {
579                                         return Result.err(rMayChange);
580                                 }
581                         } else {
582                                 return Result.err(rMayChange);
583                         }
584                 }
585                 GregorianCalendar now = new GregorianCalendar(); 
586                 GregorianCalendar start = from.getStart()==null?now:from.getStart().toGregorianCalendar();
587                 
588                 GregorianCalendar expires = trans.org().expiration(start, Expiration.Future);
589                 XMLGregorianCalendar xgc;
590                 if((xgc=from.getEnd())!=null) {
591                         GregorianCalendar fgc = xgc.toGregorianCalendar();
592                         expires = expires.before(fgc)?expires:fgc; // Min of desired expiration, and Org expiration
593                 }
594                 
595                 //TODO needs two answers from this.  What's the NSS, and may Change.
596                 FutureDAO.Data fto;
597                 if(start.after(now) || needsAppr ) {
598                         //String user = trans.user();
599                         fto = new FutureDAO.Data();
600                         fto.target=table;
601                         fto.memo = memo.get();
602                         fto.start = start.getTime();
603                         fto.expires = expires.getTime();
604                         if(needsAppr) { // Need to add Approvers...
605                                 /*
606                                 Result<Data> rslt = mc.getNsd();
607                                 if(rslt.notOKorIsEmpty())return Result.err(rslt);
608                                 appr.addAll(mc.getNsd().value.responsible);
609                                 try {
610                                         //Note from 2013 Is this getting Approvers for user only?  What about Delegates?
611                                         // 3/25/2014.  Approvers are set by Corporate policy.  We don't have to worry here about what that means.
612                                         // It is important to get Delegates, if necessary, at notification time
613                                         // If we add delegates now, it will get all confused as to who is actually responsible.
614                                         for(Organization.User ou : org.getApprovers(trans, user)) {
615                                                 appr.add(ou.email);
616                                         }
617                                 } catch (Exception e) {
618                                         return Result.err(Status.ERR_Policy,org.getName() + " did not respond with Approvers: " + e.getLocalizedMessage());
619                                 }
620                                 */
621                         }
622                         try {
623                                 fto.construct = content.bytify();
624                         } catch (Exception e) {
625                                 return Result.err(Status.ERR_BadData,"Data cannot be saved for Future.");
626                         }
627                 } else {
628                         return Result.err(Status.ACC_Now, "Make Data changes now.");
629                 }
630                 return Result.ok(fto);
631         }
632
633
634         /* (non-Javadoc)
635          * @see org.onap.aaf.auth.service.mapper.Mapper#history(java.util.List)
636          */
637         @Override
638         public Result<History> history(AuthzTrans trans, List<HistoryDAO.Data> history, final int sort) {
639                 History hist = new History();
640                 List<Item> items = hist.getItem();
641                 for(HistoryDAO.Data data : history) {
642                         History.Item item = new History.Item();
643                         item.setYYYYMM(Integer.toString(data.yr_mon));
644                         Date date = Chrono.uuidToDate(data.id);
645                         item.setTimestamp(Chrono.timeStamp(date));
646                         item.setAction(data.action);
647                         item.setMemo(data.memo);
648                         item.setSubject(data.subject);
649                         item.setTarget(data.target);
650                         item.setUser(data.user);
651                         items.add(item);
652                 }
653                 
654                 if(sort != 0) {
655                         TimeTaken tt = trans.start("Sort ", Env.SUB);
656                         try {
657                                 java.util.Collections.sort(items, new Comparator<Item>() {
658                                         @Override
659                                         public int compare(Item o1, Item o2) {
660                                                 return sort*(o1.getTimestamp().compare(o2.getTimestamp()));
661                                         }
662                                 });
663                         } finally {
664                                 tt.done();
665                         }
666                 }
667                 return Result.ok(hist);
668         }
669
670         @Override
671         public Error errorFromMessage(StringBuilder holder, String msgID, String text, String... var) {
672                 Error err = new Error();
673                 err.setMessageId(msgID);
674                 // AT&T Restful Error Format requires numbers "%" placements
675                 err.setText(Vars.convert(holder, text, var));
676                 for(String s : var) {
677                         err.getVariables().add(s);
678                 }
679                 return err;
680         }
681         
682         @Override
683         public Class<?> getClass(API api) {
684                 switch(api) {
685                         case NSS:  return Nss.class;
686                         case NS_REQ: return NsRequest.class;
687                         case PERMS: return Perms.class;
688                         case PERM_KEY: return PermKey.class;
689                         case ROLES: return Roles.class;
690                         case ROLE: return Role.class;
691                         case USERS: return Users.class;
692                         case DELGS: return Delgs.class;
693                         case CERTS: return Certs.class;
694                         case DELG_REQ: return DelgRequest.class;
695                         case PERM_REQ: return PermRequest.class;
696                         case ROLE_REQ:  return RoleRequest.class;
697                         case CRED_REQ:  return CredRequest.class;
698                         case USER_ROLE_REQ:  return UserRoleRequest.class;
699                         case USER_ROLES: return UserRoles.class;
700                         case ROLE_PERM_REQ:  return RolePermRequest.class;
701                         case APPROVALS: return Approvals.class;
702                         case KEYS: return Keys.class;
703                         case HISTORY: return History.class;
704 //                      case MODEL: return Model.class;
705                         case ERROR: return Error.class;
706                         case API: return Api.class;
707                         case VOID: return Void.class;
708                 }
709                 return null;
710         }
711
712         @SuppressWarnings("unchecked")
713         @Override
714         public <A> A newInstance(API api) {
715                 switch(api) {
716                         case NS_REQ: return (A) new NsRequest();
717                         case NSS: return (A) new Nss();
718                         case PERMS: return (A)new Perms();
719                         case PERM_KEY: return (A)new PermKey();
720                         case ROLES: return (A)new Roles();
721                         case ROLE: return (A)new Role();
722                         case USERS: return (A)new Users();
723                         case DELGS: return (A)new Delgs();
724                         case CERTS: return (A)new Certs();
725                         case PERM_REQ: return (A)new PermRequest();
726                         case CRED_REQ: return (A)new CredRequest();
727                         case ROLE_REQ:  return (A)new RoleRequest();
728                         case USER_ROLE_REQ:  return (A)new UserRoleRequest();
729                         case USER_ROLES:  return (A)new UserRoles();
730                         case ROLE_PERM_REQ:  return (A)new RolePermRequest();
731                         case HISTORY: return (A)new History();
732                         case KEYS: return (A)new Keys();
733                         //case MODEL: return (A)new Model();
734                         case ERROR: return (A)new Error();
735                         case API: return (A)new Api();
736                         case VOID: return null;
737                         
738                         case APPROVALS: return (A) new Approvals();
739                         case DELG_REQ: return (A) new DelgRequest();
740                 }
741                 return null;
742         }
743         
744         @SuppressWarnings("unchecked")
745         /**
746          * Get Typed Marshaler as they are defined
747          * 
748          * @param api
749          * @return
750          */
751         public <A> Marshal<A> getMarshal(API api) {
752                 switch(api) {
753                         case CERTS: return (Marshal<A>) new CertsMarshal();
754                         default:
755                                 return null;
756                 }
757         }
758
759         @Override
760         public Result<Approvals> approvals(List<ApprovalDAO.Data> lAppr) {
761                 Approvals apprs = new Approvals();
762                 List<Approval> lappr = apprs.getApprovals();
763                 Approval a;
764                 for(ApprovalDAO.Data appr : lAppr) {
765                         a = new Approval();
766                         a.setId(appr.id.toString());
767                         if(appr.ticket==null) {
768                                 a.setTicket(null);
769                         } else {
770                                 a.setTicket(appr.ticket.toString());
771                         }
772                         a.setUser(appr.user);
773                         a.setApprover(appr.approver);
774                         a.setType(appr.type);
775                         a.setStatus(appr.status);
776                         a.setMemo(appr.memo);
777                         a.setOperation(appr.operation);
778                         a.setUpdated(Chrono.timeStamp(appr.updated));
779                         lappr.add(a);
780                 }
781                 return Result.ok(apprs);
782         }
783         
784         @Override
785         public Result<List<ApprovalDAO.Data>> approvals(Approvals apprs) {
786                 List<ApprovalDAO.Data>  lappr = new ArrayList<>();
787                 for(Approval a : apprs.getApprovals()) {
788                         ApprovalDAO.Data ad = new ApprovalDAO.Data();
789                         String str = a.getId();
790                         if(str!=null)ad.id=UUID.fromString(str);
791                         str = a.getTicket();
792                         if(str!=null)ad.ticket=UUID.fromString(str);
793                         ad.user=a.getUser();
794                         ad.approver=a.getApprover();
795                         ad.type=a.getType();
796                         ad.status=a.getStatus();
797                         ad.operation=a.getOperation();
798                         ad.memo=a.getMemo();
799                         
800                         XMLGregorianCalendar xgc = a.getUpdated();
801                         if(xgc!=null)ad.updated=xgc.toGregorianCalendar().getTime();
802                         lappr.add(ad);
803                 }
804                 return Result.ok(lappr);
805         }
806
807         @Override
808         public Result<Delgs> delegate(List<DelegateDAO.Data> lDelg) {
809                 Delgs delgs = new Delgs();
810                 List<Delg> ldelg = delgs.getDelgs();
811                 Delg d;
812                 for(DelegateDAO.Data del: lDelg) {
813                         d = new Delg();
814                         d.setUser(del.user);
815                         d.setDelegate(del.delegate);
816                         if(del.expires!=null)d.setExpires(Chrono.timeStamp(del.expires));
817                         ldelg.add(d);
818                 }
819                 return Result.ok(delgs);
820         }
821
822         @Override
823         public Result<Data> delegate(AuthzTrans trans, Request base) {
824                 try {
825                         DelgRequest from = (DelgRequest)base;
826                         DelegateDAO.Data to = new DelegateDAO.Data();
827                         String user = from.getUser();
828                         to.user = user;
829                         String delegate = from.getDelegate();
830                         to.delegate = delegate;
831                         to.expires = getExpires(trans.org(),Expiration.UserDelegate,base,from.getUser());
832                         trans.checkpoint(to.user+"=>"+to.delegate, Env.ALWAYS);
833
834                         return Result.ok(to);
835                 } catch (Exception t) {
836                         return Result.err(Status.ERR_BadData,t.getMessage());
837                 }
838         }
839
840         /*
841          * We want "Expired" dates to start at a specified time set by the Organization, and consistent wherever
842          * the date is created from.
843          */ 
844         private Date getExpires(Organization org, Expiration exp, Request base, String id) {
845                 XMLGregorianCalendar end = base.getEnd();
846                 GregorianCalendar gc = end==null?new GregorianCalendar():end.toGregorianCalendar();
847                 GregorianCalendar orggc;
848                 orggc = org.expiration(gc,exp,id); 
849
850                 // We'll choose the lesser of dates to ensure Policy Compliance...
851         
852                 GregorianCalendar endgc = end==null||gc.after(orggc)?orggc:gc;
853                 // Allow the Organization to determine when official "day Start" begins, Specifically when to consider something Expired.
854                 endgc = Chrono.firstMomentOfDay(endgc);
855                 endgc.set(GregorianCalendar.HOUR_OF_DAY, org.startOfDay());
856                 return endgc.getTime();
857         }
858
859
860         @Override
861         public Result<Keys> keys(Collection<String> from) {
862                 Keys keys = new Keys();
863                 keys.getKey().addAll(from);
864                 return Result.ok(keys).emptyList(from.isEmpty());
865         }
866
867 }