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