Coverage Summary for Class: NonRecursiveGrantGlobalResourcePermissionPersister (com.acciente.oacc.sql.internal.persister)
Class | Class, % | Method, % | Line, % |
---|---|---|---|
NonRecursiveGrantGlobalResourcePermissionPersister | 100% (1/ 1) | 100% (6/ 6) | 88.7% (141/ 159) |
1 /*
2 * Copyright 2009-2018, Acciente LLC
3 *
4 * Acciente LLC licenses this file to you under the
5 * Apache License, Version 2.0 (the "License"); you
6 * may not use this file except in compliance with the
7 * License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in
12 * writing, software distributed under the License is
13 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
14 * OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing
16 * permissions and limitations under the License.
17 */
18 package com.acciente.oacc.sql.internal.persister;
19
20 import com.acciente.oacc.Resource;
21 import com.acciente.oacc.ResourcePermission;
22 import com.acciente.oacc.sql.SQLProfile;
23 import com.acciente.oacc.sql.internal.persister.id.DomainId;
24 import com.acciente.oacc.sql.internal.persister.id.Id;
25 import com.acciente.oacc.sql.internal.persister.id.ResourceClassId;
26 import com.acciente.oacc.sql.internal.persister.id.ResourceId;
27 import com.acciente.oacc.sql.internal.persister.id.ResourcePermissionId;
28
29 import java.io.Serializable;
30 import java.sql.SQLException;
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38
39 public class NonRecursiveGrantGlobalResourcePermissionPersister extends CommonGrantGlobalResourcePermissionPersister implements Serializable {
40 private static final long serialVersionUID = 1L;
41
42 public NonRecursiveGrantGlobalResourcePermissionPersister(SQLProfile sqlProfile,
43 SQLStrings sqlStrings) {
44 super(sqlProfile, sqlStrings);
45 }
46
47 @Override
48 public Set<Resource> getResourcesByGlobalResourcePermission(SQLConnection connection,
49 Resource accessorResource,
50 Id<ResourceClassId> resourceClassId,
51 ResourcePermission resourcePermission,
52 Id<ResourcePermissionId> resourcePermissionId) {
53 if (resourcePermission.isSystemPermission()) {
54 throw new IllegalArgumentException("Permission: " + resourcePermission + " is not a non-system permission");
55 }
56
57 SQLStatement statement = null;
58 try {
59 // first get all the resources from which the accessor inherits any permissions
60 final Set<Id<ResourceId>> accessorResourceIds
61 = NonRecursivePersisterHelper.getInheritedAccessorResourceIds(sqlStrings, connection, accessorResource);
62
63 // second, get all the domains the accessors directly have the specified global permission to
64 SQLResult resultSet;
65 Set<Id<DomainId>> directGlobalDomains = new HashSet<>();
66 statement = connection.prepareStatement(sqlStrings.SQL_findInGrantGlobalResourcePermission_withoutInheritance_ResourceDomainID_BY_AccessorID_ResourceClassID_PermissionID_IsWithGrant);
67
68 for (Id<ResourceId> accessorResourceId : accessorResourceIds) {
69 statement.setResourceId(1, accessorResourceId);
70 statement.setResourceClassId(2, resourceClassId);
71 statement.setResourcePermissionId(3, resourcePermissionId);
72 statement.setBoolean(4, resourcePermission.isWithGrantOption());
73 resultSet = statement.executeQuery();
74
75 while (resultSet.next()) {
76 directGlobalDomains.add(resultSet.getResourceDomainId("DomainId"));
77 }
78 resultSet.close();
79 }
80 closeStatement(statement);
81
82 // then get all resources of the specified class for each of the direct domain's descendants
83 Set<Resource> resources = new HashSet<>();
84 statement = connection.prepareStatement(sqlStrings.SQL_findInResource_withoutInheritance_ResourceId_ExternalId_BY_ResourceClassID_DomainID);
85
86 for (Id<DomainId> directDomainId: directGlobalDomains) {
87 Set<Id<DomainId>> descendentDomainIds
88 = NonRecursivePersisterHelper.getDescendantDomainIdsOrderedByAscendingLevel(sqlStrings,
89 connection,
90 directDomainId);
91 for (Id<DomainId> descendentDomainId : descendentDomainIds) {
92 statement.setResourceClassId(1, resourceClassId);
93 statement.setResourceDomainId(2, descendentDomainId);
94 resultSet = statement.executeQuery();
95
96 while (resultSet.next()) {
97 resources.add(resultSet.getResource("ResourceId", "ExternalId"));
98 }
99 resultSet.close();
100 }
101 }
102
103 return resources;
104 }
105 catch (SQLException e) {
106 throw new RuntimeException(e);
107 }
108 finally {
109 closeStatement(statement);
110 }
111 }
112
113 @Override
114 public Set<Resource> getResourcesByGlobalResourcePermission(SQLConnection connection,
115 Resource accessorResource,
116 Id<ResourceClassId> resourceClassId,
117 Id<DomainId> resourceDomainId,
118 ResourcePermission resourcePermission,
119 Id<ResourcePermissionId> resourcePermissionId) {
120 if (resourcePermission.isSystemPermission()) {
121 throw new IllegalArgumentException("Permission: " + resourcePermission + " is not a non-system permission");
122 }
123
124 SQLStatement statement = null;
125 try {
126 // first get all the resources from which the accessor inherits any permissions
127 final Set<Id<ResourceId>> accessorResourceIds
128 = NonRecursivePersisterHelper.getInheritedAccessorResourceIds(sqlStrings, connection, accessorResource);
129
130 // second, get all the domains the accessors directly have the specified global permission to
131 SQLResult resultSet;
132 Set<Id<DomainId>> directGlobalDomains = new HashSet<>();
133 statement = connection.prepareStatement(sqlStrings.SQL_findInGrantGlobalResourcePermission_withoutInheritance_ResourceDomainID_BY_AccessorID_ResourceClassID_PermissionID_IsWithGrant);
134
135 for (Id<ResourceId> accessorResourceId : accessorResourceIds) {
136 statement.setResourceId(1, accessorResourceId);
137 statement.setResourceClassId(2, resourceClassId);
138 statement.setResourcePermissionId(3, resourcePermissionId);
139 statement.setBoolean(4, resourcePermission.isWithGrantOption());
140 resultSet = statement.executeQuery();
141
142 while (resultSet.next()) {
143 directGlobalDomains.add(resultSet.getResourceDomainId("DomainId"));
144 }
145 resultSet.close();
146 }
147 closeStatement(statement);
148
149 Set<Id<DomainId>> requestedAncestorDomainIds
150 = NonRecursivePersisterHelper.getAncestorDomainIds(sqlStrings, connection, resourceDomainId);
151 Set<Id<DomainId>> requestedDescendentDomainIds
152 = NonRecursivePersisterHelper.getDescendantDomainIdsOrderedByAscendingLevel(sqlStrings,
153 connection,
154 resourceDomainId);
155 Set<Id<DomainId>> effectiveDomainIds = Collections.emptySet();
156
157 // let's see if we have global permissions on an ancestor of the requested domain, first
158 for (Id<DomainId> directDomainId: directGlobalDomains) {
159 if (requestedAncestorDomainIds.contains(directDomainId)) {
160 // because we have global permissions on an ancestor of the requested domain,
161 // we have access to all resources of any sub-domain of the requested domain
162 effectiveDomainIds = requestedDescendentDomainIds;
163 break;
164 }
165 }
166
167 if (effectiveDomainIds.isEmpty()){
168 // we did not have global permission on an ancestor of the requested domain, so let's
169 // find the highest level sub-domain of the requested domain to which we have global permission
170 for (Id<DomainId> requestedDescendentDomainId : requestedDescendentDomainIds) {
171 if (directGlobalDomains.contains(requestedDescendentDomainId)) {
172 effectiveDomainIds
173 = NonRecursivePersisterHelper.getDescendantDomainIdsOrderedByAscendingLevel(sqlStrings,
174 connection,
175 requestedDescendentDomainId);
176 break;
177 }
178 }
179 }
180
181 // now let's collect all the resources for those sub-domains to which we effectively have global permissions
182 Set<Resource> resources = new HashSet<>();
183 statement = connection.prepareStatement(sqlStrings.SQL_findInResource_withoutInheritance_ResourceId_ExternalId_BY_ResourceClassID_DomainID);
184 for (Id<DomainId> effectiveDomainId : effectiveDomainIds) {
185 statement.setResourceClassId(1, resourceClassId);
186 statement.setResourceDomainId(2, effectiveDomainId);
187 resultSet = statement.executeQuery();
188
189 while (resultSet.next()) {
190 resources.add(resultSet.getResource("ResourceId", "ExternalId"));
191 }
192 resultSet.close();
193 }
194
195 return resources;
196 }
197 catch (SQLException e) {
198 throw new RuntimeException(e);
199 }
200 finally {
201 closeStatement(statement);
202 }
203 }
204
205 @Override
206 public Set<ResourcePermission> getGlobalResourcePermissionsIncludeInherited(SQLConnection connection,
207 Resource accessorResource,
208 Id<ResourceClassId> resourceClassId,
209 Id<DomainId> resourceDomainId) {
210 SQLStatement statement = null;
211 try {
212 // first get all the resources from which the accessor inherits any permissions
213 final Set<Id<ResourceId>> accessorResourceIds
214 = NonRecursivePersisterHelper.getInheritedAccessorResourceIds(sqlStrings, connection, accessorResource);
215
216 // get the ancestors of the specified domain, to which the accessors could also have permissions
217 final Set<Id<DomainId>> ancestorDomainIds
218 = NonRecursivePersisterHelper.getAncestorDomainIds(sqlStrings, connection, resourceDomainId);
219
220 // now collect the global permissions any accessor resource has to the specified domain or its ancestors
221 SQLResult resultSet;
222 Set<ResourcePermission> resourcePermissions = new HashSet<>();
223 statement = connection.prepareStatement(sqlStrings.SQL_findInGrantGlobalResourcePermission_withoutInheritance_PermissionName_IsWithGrant_BY_AccessorID_AccessedDomainID_ResourceClassID);
224
225 for (Id<ResourceId> accessorResourceId : accessorResourceIds) {
226 for (Id<DomainId> domainId : ancestorDomainIds) {
227 statement.setResourceId(1, accessorResourceId);
228 statement.setResourceDomainId(2, domainId);
229 statement.setResourceClassId(3, resourceClassId);
230 resultSet = statement.executeQuery();
231
232 while (resultSet.next()) {
233 resourcePermissions.add(getResourcePermission(resultSet));
234 }
235 resultSet.close();
236 }
237 }
238
239 return resourcePermissions;
240 }
241 catch (SQLException e) {
242 throw new RuntimeException(e);
243 }
244 finally {
245 closeStatement(statement);
246 }
247 }
248
249 @Override
250 public Map<String, Map<String, Set<ResourcePermission>>> getGlobalResourcePermissionsIncludeInherited(SQLConnection connection,
251 Resource accessorResource) {
252 SQLStatement statement = null;
253 try {
254 // first get all the resources from which the accessor inherits any permissions
255 final Set<Id<ResourceId>> accessorResourceIds
256 = NonRecursivePersisterHelper.getInheritedAccessorResourceIds(sqlStrings, connection, accessorResource);
257
258 // second, get all the global resource permissions the accessors directly have access to
259 SQLResult resultSet;
260 Map<String, Map<String, Set<ResourcePermission>>> globalPermissionsMap = new HashMap<>();
261
262 statement = connection.prepareStatement(sqlStrings.SQL_findInGrantGlobalResourcePermission_withoutInheritance_ResourceDomainName_ResourceClassName_PermissionName_IsWithGrant_BY_AccessorID);
263
264 for (Id<ResourceId> accessorResourceId : accessorResourceIds) {
265 statement.setResourceId(1, accessorResourceId);
266 resultSet = statement.executeQuery();
267
268 while (resultSet.next()) {
269 final String resourceDomainName = resultSet.getString("DomainName");
270 final String resourceClassName = resultSet.getString("ResourceClassName");
271
272 Map<String, Set<ResourcePermission>> permissionsForResourceDomain
273 = globalPermissionsMap.get(resourceDomainName);
274 if (permissionsForResourceDomain == null) {
275 permissionsForResourceDomain = new HashMap<>();
276 globalPermissionsMap.put(resourceDomainName, permissionsForResourceDomain);
277 }
278
279 Set<ResourcePermission> permissionsForResourceClass
280 = permissionsForResourceDomain.get(resourceClassName);
281 if (permissionsForResourceClass == null) {
282 permissionsForResourceClass = new HashSet<>();
283 permissionsForResourceDomain.put(resourceClassName, permissionsForResourceClass);
284 }
285
286 permissionsForResourceClass.add(getResourcePermission(resultSet));
287 }
288 resultSet.close();
289 }
290 closeStatement(statement);
291 statement = null;
292
293 // then apply each domain's direct permissions to all its descendants
294 // !! DON'T UPDATE THE PERMISSION-MAP WHILE ITERATING OVER ITS KEY-SET !! (get a copy of the key-set instead)
295 Set<String> directDomainNames = new HashSet<>(globalPermissionsMap.keySet());
296 for (String directDomainName : directDomainNames) {
297 Set<String> descendentDomains = NonRecursivePersisterHelper.getDescendantDomainNames(sqlStrings,
298 connection,
299 directDomainName);
300
301 for (String descendentDomain : descendentDomains) {
302 Map<String, Set<ResourcePermission>> permissionsForResourceDomain
303 = globalPermissionsMap.get(descendentDomain);
304 if (permissionsForResourceDomain == null) {
305 permissionsForResourceDomain = new HashMap<>();
306 globalPermissionsMap.put(descendentDomain, permissionsForResourceDomain);
307 }
308
309 if (!descendentDomain.equals(directDomainName)) {
310 final Map<String, Set<ResourcePermission>> sourceResourceClassPermissionsMap
311 = globalPermissionsMap.get(directDomainName);
312
313 for (String resourceClassName : sourceResourceClassPermissionsMap.keySet()) {
314 Set<ResourcePermission> permissionsForResourceClass
315 = permissionsForResourceDomain.get(resourceClassName);
316 if (permissionsForResourceClass == null) {
317 permissionsForResourceClass = new HashSet<>();
318 permissionsForResourceDomain.put(resourceClassName, permissionsForResourceClass);
319 }
320
321 permissionsForResourceClass.addAll(sourceResourceClassPermissionsMap.get(resourceClassName));
322 }
323 }
324 }
325 }
326
327 return globalPermissionsMap;
328 }
329 catch (SQLException e) {
330 throw new RuntimeException(e);
331 }
332 finally {
333 closeStatement(statement);
334 }
335 }
336
337 @Override
338 public void removeAllGlobalResourcePermissions(SQLConnection connection,
339 Id<DomainId> accessedDomainId) {
340 SQLStatement statement = null;
341 try {
342 // get descendant domain Ids
343 List<Id<DomainId>> descendantDomainIds
344 = new ArrayList<>(NonRecursivePersisterHelper.getDescendantDomainIdsOrderedByAscendingLevel(sqlStrings,
345 connection,
346 accessedDomainId));
347
348 // delete domains' accessors (in reverse order of domainLevel, to preserve FK constraints)
349 statement = connection.prepareStatement(sqlStrings.SQL_removeInGrantGlobalResourcePermission_BY_AccessedDomainId);
350
351 for (int i=descendantDomainIds.size()-1; i >= 0; i--) {
352 statement.setResourceDomainId(1, descendantDomainIds.get(i));
353 statement.executeUpdate();
354 }
355 }
356 catch (SQLException e) {
357 throw new RuntimeException(e);
358 }
359 finally {
360 closeStatement(statement);
361 }
362 }
363 }