c552cc938ec63325c85814173c40d586581aacc2
[aaf/authz.git] / authz-cass / src / main / java / org / onap / aaf / dao / aaf / hl / Question.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aaf\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * ===========================================================================\r
7  * * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * * you may not use this file except in compliance with the License.\r
9  * * You may obtain a copy of the License at\r
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \r
13  *  * Unless required by applicable law or agreed to in writing, software\r
14  * * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * * See the License for the specific language governing permissions and\r
17  * * limitations under the License.\r
18  * * ============LICENSE_END====================================================\r
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 package org.onap.aaf.dao.aaf.hl;\r
24 \r
25 import java.io.IOException;\r
26 import java.nio.ByteBuffer;\r
27 import java.security.NoSuchAlgorithmException;\r
28 import java.security.SecureRandom;\r
29 import java.util.ArrayList;\r
30 import java.util.Collections;\r
31 import java.util.Comparator;\r
32 import java.util.Date;\r
33 import java.util.HashSet;\r
34 import java.util.List;\r
35 import java.util.Set;\r
36 import java.util.TreeSet;\r
37 \r
38 import org.onap.aaf.authz.common.Define;\r
39 import org.onap.aaf.authz.env.AuthzTrans;\r
40 import org.onap.aaf.authz.env.AuthzTransFilter;\r
41 import org.onap.aaf.authz.layer.Result;\r
42 import org.onap.aaf.authz.org.Organization;\r
43 import org.onap.aaf.authz.org.Organization.Identity;\r
44 import org.onap.aaf.dao.AbsCassDAO;\r
45 import org.onap.aaf.dao.CachedDAO;\r
46 import org.onap.aaf.dao.DAOException;\r
47 import org.onap.aaf.dao.aaf.cached.CachedCertDAO;\r
48 import org.onap.aaf.dao.aaf.cached.CachedCredDAO;\r
49 import org.onap.aaf.dao.aaf.cached.CachedNSDAO;\r
50 import org.onap.aaf.dao.aaf.cached.CachedPermDAO;\r
51 import org.onap.aaf.dao.aaf.cached.CachedRoleDAO;\r
52 import org.onap.aaf.dao.aaf.cached.CachedUserRoleDAO;\r
53 import org.onap.aaf.dao.aaf.cass.ApprovalDAO;\r
54 import org.onap.aaf.dao.aaf.cass.CacheInfoDAO;\r
55 import org.onap.aaf.dao.aaf.cass.CertDAO;\r
56 import org.onap.aaf.dao.aaf.cass.CredDAO;\r
57 import org.onap.aaf.dao.aaf.cass.DelegateDAO;\r
58 import org.onap.aaf.dao.aaf.cass.FutureDAO;\r
59 import org.onap.aaf.dao.aaf.cass.HistoryDAO;\r
60 import org.onap.aaf.dao.aaf.cass.NsDAO;\r
61 import org.onap.aaf.dao.aaf.cass.NsSplit;\r
62 import org.onap.aaf.dao.aaf.cass.NsType;\r
63 import org.onap.aaf.dao.aaf.cass.PermDAO;\r
64 import org.onap.aaf.dao.aaf.cass.RoleDAO;\r
65 import org.onap.aaf.dao.aaf.cass.Status;\r
66 import org.onap.aaf.dao.aaf.cass.UserRoleDAO;\r
67 import org.onap.aaf.dao.aaf.cass.NsDAO.Data;\r
68 \r
69 import org.onap.aaf.cadi.Hash;\r
70 import org.onap.aaf.cadi.aaf.PermEval;\r
71 import org.onap.aaf.inno.env.APIException;\r
72 import org.onap.aaf.inno.env.Env;\r
73 import org.onap.aaf.inno.env.Slot;\r
74 import org.onap.aaf.inno.env.TimeTaken;\r
75 import org.onap.aaf.inno.env.util.Chrono;\r
76 import com.datastax.driver.core.Cluster;\r
77 \r
78 /**\r
79  * Question HL DAO\r
80  * \r
81  * A Data Access Combination Object which asks Security and other Questions\r
82  * \r
83  *\r
84  */\r
85 public class Question {\r
86         // DON'T CHANGE FROM lower Case!!!\r
87         public static enum Type {\r
88                 ns, role, perm, cred\r
89         };\r
90 \r
91         public static final String OWNER="owner";\r
92         public static final String ADMIN="admin";\r
93         public static final String DOT_OWNER=".owner";\r
94         public static final String DOT_ADMIN=".admin";\r
95         static final String ASTERIX = "*";\r
96 \r
97         public static enum Access {\r
98                 read, write, create\r
99         };\r
100 \r
101         public static final String READ = Access.read.name();\r
102         public static final String WRITE = Access.write.name();\r
103         public static final String CREATE = Access.create.name();\r
104 \r
105         public static final String ROLE = Type.role.name();\r
106         public static final String PERM = Type.perm.name();\r
107         public static final String NS = Type.ns.name();\r
108         public static final String CRED = Type.cred.name();\r
109         private static final String DELG = "delg";\r
110         public static final String ATTRIB = "attrib";\r
111 \r
112 \r
113         public static final int MAX_SCOPE = 10;\r
114         public static final int APP_SCOPE = 3;\r
115         public static final int COMPANY_SCOPE = 2;\r
116         static Slot PERMS;\r
117 \r
118         private static Set<String> specialLog = null;\r
119         public static final SecureRandom random = new SecureRandom();\r
120         private static long traceID = random.nextLong();\r
121         private static final String SPECIAL_LOG_SLOT = "SPECIAL_LOG_SLOT";\r
122         private static Slot specialLogSlot = null;\r
123         private static Slot transIDSlot = null;\r
124 \r
125 \r
126         public final HistoryDAO historyDAO;\r
127         public final CachedNSDAO nsDAO;\r
128         public final CachedRoleDAO roleDAO;\r
129         public final CachedPermDAO permDAO;\r
130         public final CachedUserRoleDAO userRoleDAO;\r
131         public final CachedCredDAO credDAO;\r
132         public final CachedCertDAO certDAO;\r
133         public final DelegateDAO delegateDAO;\r
134         public final FutureDAO futureDAO;\r
135         public final ApprovalDAO approvalDAO;\r
136         private final CacheInfoDAO cacheInfoDAO;\r
137 \r
138         // final ContactDAO contDAO;\r
139         // private static final String DOMAIN = "@aaf.att.com";\r
140         // private static final int DOMAIN_LENGTH = 0;\r
141 \r
142         public Question(AuthzTrans trans, Cluster cluster, String keyspace, boolean startClean) throws APIException, IOException {\r
143                 PERMS = trans.slot("USER_PERMS");\r
144                 trans.init().log("Instantiating DAOs");\r
145                 historyDAO = new HistoryDAO(trans, cluster, keyspace);\r
146 \r
147                 // Deal with Cached Entries\r
148                 cacheInfoDAO = new CacheInfoDAO(trans, historyDAO);\r
149 \r
150                 nsDAO = new CachedNSDAO(new NsDAO(trans, historyDAO, cacheInfoDAO),\r
151                                 cacheInfoDAO);\r
152                 permDAO = new CachedPermDAO(\r
153                                 new PermDAO(trans, historyDAO, cacheInfoDAO), cacheInfoDAO);\r
154                 roleDAO = new CachedRoleDAO(\r
155                                 new RoleDAO(trans, historyDAO, cacheInfoDAO), cacheInfoDAO);\r
156                 userRoleDAO = new CachedUserRoleDAO(new UserRoleDAO(trans, historyDAO,\r
157                                 cacheInfoDAO), cacheInfoDAO);\r
158                 credDAO = new CachedCredDAO(\r
159                                 new CredDAO(trans, historyDAO, cacheInfoDAO), cacheInfoDAO);\r
160                 certDAO = new CachedCertDAO(\r
161                                 new CertDAO(trans, historyDAO, cacheInfoDAO), cacheInfoDAO);\r
162 \r
163                 futureDAO = new FutureDAO(trans, historyDAO);\r
164                 delegateDAO = new DelegateDAO(trans, historyDAO);\r
165                 approvalDAO = new ApprovalDAO(trans, historyDAO);\r
166 \r
167                 // Only want to aggressively cleanse User related Caches... The others,\r
168                 // just normal refresh\r
169                 if(startClean) {\r
170                         CachedDAO.startCleansing(trans.env(), credDAO, userRoleDAO);\r
171                         CachedDAO.startRefresh(trans.env(), cacheInfoDAO);\r
172                 }\r
173                 // Set a Timer to Check Caches to send messages for Caching changes\r
174                 \r
175                 if(specialLogSlot==null) {\r
176                         specialLogSlot = trans.slot(SPECIAL_LOG_SLOT);\r
177                         transIDSlot = trans.slot(AuthzTransFilter.TRANS_ID_SLOT);\r
178                 }\r
179                 \r
180                 AbsCassDAO.primePSIs(trans);\r
181         }\r
182 \r
183 \r
184         public void close(AuthzTrans trans) {\r
185                 historyDAO.close(trans);\r
186                 cacheInfoDAO.close(trans);\r
187                 nsDAO.close(trans);\r
188                 permDAO.close(trans);\r
189                 roleDAO.close(trans);\r
190                 userRoleDAO.close(trans);\r
191                 credDAO.close(trans);\r
192                 certDAO.close(trans);\r
193                 delegateDAO.close(trans);\r
194                 futureDAO.close(trans);\r
195                 approvalDAO.close(trans);\r
196         }\r
197 \r
198         public Result<PermDAO.Data> permFrom(AuthzTrans trans, String type,\r
199                         String instance, String action) {\r
200                 Result<NsDAO.Data> rnd = deriveNs(trans, type);\r
201                 if (rnd.isOK()) {\r
202                         return Result.ok(new PermDAO.Data(new NsSplit(rnd.value, type),\r
203                                         instance, action));\r
204                 } else {\r
205                         return Result.err(rnd);\r
206                 }\r
207         }\r
208 \r
209         /**\r
210          * getPermsByUser\r
211          * \r
212          * Because this call is frequently called internally, AND because we already\r
213          * look for it in the initial Call, we cache within the Transaction\r
214          * \r
215          * @param trans\r
216          * @param user\r
217          * @return\r
218          */\r
219         public Result<List<PermDAO.Data>> getPermsByUser(AuthzTrans trans, String user, boolean lookup) {\r
220                 return PermLookup.get(trans, this, user).getPerms(lookup);\r
221         }\r
222         \r
223         public Result<List<PermDAO.Data>> getPermsByUserFromRolesFilter(AuthzTrans trans, String user, String forUser) {\r
224                 PermLookup plUser = PermLookup.get(trans, this, user);\r
225                 Result<Set<String>> plPermNames = plUser.getPermNames();\r
226                 if(plPermNames.notOK()) {\r
227                         return Result.err(plPermNames);\r
228                 }\r
229                 \r
230                 Set<String> nss;\r
231                 if(forUser.equals(user)) {\r
232                         nss = null;\r
233                 } else {\r
234                         // Setup a TreeSet to check on Namespaces to \r
235                         nss = new TreeSet<String>();\r
236                         PermLookup fUser = PermLookup.get(trans, this, forUser);\r
237                         Result<Set<String>> forUpn = fUser.getPermNames();\r
238                         if(forUpn.notOK()) {\r
239                                 return Result.err(forUpn);\r
240                         }\r
241                         \r
242                         for(String pn : forUpn.value) {\r
243                                 Result<String[]> decoded = PermDAO.Data.decodeToArray(trans, this, pn);\r
244                                 if(decoded.isOKhasData()) {\r
245                                         nss.add(decoded.value[0]);\r
246                                 } else {\r
247                                         trans.error().log(pn,", derived from a Role, is invalid:",decoded.errorString());\r
248                                 }\r
249                         }\r
250                 }\r
251 \r
252                 List<PermDAO.Data> rlpUser = new ArrayList<PermDAO.Data>();\r
253                 Result<PermDAO.Data> rpdd;\r
254                 PermDAO.Data pdd;\r
255                 for(String pn : plPermNames.value) {\r
256                         rpdd = PermDAO.Data.decode(trans, this, pn);\r
257                         if(rpdd.isOKhasData()) {\r
258                                 pdd=rpdd.value;\r
259                                 if(nss==null || nss.contains(pdd.ns)) {\r
260                                         rlpUser.add(pdd);\r
261                                 }\r
262                         } else {\r
263                                 trans.error().log(pn,", derived from a Role, is invalid.  Run Data Cleanup:",rpdd.errorString());\r
264                         }\r
265                 }\r
266                 return Result.ok(rlpUser); \r
267         }\r
268 \r
269         public Result<List<PermDAO.Data>> getPermsByType(AuthzTrans trans, String perm) {\r
270                 Result<NsSplit> nss = deriveNsSplit(trans, perm);\r
271                 if (nss.notOK()) {\r
272                         return Result.err(nss);\r
273                 }\r
274                 return permDAO.readByType(trans, nss.value.ns, nss.value.name);\r
275         }\r
276 \r
277         public Result<List<PermDAO.Data>> getPermsByName(AuthzTrans trans,\r
278                         String type, String instance, String action) {\r
279                 Result<NsSplit> nss = deriveNsSplit(trans, type);\r
280                 if (nss.notOK()) {\r
281                         return Result.err(nss);\r
282                 }\r
283                 return permDAO.read(trans, nss.value.ns, nss.value.name, instance,action);\r
284         }\r
285 \r
286         public Result<List<PermDAO.Data>> getPermsByRole(AuthzTrans trans, String role, boolean lookup) {\r
287                 Result<NsSplit> nss = deriveNsSplit(trans, role);\r
288                 if (nss.notOK()) {\r
289                         return Result.err(nss);\r
290                 }\r
291 \r
292                 Result<List<RoleDAO.Data>> rlrd = roleDAO.read(trans, nss.value.ns,\r
293                                 nss.value.name);\r
294                 if (rlrd.notOKorIsEmpty()) {\r
295                         return Result.err(rlrd);\r
296                 }\r
297                 // Using Set to avoid duplicates\r
298                 Set<String> permNames = new HashSet<String>();\r
299                 if (rlrd.isOKhasData()) {\r
300                         for (RoleDAO.Data drr : rlrd.value) {\r
301                                 permNames.addAll(drr.perms(false));\r
302                         }\r
303                 }\r
304 \r
305                 // Note: It should be ok for a Valid user to have no permissions -\r
306                 // 8/12/2013\r
307                 List<PermDAO.Data> perms = new ArrayList<PermDAO.Data>();\r
308                 for (String perm : permNames) {\r
309                         Result<PermDAO.Data> pr = PermDAO.Data.decode(trans, this, perm);\r
310                         if (pr.notOK()) {\r
311                                 return Result.err(pr);\r
312                         }\r
313 \r
314                         if(lookup) {\r
315                                 Result<List<PermDAO.Data>> rlpd = permDAO.read(trans, pr.value);\r
316                                 if (rlpd.isOKhasData()) {\r
317                                         for (PermDAO.Data pData : rlpd.value) {\r
318                                                 perms.add(pData);\r
319                                         }\r
320                                 }\r
321                         } else {\r
322                                 perms.add(pr.value);\r
323                         }\r
324                 }\r
325 \r
326                 return Result.ok(perms);\r
327         }\r
328 \r
329         public Result<List<RoleDAO.Data>> getRolesByName(AuthzTrans trans,\r
330                         String role) {\r
331                 Result<NsSplit> nss = deriveNsSplit(trans, role);\r
332                 if (nss.notOK()) {\r
333                         return Result.err(nss);\r
334                 }\r
335                 String r = nss.value.name;\r
336                 if (r.endsWith(".*")) { // do children Search\r
337                         return roleDAO.readChildren(trans, nss.value.ns,\r
338                                         r.substring(0, r.length() - 2));\r
339                 } else if (ASTERIX.equals(r)) {\r
340                         return roleDAO.readChildren(trans, nss.value.ns, ASTERIX);\r
341                 } else {\r
342                         return roleDAO.read(trans, nss.value.ns, r);\r
343                 }\r
344         }\r
345 \r
346         /**\r
347          * Derive NS\r
348          * \r
349          * Given a Child Namespace, figure out what the best Namespace parent is.\r
350          * \r
351          * For instance, if in the NS table, the parent "com.att" exists, but not\r
352          * "com.att.child" or "com.att.a.b.c", then passing in either\r
353          * "com.att.child" or "com.att.a.b.c" will return "com.att"\r
354          * \r
355          * Uses recursive search on Cached DAO data\r
356          * \r
357          * @param trans\r
358          * @param child\r
359          * @return\r
360          */\r
361         public Result<NsDAO.Data> deriveNs(AuthzTrans trans, String child) {\r
362                 Result<List<NsDAO.Data>> r = nsDAO.read(trans, child);\r
363                 \r
364                 if (r.isOKhasData()) {\r
365                         return Result.ok(r.value.get(0));\r
366                 } else {\r
367                         int dot = child == null ? -1 : child.lastIndexOf('.');\r
368                         if (dot < 0) {\r
369                                 return Result.err(Status.ERR_NsNotFound,\r
370                                                 "No Namespace for [%s]", child);\r
371                         } else {\r
372                                 return deriveNs(trans, child.substring(0, dot));\r
373                         }\r
374                 }\r
375         }\r
376 \r
377         public Result<NsDAO.Data> deriveFirstNsForType(AuthzTrans trans, String str, NsType type) {\r
378                 NsDAO.Data nsd;\r
379 \r
380                 System.out.println("value of str before for loop ---------0---++++++++++++++++++" +str);\r
381                 for(int idx = str.indexOf('.');idx>=0;idx=str.indexOf('.',idx+1)) {\r
382                 //      System.out.println("printing value of str-----------------1------------++++++++++++++++++++++" +str);\r
383                         Result<List<Data>> rld = nsDAO.read(trans, str.substring(0,idx));\r
384                         System.out.println("value of idx is -----------------++++++++++++++++++++++++++" +idx);\r
385                         System.out.println("printing value of str.substring-----------------1------------++++++++++++++++++++++" + (str.substring(0,idx)));\r
386                         System.out.println("value of ResultListData ------------------2------------+++++++++++++++++++++++++++" +rld);\r
387                         if(rld.isOKhasData()) {\r
388                                 System.out.println("In if loop -----------------3-------------- ++++++++++++++++");\r
389                                 System.out.println("value of nsd=rld.value.get(0).type -----------4------++++++++++++++++++++++++++++++++++++" +(nsd=rld.value.get(0)).type);\r
390                                 System.out.println("value of rld.value.get(0).name.toString()+++++++++++++++++++++++++++++++ " +rld.value.get(0).name);\r
391                                 if(type.type == (nsd=rld.value.get(0)).type) {\r
392                                         return Result.ok(nsd);\r
393                                 }\r
394                         } else {\r
395                                 System.out.println("In else loop ----------------4------------+++++++++++++++++++++++");\r
396                                 return Result.err(Status.ERR_NsNotFound,"There is no valid Company Namespace for %s",str.substring(0,idx));\r
397                         }\r
398                 }\r
399                 return Result.err(Status.ERR_NotFound, str + " does not contain type " + type.name());\r
400         }\r
401 \r
402         public Result<NsSplit> deriveNsSplit(AuthzTrans trans, String child) {\r
403                 Result<NsDAO.Data> ndd = deriveNs(trans, child);\r
404                 if (ndd.isOK()) {\r
405                         NsSplit nss = new NsSplit(ndd.value, child);\r
406                         if (nss.isOK()) {\r
407                                 return Result.ok(nss);\r
408                         } else {\r
409                                 return Result.err(Status.ERR_NsNotFound,\r
410                                                 "Cannot split [%s] into valid namespace elements",\r
411                                                 child);\r
412                         }\r
413                 }\r
414                 return Result.err(ndd);\r
415         }\r
416 \r
417         /**\r
418          * Translate an ID into it's domain\r
419          * \r
420          * i.e. myid1234@myapp.att.com results in domain of com.att.myapp\r
421          * \r
422          * @param id\r
423          * @return\r
424          */\r
425         public static String domain2ns(String id) {\r
426                 int at = id.indexOf('@');\r
427                 if (at >= 0) {\r
428                         String[] domain = id.substring(at + 1).split("\\.");\r
429                         StringBuilder ns = new StringBuilder(id.length());\r
430                         boolean first = true;\r
431                         for (int i = domain.length - 1; i >= 0; --i) {\r
432                                 if (first) {\r
433                                         first = false;\r
434                                 } else {\r
435                                         ns.append('.');\r
436                                 }\r
437                                 ns.append(domain[i]);\r
438                         }\r
439                         return ns.toString();\r
440                 } else {\r
441                         return "";\r
442                 }\r
443 \r
444         }\r
445 \r
446         /**\r
447          * Validate Namespace of ID@Domain\r
448          * \r
449          * Namespace is reverse order of Domain.\r
450          * \r
451          * i.e. myid1234@myapp.att.com results in domain of com.att.myapp\r
452          * \r
453          * @param trans\r
454          * @param id\r
455          * @return\r
456          */\r
457         public Result<NsDAO.Data> validNSOfDomain(AuthzTrans trans, String id) {\r
458                 // Take domain, reverse order, and check on NS\r
459                 String ns;\r
460                 if(id.indexOf('@')<0) { // it's already an ns, not an ID\r
461                         ns = id;\r
462                 } else {\r
463                         ns = domain2ns(id);\r
464                 }\r
465                 if (ns.length() > 0) {\r
466                         if(!trans.org().getDomain().equals(ns)) { \r
467                                 Result<List<NsDAO.Data>> rlnsd = nsDAO.read(trans, ns);\r
468                                 if (rlnsd.isOKhasData()) {\r
469                                         return Result.ok(rlnsd.value.get(0));\r
470                                 }\r
471                         }\r
472                 }\r
473                 return Result.err(Status.ERR_NsNotFound,\r
474                                 "A Namespace is not available for %s", id);\r
475         }\r
476 \r
477         public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user,NsDAO.Data ndd, Access access) {\r
478                 // <ns>.access|:role:<role name>|<read|write>\r
479                 String ns = ndd.name;\r
480                 int last;\r
481                 do {\r
482                         if (isGranted(trans, user, ns, "access", ":ns", access.name())) {\r
483                                 return Result.ok(ndd);\r
484                         }\r
485                         if ((last = ns.lastIndexOf('.')) >= 0) {\r
486                                 ns = ns.substring(0, last);\r
487                         }\r
488                 } while (last >= 0);\r
489                 // <root ns>.ns|:<client ns>:ns|<access>\r
490                 // AAF-724 - Make consistent response for May User", and not take the\r
491                 // last check... too confusing.\r
492                 Result<NsDAO.Data> rv = mayUserVirtueOfNS(trans, user, ndd, ":" + ndd.name + ":ns", access.name());\r
493                 if (rv.isOK()) {\r
494                         return rv;\r
495                 } else if(rv.status==Result.ERR_Backend) {\r
496                         return Result.err(rv);\r
497                 } else {\r
498                         return Result.err(Status.ERR_Denied, "[%s] may not %s in NS [%s]",\r
499                                         user, access.name(), ndd.name);\r
500                 }\r
501         }\r
502 \r
503         public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user, RoleDAO.Data rdd, Access access) {\r
504                 Result<NsDAO.Data> rnsd = deriveNs(trans, rdd.ns);\r
505                 if (rnsd.isOK()) {\r
506                         return mayUser(trans, user, rnsd.value, rdd, access);\r
507                 }\r
508                 return rnsd;\r
509         }\r
510 \r
511         public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user, NsDAO.Data ndd, RoleDAO.Data rdd, Access access) {\r
512                 // 1) Is User in the Role?\r
513                 Result<List<UserRoleDAO.Data>> rurd = userRoleDAO.readUserInRole(trans, user, rdd.fullName());\r
514                 if (rurd.isOKhasData()) {\r
515                         return Result.ok(ndd);\r
516                 }\r
517 \r
518                 String roleInst = ":role:" + rdd.name;\r
519                 // <ns>.access|:role:<role name>|<read|write>\r
520                 String ns = rdd.ns;\r
521                 int last;\r
522                 do {\r
523                         if (isGranted(trans, user, ns,"access", roleInst, access.name())) {\r
524                                 return Result.ok(ndd);\r
525                         }\r
526                         if ((last = ns.lastIndexOf('.')) >= 0) {\r
527                                 ns = ns.substring(0, last);\r
528                         }\r
529                 } while (last >= 0);\r
530 \r
531                 // Check if Access by Global Role perm\r
532                 // <root ns>.ns|:<client ns>:role:name|<access>\r
533                 Result<NsDAO.Data> rnsd = mayUserVirtueOfNS(trans, user, ndd, ":"\r
534                                 + rdd.ns + roleInst, access.name());\r
535                 if (rnsd.isOK()) {\r
536                         return rnsd;\r
537                 } else if(rnsd.status==Result.ERR_Backend) {\r
538                         return Result.err(rnsd);\r
539                 }\r
540 \r
541                 // Check if Access to Whole NS\r
542                 // AAF-724 - Make consistent response for May User", and not take the\r
543                 // last check... too confusing.\r
544                 Result<org.onap.aaf.dao.aaf.cass.NsDAO.Data> rv = mayUserVirtueOfNS(trans, user, ndd, \r
545                                 ":" + rdd.ns + ":ns", access.name());\r
546                 if (rv.isOK()) {\r
547                         return rv;\r
548                 } else if(rnsd.status==Result.ERR_Backend) {\r
549                         return Result.err(rnsd);\r
550                 } else {\r
551                         return Result.err(Status.ERR_Denied, "[%s] may not %s Role [%s]",\r
552                                         user, access.name(), rdd.fullName());\r
553                 }\r
554 \r
555         }\r
556 \r
557         public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user,PermDAO.Data pdd, Access access) {\r
558                 Result<NsDAO.Data> rnsd = deriveNs(trans, pdd.ns);\r
559                 if (rnsd.isOK()) {\r
560                         return mayUser(trans, user, rnsd.value, pdd, access);\r
561                 }\r
562                 return rnsd;\r
563         }\r
564 \r
565         public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user,NsDAO.Data ndd, PermDAO.Data pdd, Access access) {\r
566                 if (isGranted(trans, user, pdd.ns, pdd.type, pdd.instance, pdd.action)) {\r
567                         return Result.ok(ndd);\r
568                 }\r
569                 String permInst = ":perm:" + pdd.type + ':' + pdd.instance + ':' + pdd.action;\r
570                 // <ns>.access|:role:<role name>|<read|write>\r
571                 String ns = ndd.name;\r
572                 int last;\r
573                 do {\r
574                         if (isGranted(trans, user, ns, "access", permInst, access.name())) {\r
575                                 return Result.ok(ndd);\r
576                         }\r
577                         if ((last = ns.lastIndexOf('.')) >= 0) {\r
578                                 ns = ns.substring(0, last);\r
579                         }\r
580                 } while (last >= 0);\r
581 \r
582                 // Check if Access by NS perm\r
583                 // <root ns>.ns|:<client ns>:role:name|<access>\r
584                 Result<NsDAO.Data> rnsd = mayUserVirtueOfNS(trans, user, ndd, ":" + pdd.ns + permInst, access.name());\r
585                 if (rnsd.isOK()) {\r
586                         return rnsd;\r
587                 } else if(rnsd.status==Result.ERR_Backend) {\r
588                         return Result.err(rnsd);\r
589                 }\r
590 \r
591                 // Check if Access to Whole NS\r
592                 // AAF-724 - Make consistent response for May User", and not take the\r
593                 // last check... too confusing.\r
594                 Result<NsDAO.Data> rv = mayUserVirtueOfNS(trans, user, ndd, ":" + pdd.ns + ":ns", access.name());\r
595                 if (rv.isOK()) {\r
596                         return rv;\r
597                 } else {\r
598                         return Result.err(Status.ERR_Denied,\r
599                                         "[%s] may not %s Perm [%s|%s|%s]", user, access.name(),\r
600                                         pdd.fullType(), pdd.instance, pdd.action);\r
601                 }\r
602 \r
603         }\r
604 \r
605         public Result<Void> mayUser(AuthzTrans trans, DelegateDAO.Data dd, Access access) {\r
606                 try {\r
607                         boolean isUser = trans.user().equals(dd.user);\r
608                         boolean isDelegate = dd.delegate != null\r
609                                         && (dd.user.equals(dd.delegate) || trans.user().equals(\r
610                                                         dd.delegate));\r
611                         Organization org = trans.org();\r
612                         switch (access) {\r
613                         case create:\r
614                                 if (org.getIdentity(trans, dd.user) == null) {\r
615                                         return Result.err(Status.ERR_UserNotFound,\r
616                                                         "[%s] is not a user in the company database.",\r
617                                                         dd.user);\r
618                                 }\r
619                                 if (!dd.user.equals(dd.delegate) && org.getIdentity(trans, dd.delegate) == null) {\r
620                                         return Result.err(Status.ERR_UserNotFound,\r
621                                                         "[%s] is not a user in the company database.",\r
622                                                         dd.delegate);\r
623                                 }\r
624                                 if (!trans.forceRequested() && dd.user != null && dd.user.equals(dd.delegate)) {\r
625                                         return Result.err(Status.ERR_BadData,\r
626                                                         "[%s] cannot be a delegate for self", dd.user);\r
627                                 }\r
628                                 if (!isUser     && !isGranted(trans, trans.user(), Define.ROOT_NS,DELG,\r
629                                                                 org.getDomain(), Question.CREATE)) {\r
630                                         return Result.err(Status.ERR_Denied,\r
631                                                         "[%s] may not create a delegate for [%s]",\r
632                                                         trans.user(), dd.user);\r
633                                 }\r
634                                 break;\r
635                         case read:\r
636                         case write:\r
637                                 if (!isUser     && !isDelegate && \r
638                                                 !isGranted(trans, trans.user(), Define.ROOT_NS,DELG,org.getDomain(), access.name())) {\r
639                                         return Result.err(Status.ERR_Denied,\r
640                                                         "[%s] may not %s delegates for [%s]", trans.user(),\r
641                                                         access.name(), dd.user);\r
642                                 }\r
643                                 break;\r
644                         default:\r
645                                 return Result.err(Status.ERR_BadData,"Unknown Access type [%s]", access.name());\r
646                         }\r
647                 } catch (Exception e) {\r
648                         return Result.err(e);\r
649                 }\r
650                 return Result.ok();\r
651         }\r
652 \r
653         /*\r
654          * Check (recursively, if necessary), if able to do something based on NS\r
655          */\r
656         private Result<NsDAO.Data> mayUserVirtueOfNS(AuthzTrans trans, String user,     NsDAO.Data nsd, String ns_and_type, String access) {\r
657                 String ns = nsd.name;\r
658 \r
659                 // If an ADMIN of the Namespace, then allow\r
660                 \r
661                 Result<List<UserRoleDAO.Data>> rurd;\r
662                 if ((rurd = userRoleDAO.readUserInRole(trans, user, nsd.name+ADMIN)).isOKhasData()) {\r
663                         return Result.ok(nsd);\r
664                 } else if(rurd.status==Result.ERR_Backend) {\r
665                         return Result.err(rurd);\r
666                 }\r
667                 \r
668                 // If Specially granted Global Permission\r
669                 if (isGranted(trans, user, Define.ROOT_NS,NS, ns_and_type, access)) {\r
670                         return Result.ok(nsd);\r
671                 }\r
672 \r
673                 // Check recur\r
674 \r
675                 int dot = ns.length();\r
676                 if ((dot = ns.lastIndexOf('.', dot - 1)) >= 0) {\r
677                         Result<NsDAO.Data> rnsd = deriveNs(trans, ns.substring(0, dot));\r
678                         if (rnsd.isOK()) {\r
679                                 rnsd = mayUserVirtueOfNS(trans, user, rnsd.value, ns_and_type,access);\r
680                         } else if(rnsd.status==Result.ERR_Backend) {\r
681                                 return Result.err(rnsd);\r
682                         }\r
683                         if (rnsd.isOK()) {\r
684                                 return Result.ok(nsd);\r
685                         } else if(rnsd.status==Result.ERR_Backend) {\r
686                                 return Result.err(rnsd);\r
687                         }\r
688                 }\r
689                 return Result.err(Status.ERR_Denied, "%s may not %s %s", user, access,\r
690                                 ns_and_type);\r
691         }\r
692 \r
693         \r
694         /**\r
695          * isGranted\r
696          * \r
697          * Important function - Check internal Permission Schemes for Permission to\r
698          * do things\r
699          * \r
700          * @param trans\r
701          * @param type\r
702          * @param instance\r
703          * @param action\r
704          * @return\r
705          */\r
706         public boolean isGranted(AuthzTrans trans, String user, String ns, String type,String instance, String action) {\r
707                 Result<List<PermDAO.Data>> perms = getPermsByUser(trans, user, false);\r
708                 if (perms.isOK()) {\r
709                         for (PermDAO.Data pd : perms.value) {\r
710                                 if (ns.equals(pd.ns)) {\r
711                                         if (type.equals(pd.type)) {\r
712                                                 if (PermEval.evalInstance(pd.instance, instance)) {\r
713                                                         if(PermEval.evalAction(pd.action, action)) { // don't return action here, might miss other action \r
714                                                                 return true;\r
715                                                         }\r
716                                                 }\r
717                                         }\r
718                                 }\r
719                         }\r
720                 }\r
721                 return false;\r
722         }\r
723 \r
724         public Result<Date> doesUserCredMatch(AuthzTrans trans, String user, byte[] cred) throws DAOException {\r
725                 Result<List<CredDAO.Data>> result;\r
726                 TimeTaken tt = trans.start("Read DB Cred", Env.REMOTE);\r
727                 try {\r
728                         result = credDAO.readID(trans, user);\r
729                 } finally {\r
730                         tt.done();\r
731                 }\r
732 \r
733                 Result<Date> rv = null;\r
734                 if(result.isOK()) {\r
735                         if (result.isEmpty()) {\r
736                                 rv = Result.err(Status.ERR_UserNotFound, user);\r
737                                 if (willSpecialLog(trans,user)) {\r
738                                         trans.audit().log("Special DEBUG:", user, " does not exist in DB");\r
739                                 }\r
740                         } else {\r
741                                 Date now = new Date();//long now = System.currentTimeMillis();\r
742                                 ByteBuffer md5=null;\r
743         \r
744                                 // Bug noticed 6/22. Sorting on the result can cause Concurrency Issues.         \r
745                                 List<CredDAO.Data> cddl;\r
746                                 if(result.value.size() > 1) {\r
747                                         cddl = new ArrayList<CredDAO.Data>(result.value.size());\r
748                                         for(CredDAO.Data old : result.value) {\r
749                                                 if(old.type==CredDAO.BASIC_AUTH || old.type==CredDAO.BASIC_AUTH_SHA256) {\r
750                                                         cddl.add(old);\r
751                                                 }\r
752                                         }\r
753                                         if(cddl.size()>1) {\r
754                                                 Collections.sort(cddl,new Comparator<CredDAO.Data>() {\r
755                                                         @Override\r
756                                                         public int compare(org.onap.aaf.dao.aaf.cass.CredDAO.Data a,\r
757                                                                                            org.onap.aaf.dao.aaf.cass.CredDAO.Data b) {\r
758                                                                 return b.expires.compareTo(a.expires);\r
759                                                         }\r
760                                                 });\r
761                                         }\r
762                                 } else {\r
763                                         cddl = result.value;\r
764                                 }\r
765         \r
766                                 for (CredDAO.Data cdd : cddl) {\r
767                                         if (cdd.expires.after(now)) {\r
768                                                 try {\r
769                                                         switch(cdd.type) {\r
770                                                                 case CredDAO.BASIC_AUTH:\r
771                                                                         if(md5==null) {\r
772                                                                                 md5=ByteBuffer.wrap(Hash.encryptMD5(cred));\r
773                                                                         }\r
774                                                                         if(md5.compareTo(cdd.cred)==0) {\r
775                                                                                 return Result.ok(cdd.expires);\r
776                                                                         } else if (willSpecialLog(trans,user)) {\r
777                                                                                 trans.audit().log("Special DEBUG:", user, "Client sent: ", trans.encryptor().encrypt(new String(cred)) ,cdd.expires);\r
778                                                                         }\r
779                                                                         break;\r
780                                                                 case CredDAO.BASIC_AUTH_SHA256:\r
781                                                                         ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE + cred.length);\r
782                                                                         bb.putInt(cdd.other);\r
783                                                                         bb.put(cred);\r
784                                                                         byte[] hash = Hash.hashSHA256(bb.array());\r
785         \r
786                                                                         ByteBuffer sha256 = ByteBuffer.wrap(hash);\r
787                                                                         if(sha256.compareTo(cdd.cred)==0) {\r
788                                                                                 return Result.ok(cdd.expires);\r
789                                                                         } else if (willSpecialLog(trans,user)) {\r
790                                                                                 trans.audit().log("Special DEBUG:", user, "Client sent: ", trans.encryptor().encrypt(new String(cred)) ,cdd.expires);\r
791                                                                         }\r
792                                                                         break;\r
793                                                                 default:\r
794                                                                         trans.error().log("Unknown Credential Type %s for %s, %s",Integer.toString(cdd.type),cdd.id, Chrono.dateTime(cdd.expires));\r
795                                                         }\r
796                                                 } catch (NoSuchAlgorithmException e) {\r
797                                                         trans.error().log(e);\r
798                                                 }\r
799                                         } else {\r
800                                                 rv = Result.err(Status.ERR_Security,\r
801                                                                 "Credentials expired " + cdd.expires.toString());\r
802                                         }\r
803                                 } // end for each\r
804                         }\r
805                 } else {\r
806                         return Result.err(result);\r
807                 }\r
808                 return rv == null ? Result.create((Date) null, Status.ERR_Security,\r
809                                 "Wrong credential") : rv;\r
810         }\r
811 \r
812 \r
813         public Result<CredDAO.Data> userCredSetup(AuthzTrans trans, CredDAO.Data cred) {\r
814                 if(cred.type==CredDAO.RAW) {\r
815                         TimeTaken tt = trans.start("Hash Cred", Env.SUB);\r
816                         try {\r
817                                 cred.type = CredDAO.BASIC_AUTH_SHA256;\r
818                                 cred.other = random.nextInt();\r
819                                 ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE + cred.cred.capacity());\r
820                                 bb.putInt(cred.other);\r
821                                 bb.put(cred.cred);\r
822                                 byte[] hash = Hash.hashSHA256(bb.array());\r
823                                 cred.cred = ByteBuffer.wrap(hash);\r
824                                 return Result.ok(cred);\r
825                         } catch (NoSuchAlgorithmException e) {\r
826                                 return Result.err(Status.ERR_General,e.getLocalizedMessage());\r
827                         } finally {\r
828                                 tt.done();\r
829                         }\r
830                         \r
831                 }\r
832                 return Result.err(Status.ERR_Security,"invalid/unreadable credential");\r
833         }\r
834 \r
835 \r
836         public static final String APPROVED = "APPROVE";\r
837         public static final String REJECT = "REJECT";\r
838         public static final String PENDING = "PENDING";\r
839 \r
840         public Result<Void> canAddUser(AuthzTrans trans, UserRoleDAO.Data data,\r
841                         List<ApprovalDAO.Data> approvals) {\r
842                 // get the approval policy for the organization\r
843 \r
844                 // get the list of approvals with an accept status\r
845 \r
846                 // validate the approvals against the policy\r
847 \r
848                 // for now check if all approvals are received and return\r
849                 // SUCCESS/FAILURE/SKIP\r
850                 boolean bReject = false;\r
851                 boolean bPending = false;\r
852 \r
853                 for (ApprovalDAO.Data approval : approvals) {\r
854                         if (approval.status.equals(REJECT)) {\r
855                                 bReject = true;\r
856                         } else if (approval.status.equals(PENDING)) {\r
857                                 bPending = true;\r
858                         }\r
859                 }\r
860                 if (bReject) {\r
861                         return Result.err(Status.ERR_Policy,\r
862                                         "Approval Polocy not conformed");\r
863                 }\r
864                 if (bPending) {\r
865                         return Result.err(Status.ERR_ActionNotCompleted,\r
866                                         "Required Approvals not received");\r
867                 }\r
868 \r
869                 return Result.ok();\r
870         }\r
871 \r
872         private static final String NO_CACHE_NAME = "No Cache Data named %s";\r
873 \r
874         public Result<Void> clearCache(AuthzTrans trans, String cname) {\r
875                 boolean all = "all".equals(cname);\r
876                 Result<Void> rv = null;\r
877 \r
878                 if (all || NsDAO.TABLE.equals(cname)) {\r
879                         int seg[] = series(NsDAO.CACHE_SEG);\r
880                         for(int i: seg) {cacheClear(trans, NsDAO.TABLE,i);}\r
881                         rv = cacheInfoDAO.touch(trans, NsDAO.TABLE, seg);\r
882                 }\r
883                 if (all || PermDAO.TABLE.equals(cname)) {\r
884                         int seg[] = series(NsDAO.CACHE_SEG);\r
885                         for(int i: seg) {cacheClear(trans, PermDAO.TABLE,i);}\r
886                         rv = cacheInfoDAO.touch(trans, PermDAO.TABLE,seg);\r
887                 }\r
888                 if (all || RoleDAO.TABLE.equals(cname)) {\r
889                         int seg[] = series(NsDAO.CACHE_SEG);\r
890                         for(int i: seg) {cacheClear(trans, RoleDAO.TABLE,i);}\r
891                         rv = cacheInfoDAO.touch(trans, RoleDAO.TABLE,seg);\r
892                 }\r
893                 if (all || UserRoleDAO.TABLE.equals(cname)) {\r
894                         int seg[] = series(NsDAO.CACHE_SEG);\r
895                         for(int i: seg) {cacheClear(trans, UserRoleDAO.TABLE,i);}\r
896                         rv = cacheInfoDAO.touch(trans, UserRoleDAO.TABLE,seg);\r
897                 }\r
898                 if (all || CredDAO.TABLE.equals(cname)) {\r
899                         int seg[] = series(NsDAO.CACHE_SEG);\r
900                         for(int i: seg) {cacheClear(trans, CredDAO.TABLE,i);}\r
901                         rv = cacheInfoDAO.touch(trans, CredDAO.TABLE,seg);\r
902                 }\r
903                 if (all || CertDAO.TABLE.equals(cname)) {\r
904                         int seg[] = series(NsDAO.CACHE_SEG);\r
905                         for(int i: seg) {cacheClear(trans, CertDAO.TABLE,i);}\r
906                         rv = cacheInfoDAO.touch(trans, CertDAO.TABLE,seg);\r
907                 }\r
908 \r
909                 if (rv == null) {\r
910                         rv = Result.err(Status.ERR_BadData, NO_CACHE_NAME, cname);\r
911                 }\r
912                 return rv;\r
913         }\r
914 \r
915         public Result<Void> cacheClear(AuthzTrans trans, String cname,Integer segment) {\r
916                 Result<Void> rv;\r
917                 if (NsDAO.TABLE.equals(cname)) {\r
918                         rv = nsDAO.invalidate(segment);\r
919                 } else if (PermDAO.TABLE.equals(cname)) {\r
920                         rv = permDAO.invalidate(segment);\r
921                 } else if (RoleDAO.TABLE.equals(cname)) {\r
922                         rv = roleDAO.invalidate(segment);\r
923                 } else if (UserRoleDAO.TABLE.equals(cname)) {\r
924                         rv = userRoleDAO.invalidate(segment);\r
925                 } else if (CredDAO.TABLE.equals(cname)) {\r
926                         rv = credDAO.invalidate(segment);\r
927                 } else if (CertDAO.TABLE.equals(cname)) {\r
928                         rv = certDAO.invalidate(segment);\r
929                 } else {\r
930                         rv = Result.err(Status.ERR_BadData, NO_CACHE_NAME, cname);\r
931                 }\r
932                 return rv;\r
933         }\r
934 \r
935         private int[] series(int max) {\r
936                 int[] series = new int[max];\r
937                 for (int i = 0; i < max; ++i)\r
938                         series[i] = i;\r
939                 return series;\r
940         }\r
941 \r
942         public boolean isDelegated(AuthzTrans trans, String user, String approver) {\r
943                 Result<List<DelegateDAO.Data>> userDelegatedFor = delegateDAO\r
944                                 .readByDelegate(trans, user);\r
945                 for (DelegateDAO.Data curr : userDelegatedFor.value) {\r
946                         if (curr.user.equals(approver) && curr.delegate.equals(user)\r
947                                         && curr.expires.after(new Date())) {\r
948                                 return true;\r
949                         }\r
950                 }\r
951                 return false;\r
952         }\r
953 \r
954         public static boolean willSpecialLog(AuthzTrans trans, String user) {\r
955                 Boolean b = trans.get(specialLogSlot, null);\r
956                 if(b==null) {\r
957                         if(specialLog==null) {\r
958                                 return false;\r
959                         } else {\r
960                                 b = specialLog.contains(user);\r
961                                 trans.put(specialLogSlot, b);\r
962                         }\r
963                 }\r
964                 return b;\r
965         }\r
966         \r
967         public static void logEncryptTrace(AuthzTrans trans, String data) {\r
968                 long ti;\r
969                 trans.put(transIDSlot, ti=nextTraceID());\r
970                 trans.trace().log("id="+Long.toHexString(ti)+",data=\""+trans.env().encryptor().encrypt(data)+'"');\r
971         }\r
972 \r
973         private synchronized static long nextTraceID() {\r
974                 return ++traceID;\r
975         }\r
976 \r
977         public static synchronized boolean specialLogOn(AuthzTrans trans, String id) {\r
978                 if (specialLog == null) {\r
979                         specialLog = new HashSet<String>();\r
980                 }\r
981                 boolean rc = specialLog.add(id);\r
982                 if(rc) {\r
983                         trans.trace().log("Trace on for",id);                   \r
984                 }\r
985                 return rc;\r
986         }\r
987 \r
988         public static synchronized boolean specialLogOff(AuthzTrans trans, String id) {\r
989                 if(specialLog==null) {\r
990                         return false;\r
991                 }\r
992                 boolean rv = specialLog.remove(id);\r
993                 if (specialLog.isEmpty()) {\r
994                         specialLog = null;\r
995                 }\r
996                 if(rv) {\r
997                         trans.trace().log("Trace off for",id);\r
998                 }\r
999                 return rv;\r
1000         }\r
1001 \r
1002         /** \r
1003          * canMove\r
1004          * Which Types can be moved\r
1005          * @param nsType\r
1006          * @return\r
1007          */\r
1008         public boolean canMove(NsType nsType) {\r
1009                 boolean rv;\r
1010                 switch(nsType) {\r
1011                         case DOT:\r
1012                         case ROOT:\r
1013                         case COMPANY:\r
1014                         case UNKNOWN:\r
1015                                 rv = false;\r
1016                                 break;\r
1017                         default:\r
1018                                 rv = true;\r
1019                 }\r
1020                 return rv;\r
1021         }\r
1022 \r
1023         public Result<String> isOwnerSponsor(AuthzTrans trans, String user, String ns, Identity mechID) {\r
1024                 \r
1025                 Identity caller;\r
1026                 Organization org = trans.org();\r
1027                 try {\r
1028                         caller = org.getIdentity(trans, user);\r
1029                         if(caller==null || !caller.isFound()) {\r
1030                                 return Result.err(Status.ERR_NotFound,"%s is not a registered %s entity",user,org.getName());\r
1031                         }\r
1032                 } catch (Exception e) {\r
1033                         return Result.err(e);\r
1034                 }\r
1035                 String sponsor = mechID.responsibleTo();\r
1036                 Result<List<UserRoleDAO.Data>> rur = userRoleDAO.read(trans, user,ns+DOT_OWNER);\r
1037                 boolean isOwner = false;\r
1038                 if(rur.isOKhasData()) {for(UserRoleDAO.Data urdd : rur.value){\r
1039                         if(urdd.expires.after(new Date())) {\r
1040                                 isOwner = true;\r
1041                         }\r
1042                 }};\r
1043                 if(!isOwner) {\r
1044                         return Result.err(Status.ERR_Policy,"%s is not a current owner of %s",user,ns);\r
1045                 }\r
1046                 \r
1047                 if(!caller.id().equals(sponsor)) {\r
1048                         return Result.err(Status.ERR_Denied,"%s is not the sponsor of %s",user,mechID.id());\r
1049                 }\r
1050                 return Result.ok(sponsor);\r
1051         }\r
1052         \r
1053         public boolean isAdmin(AuthzTrans trans, String user, String ns) {\r
1054                 Date now = new Date();\r
1055                 Result<List<UserRoleDAO.Data>> rur = userRoleDAO.read(trans, user,ns+ADMIN);\r
1056                 if(rur.isOKhasData()) {for(UserRoleDAO.Data urdd : rur.value){\r
1057                         if(urdd.expires.after(now)) {\r
1058                                 return true;\r
1059                         }\r
1060                 }};\r
1061                 return false;\r
1062         }\r
1063         \r
1064         public boolean isOwner(AuthzTrans trans, String user, String ns) {\r
1065                 Result<List<UserRoleDAO.Data>> rur = userRoleDAO.read(trans, user,ns+DOT_OWNER);\r
1066                 Date now = new Date();\r
1067                 if(rur.isOKhasData()) {for(UserRoleDAO.Data urdd : rur.value){\r
1068                         if(urdd.expires.after(now)) {\r
1069                                 return true;\r
1070                         }\r
1071                 }};\r
1072                 return false;\r
1073         }\r
1074 \r
1075         public int countOwner(AuthzTrans trans, String user, String ns) {\r
1076                 Result<List<UserRoleDAO.Data>> rur = userRoleDAO.read(trans, user,ns+DOT_OWNER);\r
1077                 Date now = new Date();\r
1078                 int count = 0;\r
1079                 if(rur.isOKhasData()) {for(UserRoleDAO.Data urdd : rur.value){\r
1080                         if(urdd.expires.after(now)) {\r
1081                                 ++count;\r
1082                         }\r
1083                 }};\r
1084                 return count;\r
1085         }\r
1086 \r
1087 }\r