Coverage Summary for Class: NonRecursiveGrantResourceCreatePermissionPostCreatePersister (com.acciente.oacc.sql.internal.persister)
| Class | Class, % | Method, % | Line, % | 
|---|---|---|---|
| NonRecursiveGrantResourceCreatePermissionPostCreatePersister | 100% (1/ 1) | 100% (4/ 4) | 92.5% (74/ 80) | 
1 /*
2  * Copyright 2009-2017, 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.ResourceCreatePermission;
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.HashMap;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36 
37 public class NonRecursiveGrantResourceCreatePermissionPostCreatePersister extends CommonGrantResourceCreatePermissionPostCreatePersister implements Serializable {
38    private static final long serialVersionUID = 1L;
39 
40    public NonRecursiveGrantResourceCreatePermissionPostCreatePersister(SQLProfile sqlProfile,
41                                                                        SQLStrings sqlStrings) {
42       super(sqlProfile, sqlStrings);
43    }
44 
45    @Override
46    public Set<ResourceCreatePermission> getResourceCreatePostCreatePermissionsIncludeInherited(SQLConnection connection,
47                                                                                                Resource accessorResource,
48                                                                                                Id<ResourceClassId> resourceClassId,
49                                                                                                Id<DomainId> resourceDomainId) {
50       SQLStatement statement = null;
51 
52       try {
53          // first get all the resources from which the accessor inherits any permissions
54          final Set<Id<ResourceId>> accessorResourceIds
55                = NonRecursivePersisterHelper.getInheritedAccessorResourceIds(sqlStrings, connection, accessorResource);
56 
57          // get the ancestors of the specified domain, to which the accessors could also have permissions
58          final Set<Id<DomainId>> ancestorDomainIds
59                = NonRecursivePersisterHelper.getAncestorDomainIds(sqlStrings, connection, resourceDomainId);
60 
61          // now collect the sys-permissions any accessor resource has to the specified domain or its ancestors
62          SQLResult resultSet;
63          Set<ResourceCreatePermission> resourceCreatePermissions = new HashSet<>();
64          statement = connection.prepareStatement(sqlStrings.SQL_findInGrantResourceCreatePermissionPostCreate_withoutInheritance_PostCreatePermissionName_PostCreateIsWithGrant_IsWithGrant_BY_AccessorID_AccessedDomainID_ResourceClassID);
65 
66          for (Id<ResourceId> accessorResourceId : accessorResourceIds) {
67             for (Id<DomainId> domainId : ancestorDomainIds) {
68                statement.setResourceId(1, accessorResourceId);
69                statement.setResourceDomainId(2, domainId);
70                statement.setResourceClassId(3, resourceClassId);
71                resultSet = statement.executeQuery();
72 
73                while (resultSet.next()) {
74                   resourceCreatePermissions.add(getResourceCreatePostCreatePermission(resultSet));
75                }
76                resultSet.close();
77             }
78          }
79 
80          return resourceCreatePermissions;
81       }
82       catch (SQLException e) {
83          throw new RuntimeException(e);
84       }
85       finally {
86          closeStatement(statement);
87       }
88 
89    }
90 
91    @Override
92    public Map<String, Map<String, Set<ResourceCreatePermission>>> getResourceCreatePostCreatePermissionsIncludeInherited(SQLConnection connection,
93                                                                                                                          Resource accessorResource) {
94       SQLStatement statement = null;
95 
96       try {
97          // first get all the resources from which the accessor inherits any permissions
98          final Set<Id<ResourceId>> accessorResourceIds
99                = NonRecursivePersisterHelper.getInheritedAccessorResourceIds(sqlStrings, connection, accessorResource);
100 
101          // second, get all the resource create permissions the accessors directly have access to
102          SQLResult resultSet;
103          Map<String, Map<String, Set<ResourceCreatePermission>>> createPermissionsMap = new HashMap<>();
104 
105          statement = connection.prepareStatement(sqlStrings.SQL_findInGrantResourceCreatePermissionPostCreate_withoutInheritance_ResourceDomainName_ResourceClassName_PostCreatePermissionName_PostCreateIsWithGrant_IsWithGrant_BY_AccessorID);
106 
107          for (Id<ResourceId> accessorResourceId : accessorResourceIds) {
108             statement.setResourceId(1, accessorResourceId);
109             resultSet = statement.executeQuery();
110 
111             while (resultSet.next()) {
112                final String resourceDomainName = resultSet.getString("DomainName");
113                final String resourceClassName = resultSet.getString("ResourceClassName");
114 
115                Map<String, Set<ResourceCreatePermission>> permissionsForResourceDomain
116                      = createPermissionsMap.get(resourceDomainName);
117                if (permissionsForResourceDomain == null) {
118                   permissionsForResourceDomain = new HashMap<>();
119                   createPermissionsMap.put(resourceDomainName, permissionsForResourceDomain);
120                }
121 
122                Set<ResourceCreatePermission> permissionsForResourceClass
123                      = permissionsForResourceDomain.get(resourceClassName);
124                if (permissionsForResourceClass == null) {
125                   permissionsForResourceClass = new HashSet<>();
126                   permissionsForResourceDomain.put(resourceClassName, permissionsForResourceClass);
127                }
128 
129                permissionsForResourceClass.add(getResourceCreatePostCreatePermission(resultSet));
130             }
131             resultSet.close();
132          }
133          closeStatement(statement);
134          statement = null;
135 
136          // then apply each domain's direct permissions to all its descendants
137          // !! DON'T UPDATE THE PERMISSION-MAP WHILE ITERATING OVER ITS KEY-SET !! (get a copy of the key-set instead)
138          Set<String> directDomainNames = new HashSet<>(createPermissionsMap.keySet());
139          for (String directDomainName : directDomainNames) {
140             Set<String> descendentDomains = NonRecursivePersisterHelper.getDescendantDomainNames(sqlStrings,
141                                                                                                  connection,
142                                                                                                  directDomainName);
143 
144             for (String descendentDomain : descendentDomains) {
145                Map<String, Set<ResourceCreatePermission>> permissionsForResourceDomain
146                      = createPermissionsMap.get(descendentDomain);
147                if (permissionsForResourceDomain == null) {
148                   permissionsForResourceDomain = new HashMap<>();
149                   createPermissionsMap.put(descendentDomain, permissionsForResourceDomain);
150                }
151 
152                if (!descendentDomain.equals(directDomainName)) {
153                   final Map<String, Set<ResourceCreatePermission>> sourceResourceClassPermissionsMap
154                         = createPermissionsMap.get(directDomainName);
155 
156                   for (String resourceClassName : sourceResourceClassPermissionsMap.keySet()) {
157                      Set<ResourceCreatePermission> permissionsForResourceClass
158                            = permissionsForResourceDomain.get(resourceClassName);
159                      if (permissionsForResourceClass == null) {
160                         permissionsForResourceClass = new HashSet<>();
161                         permissionsForResourceDomain.put(resourceClassName, permissionsForResourceClass);
162                      }
163 
164                      permissionsForResourceClass.addAll(sourceResourceClassPermissionsMap.get(resourceClassName));
165                   }
166                }
167             }
168          }
169 
170          return createPermissionsMap;
171       }
172       catch (SQLException e) {
173          throw new RuntimeException(e);
174       }
175       finally {
176          closeStatement(statement);
177       }
178    }
179 
180    @Override
181    public void removeAllResourceCreatePostCreatePermissions(SQLConnection connection,
182                                                             Id<DomainId> accessedDomainId) {
183       SQLStatement statement = null;
184       try {
185          // get descendant domain Ids
186          List<Id<DomainId>> descendantDomainIds
187                = new ArrayList<>(NonRecursivePersisterHelper.getDescendantDomainIdsOrderedByAscendingLevel(sqlStrings,
188                                                                                                            connection,
189                                                                                                            accessedDomainId));
190 
191          // delete domains' accessors (in reverse order of domainLevel, to preserve FK constraints)
192          statement = connection.prepareStatement(sqlStrings.SQL_removeInGrantResourceCreatePermissionPostCreate_BY_AccessedDomainId);
193 
194          for (int i=descendantDomainIds.size()-1; i >= 0; i--) {
195             statement.setResourceDomainId(1, descendantDomainIds.get(i));
196             statement.executeUpdate();
197          }
198       }
199       catch (SQLException e) {
200          throw new RuntimeException(e);
201       }
202       finally {
203          closeStatement(statement);
204       }
205    }
206 }