AT&T 2.0.19 Code drop, stage 3
[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<PermDAO.Data>();
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.mayUserViewRole(trans, trans.user(), frole).isOK()) {
421                         if(!filter || q.mayUser(trans, trans.user(), frole,Access.read).isOK()) {
422                                 Role role = new Role();
423                                 role.setName(frole.ns + '.' + frole.name);
424                                 role.setDescription(frole.description);
425                                 if(needNS) {
426                                         role.setNs(frole.ns);
427                                 }
428                                 for(String p : frole.perms(false)) { // can see any Perms in the Role he has permission for
429                                         Result<String[]> rpa = PermDAO.Data.decodeToArray(trans,q,p);
430                                         if(rpa.notOK()) 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         /**
485          * 
486          * @param base
487          * @param start
488          * @return
489          */
490         @Override
491         public Result<UserRoleDAO.Data> userRole(AuthzTrans trans, Request base) {
492                 try {
493                         UserRoleRequest from = (UserRoleRequest)base;
494
495                         // Setup UserRoleData, either for immediate placement, or for futureIt i
496                         UserRoleDAO.Data to = new UserRoleDAO.Data();
497                         if (from.getUser() != null) {
498                                 String user = from.getUser();
499                                 to.user = user;
500                         }
501                         if (from.getRole() != null) {
502                                 to.role(trans,q,from.getRole());
503                         }
504                         to.expires = getExpires(trans.org(),Expiration.UserInRole,base,from.getUser());
505                         trans.checkpoint(to.toString(), Env.ALWAYS);
506
507                         return Result.ok(to);
508                 } catch (Exception t) {
509                         return Result.err(Status.ERR_BadData,t.getMessage());
510                 }
511         }
512
513         @Override
514         public Result<CredDAO.Data> cred(AuthzTrans trans, Request base, boolean requiresPass) {
515                 CredRequest from = (CredRequest)base;
516                 CredDAO.Data to = new CredDAO.Data();
517                 to.id=from.getId();
518                 to.ns = Question.domain2ns(to.id);
519                 String passwd = from.getPassword();
520                 if(requiresPass) {
521                         String ok = trans.org().isValidPassword(trans, to.id,passwd);
522                         if(ok.length()>0) {
523                                 return Result.err(Status.ERR_BadData,ok);
524                         }
525
526                 } else {
527                         to.type=0;
528                 }
529                 if(passwd != null) {
530                         to.cred = ByteBuffer.wrap(passwd.getBytes());
531                         to.type = CredDAO.RAW; 
532                 } else {
533                         to.type = 0;
534                 }
535                 
536                 // Note: Ensure requested EndDate created will match Organization Password Rules
537                 //  P.S. Do not apply TempPassword rule here. Do that when you know you are doing a Create/Reset (see Service)
538                 to.expires = getExpires(trans.org(),Expiration.Password,base,from.getId());
539                 trans.checkpoint(to.id, Env.ALWAYS);
540
541                 return Result.ok(to);
542         }
543         
544         @Override
545         public Result<Users> cred(List<CredDAO.Data> from, Users to) {
546                 List<User> cu = to.getUser();
547                 for(CredDAO.Data cred : from) {
548                         User user = new User();
549                         user.setId(cred.id);
550                         user.setExpires(Chrono.timeStamp(cred.expires));
551                         user.setType(cred.type);
552                         cu.add(user);
553                 }
554                 return Result.ok(to);
555         }
556         
557         @Override
558         public Result<Certs> cert(List<CertDAO.Data> from, Certs to) {
559                 List<Cert> lc = to.getCert();
560                 for(CertDAO.Data fcred : from) {
561                         Cert cert = new Cert();
562                         cert.setId(fcred.id);
563                         cert.setX500(fcred.x500);
564                         /**TODO - change Interface 
565                          * @deprecated */
566                         cert.setFingerprint(fcred.serial.toByteArray());
567                         lc.add(cert);
568                 }
569                 return Result.ok(to);
570         }
571
572         /**
573          * Analyze whether Requests should be acted on now, or in the future, based on Start Date, and whether the requester
574          * is allowed to change this value directly
575          * 
576          * Returning Result.OK means it should be done in the future.
577          * Returning Result.ACC_Now means to act on table change now.
578          */
579         @Override
580         public Result<FutureDAO.Data> future(AuthzTrans trans, String table, Request from, 
581                                 Bytification content, boolean enableApproval,  Memo memo, MayChange mc) {
582                 Result<?> rMayChange;
583                 boolean needsAppr = enableApproval?trans.requested(REQD_TYPE.future):false; 
584                 if(!needsAppr && (needsAppr = (rMayChange=mc.mayChange()).notOK())) {
585                         if(enableApproval) {
586                                 if(!trans.requested(AuthzTrans.REQD_TYPE.future)) {
587                                         return Result.err(rMayChange);
588                                 }
589                         } else {
590                                 return Result.err(rMayChange);
591                         }
592                 }
593                 GregorianCalendar now = new GregorianCalendar(); 
594                 GregorianCalendar start = from.getStart()==null?now:from.getStart().toGregorianCalendar();
595                 
596                 GregorianCalendar expires = trans.org().expiration(start, Expiration.Future);
597                 XMLGregorianCalendar xgc;
598                 if((xgc=from.getEnd())!=null) {
599                         GregorianCalendar fgc = xgc.toGregorianCalendar();
600                         expires = expires.before(fgc)?expires:fgc; // Min of desired expiration, and Org expiration
601                 }
602                 
603                 //TODO needs two answers from this.  What's the NSS, and may Change.
604                 FutureDAO.Data fto;
605                 if(start.after(now) || needsAppr ) {
606                         //String user = trans.user();
607                         fto = new FutureDAO.Data();
608                         fto.target=table;
609                         fto.memo = memo.get();
610                         fto.start = start.getTime();
611                         fto.expires = expires.getTime();
612                         if(needsAppr) { // Need to add Approvers...
613                                 /*
614                                 Result<Data> rslt = mc.getNsd();
615                                 if(rslt.notOKorIsEmpty())return Result.err(rslt);
616                                 appr.addAll(mc.getNsd().value.responsible);
617                                 try {
618                                         //Note from 2013 Is this getting Approvers for user only?  What about Delegates?
619                                         // 3/25/2014.  Approvers are set by Corporate policy.  We don't have to worry here about what that means.
620                                         // It is important to get Delegates, if necessary, at notification time
621                                         // If we add delegates now, it will get all confused as to who is actually responsible.
622                                         for(Organization.User ou : org.getApprovers(trans, user)) {
623                                                 appr.add(ou.email);
624                                         }
625                                 } catch (Exception e) {
626                                         return Result.err(Status.ERR_Policy,org.getName() + " did not respond with Approvers: " + e.getLocalizedMessage());
627                                 }
628                                 */
629                         }
630                         try {
631                                 fto.construct = content.bytify();
632                         } catch (Exception e) {
633                                 return Result.err(Status.ERR_BadData,"Data cannot be saved for Future.");
634                         }
635                 } else {
636                         return Result.err(Status.ACC_Now, "Make Data changes now.");
637                 }
638                 return Result.ok(fto);
639         }
640
641
642         /* (non-Javadoc)
643          * @see org.onap.aaf.auth.service.mapper.Mapper#history(java.util.List)
644          */
645         @Override
646         public Result<History> history(AuthzTrans trans, List<HistoryDAO.Data> history, final int sort) {
647                 History hist = new History();
648                 List<Item> items = hist.getItem();
649                 for(HistoryDAO.Data data : history) {
650                         History.Item item = new History.Item();
651                         item.setYYYYMM(Integer.toString(data.yr_mon));
652                         Date date = Chrono.uuidToDate(data.id);
653                         item.setTimestamp(Chrono.timeStamp(date));
654                         item.setAction(data.action);
655                         item.setMemo(data.memo);
656                         item.setSubject(data.subject);
657                         item.setTarget(data.target);
658                         item.setUser(data.user);
659                         items.add(item);
660                 }
661                 
662                 if(sort != 0) {
663                         TimeTaken tt = trans.start("Sort ", Env.SUB);
664                         try {
665                                 java.util.Collections.sort(items, new Comparator<Item>() {
666                                         @Override
667                                         public int compare(Item o1, Item o2) {
668                                                 return sort*(o1.getTimestamp().compare(o2.getTimestamp()));
669                                         }
670                                 });
671                         } finally {
672                                 tt.done();
673                         }
674                 }
675                 return Result.ok(hist);
676         }
677
678         @Override
679         public Error errorFromMessage(StringBuilder holder, String msgID, String text, String... var) {
680                 Error err = new Error();
681                 err.setMessageId(msgID);
682                 // AT&T Restful Error Format requires numbers "%" placements
683                 err.setText(Vars.convert(holder, text, var));
684                 for(String s : var) {
685                         err.getVariables().add(s);
686                 }
687                 return err;
688         }
689         
690         @Override
691         public Class<?> getClass(API api) {
692                 switch(api) {
693                         case NSS:  return Nss.class;
694                         case NS_REQ: return NsRequest.class;
695                         case PERMS: return Perms.class;
696                         case PERM_KEY: return PermKey.class;
697                         case ROLES: return Roles.class;
698                         case ROLE: return Role.class;
699                         case USERS: return Users.class;
700                         case DELGS: return Delgs.class;
701                         case CERTS: return Certs.class;
702                         case DELG_REQ: return DelgRequest.class;
703                         case PERM_REQ: return PermRequest.class;
704                         case ROLE_REQ:  return RoleRequest.class;
705                         case CRED_REQ:  return CredRequest.class;
706                         case USER_ROLE_REQ:  return UserRoleRequest.class;
707                         case USER_ROLES: return UserRoles.class;
708                         case ROLE_PERM_REQ:  return RolePermRequest.class;
709                         case APPROVALS: return Approvals.class;
710                         case KEYS: return Keys.class;
711                         case HISTORY: return History.class;
712 //                      case MODEL: return Model.class;
713                         case ERROR: return Error.class;
714                         case API: return Api.class;
715                         case VOID: return Void.class;
716                 }
717                 return null;
718         }
719
720         @SuppressWarnings("unchecked")
721         @Override
722         public <A> A newInstance(API api) {
723                 switch(api) {
724                         case NS_REQ: return (A) new NsRequest();
725                         case NSS: return (A) new Nss();
726                         case PERMS: return (A)new Perms();
727                         case PERM_KEY: return (A)new PermKey();
728                         case ROLES: return (A)new Roles();
729                         case ROLE: return (A)new Role();
730                         case USERS: return (A)new Users();
731                         case DELGS: return (A)new Delgs();
732                         case CERTS: return (A)new Certs();
733                         case PERM_REQ: return (A)new PermRequest();
734                         case CRED_REQ: return (A)new CredRequest();
735                         case ROLE_REQ:  return (A)new RoleRequest();
736                         case USER_ROLE_REQ:  return (A)new UserRoleRequest();
737                         case USER_ROLES:  return (A)new UserRoles();
738                         case ROLE_PERM_REQ:  return (A)new RolePermRequest();
739                         case HISTORY: return (A)new History();
740                         case KEYS: return (A)new Keys();
741                         //case MODEL: return (A)new Model();
742                         case ERROR: return (A)new Error();
743                         case API: return (A)new Api();
744                         case VOID: return null;
745                         
746                         case APPROVALS: return (A) new Approvals();
747                         case DELG_REQ: return (A) new DelgRequest();
748                 }
749                 return null;
750         }
751         
752         @SuppressWarnings("unchecked")
753         /**
754          * Get Typed Marshaler as they are defined
755          * 
756          * @param api
757          * @return
758          */
759         public <A> Marshal<A> getMarshal(API api) {
760                 switch(api) {
761                         case CERTS: return (Marshal<A>) new CertsMarshal();
762                         default:
763                                 return null;
764                 }
765         }
766
767         @Override
768         public Result<Approvals> approvals(List<ApprovalDAO.Data> lAppr) {
769                 Approvals apprs = new Approvals();
770                 List<Approval> lappr = apprs.getApprovals();
771                 Approval a;
772                 for(ApprovalDAO.Data appr : lAppr) {
773                         a = new Approval();
774                         a.setId(appr.id.toString());
775                         if(appr.ticket==null) {
776                                 a.setTicket(null);
777                         } else {
778                                 a.setTicket(appr.ticket.toString());
779                         }
780                         a.setUser(appr.user);
781                         a.setApprover(appr.approver);
782                         a.setType(appr.type);
783                         a.setStatus(appr.status);
784                         a.setMemo(appr.memo);
785                         a.setOperation(appr.operation);
786                         a.setUpdated(Chrono.timeStamp(appr.updated));
787                         lappr.add(a);
788                 }
789                 return Result.ok(apprs);
790         }
791         
792         @Override
793         public Result<List<ApprovalDAO.Data>> approvals(Approvals apprs) {
794                 List<ApprovalDAO.Data>  lappr = new ArrayList<ApprovalDAO.Data>();
795                 for(Approval a : apprs.getApprovals()) {
796                         ApprovalDAO.Data ad = new ApprovalDAO.Data();
797                         String str = a.getId();
798                         if(str!=null)ad.id=UUID.fromString(str);
799                         str = a.getTicket();
800                         if(str!=null)ad.ticket=UUID.fromString(str);
801                         ad.user=a.getUser();
802                         ad.approver=a.getApprover();
803                         ad.type=a.getType();
804                         ad.status=a.getStatus();
805                         ad.operation=a.getOperation();
806                         ad.memo=a.getMemo();
807                         
808                         XMLGregorianCalendar xgc = a.getUpdated();
809                         if(xgc!=null)ad.updated=xgc.toGregorianCalendar().getTime();
810                         lappr.add(ad);
811                 }
812                 return Result.ok(lappr);
813         }
814
815         @Override
816         public Result<Delgs> delegate(List<DelegateDAO.Data> lDelg) {
817                 Delgs delgs = new Delgs();
818                 List<Delg> ldelg = delgs.getDelgs();
819                 Delg d;
820                 for(DelegateDAO.Data del: lDelg) {
821                         d = new Delg();
822                         d.setUser(del.user);
823                         d.setDelegate(del.delegate);
824                         if(del.expires!=null)d.setExpires(Chrono.timeStamp(del.expires));
825                         ldelg.add(d);
826                 }
827                 return Result.ok(delgs);
828         }
829
830         @Override
831         public Result<Data> delegate(AuthzTrans trans, Request base) {
832                 try {
833                         DelgRequest from = (DelgRequest)base;
834                         DelegateDAO.Data to = new DelegateDAO.Data();
835                         String user = from.getUser();
836                         to.user = user;
837                         String delegate = from.getDelegate();
838                         to.delegate = delegate;
839                         to.expires = getExpires(trans.org(),Expiration.UserDelegate,base,from.getUser());
840                         trans.checkpoint(to.user+"=>"+to.delegate, Env.ALWAYS);
841
842                         return Result.ok(to);
843                 } catch (Exception t) {
844                         return Result.err(Status.ERR_BadData,t.getMessage());
845                 }
846         }
847
848         /*
849          * We want "Expired" dates to start at a specified time set by the Organization, and consistent wherever
850          * the date is created from.
851          */ 
852         private Date getExpires(Organization org, Expiration exp, Request base, String id) {
853                 XMLGregorianCalendar end = base.getEnd();
854                 GregorianCalendar gc = end==null?new GregorianCalendar():end.toGregorianCalendar();
855                 GregorianCalendar orggc;
856                 orggc = org.expiration(gc,exp,id); 
857
858                 // We'll choose the lesser of dates to ensure Policy Compliance...
859         
860                 GregorianCalendar endgc = end==null||gc.after(orggc)?orggc:gc;
861                 // Allow the Organization to determine when official "day Start" begins, Specifically when to consider something Expired.
862                 endgc = Chrono.firstMomentOfDay(endgc);
863                 endgc.set(GregorianCalendar.HOUR_OF_DAY, org.startOfDay());
864                 return endgc.getTime();
865         }
866
867
868         @Override
869         public Result<Keys> keys(Collection<String> from) {
870                 Keys keys = new Keys();
871                 keys.getKey().addAll(from);
872                 return Result.ok(keys).emptyList(from.isEmpty());
873         }
874
875 }