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