1 package io.oasp.module.security.common.base.accesscontrol;
2
3 import io.oasp.module.security.common.api.accesscontrol.AccessControl;
4 import io.oasp.module.security.common.api.accesscontrol.AccessControlGroup;
5 import io.oasp.module.security.common.api.accesscontrol.AccessControlPermission;
6 import io.oasp.module.security.common.api.accesscontrol.AccessControlProvider;
7 import io.oasp.module.security.common.api.accesscontrol.AccessControlSchema;
8
9 import java.util.HashMap;
10 import java.util.HashSet;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Set;
14
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17
18
19
20
21
22
23
24
25 public abstract class AbstractAccessControlProvider implements AccessControlProvider {
26
27
28 private static final Logger LOG = LoggerFactory.getLogger(AbstractAccessControlProvider.class);
29
30
31 private final Map<String, AccessControl> id2nodeMap;
32
33
34
35
36 public AbstractAccessControlProvider() {
37
38 super();
39 this.id2nodeMap = new HashMap<>();
40 }
41
42
43
44
45
46
47 protected void initialize(AccessControlSchema config) {
48
49 LOG.debug("Initializing.");
50 List<AccessControlGroup> groups = config.getGroups();
51 if (groups.size() == 0) {
52 throw new IllegalStateException("AccessControlSchema is empty - please configure at least one group!");
53 }
54 Set<AccessControlGroup> toplevelGroups = new HashSet<>(groups);
55 for (AccessControlGroup group : groups) {
56 collectAccessControls(group, toplevelGroups);
57 checkForCyclicDependencies(group, new HashSet<AccessControlGroup>());
58 }
59 }
60
61
62
63
64
65
66
67
68 protected void checkForCyclicDependencies(AccessControlGroup group, Set<AccessControlGroup> visitedGroups) {
69
70 boolean added = visitedGroups.add(group);
71 if (!added) {
72
73 throw new IllegalStateException("Cyclic inheritance of access control groups detected for " + group);
74 }
75 for (AccessControlGroup inheritedGroup : group.getInherits()) {
76 checkForCyclicDependencies(inheritedGroup, visitedGroups);
77 }
78 }
79
80
81
82
83
84
85
86
87 protected void collectAccessControls(AccessControlGroup group, Set<AccessControlGroup> toplevelGroups) {
88
89
90
91
92
93 AccessControl old = this.id2nodeMap.put(group.getId(), group);
94 if (old != null) {
95 LOG.debug("Already visited access control group {}", group);
96 if (old != group) {
97 throw new IllegalStateException("Invalid security configuration: duplicate groups with id " + group.getId()
98 + "!");
99 }
100
101 return;
102 } else {
103 LOG.debug("Registered access control group {}", group);
104 }
105 for (AccessControlPermission permission : group.getPermissions()) {
106 old = this.id2nodeMap.put(permission.getId(), permission);
107 if (old != null) {
108
109
110 LOG.warn("Security configuration contains duplicate permission with id {}.", permission.getId());
111 } else {
112 LOG.debug("Registered access control permission {}", permission);
113 }
114 }
115 for (AccessControlGroup inheritedGroup : group.getInherits()) {
116 collectAccessControls(inheritedGroup, toplevelGroups);
117 }
118 }
119
120 @Override
121 public AccessControl getAccessControl(String nodeId) {
122
123 return this.id2nodeMap.get(nodeId);
124 }
125
126 @Override
127 public boolean collectAccessControlIds(String groupId, Set<String> permissions) {
128
129 AccessControl node = getAccessControl(groupId);
130 if (node instanceof AccessControlGroup) {
131 collectPermissionIds((AccessControlGroup) node, permissions);
132 } else {
133
134 permissions.add(groupId);
135 }
136 return (node != null);
137 }
138
139
140
141
142
143
144
145 public void collectPermissionIds(AccessControlGroup group, Set<String> permissions) {
146
147 boolean added = permissions.add(group.getId());
148 if (!added) {
149
150 return;
151 }
152 for (AccessControlPermission permission : group.getPermissions()) {
153 permissions.add(permission.getId());
154 }
155 for (AccessControlGroup inheritedGroup : group.getInherits()) {
156 collectPermissionIds(inheritedGroup, permissions);
157 }
158 }
159
160 @Override
161 public boolean collectAccessControls(String groupId, Set<AccessControl> permissions) {
162
163 AccessControl node = getAccessControl(groupId);
164 if (node == null) {
165 return false;
166 }
167 if (node instanceof AccessControlGroup) {
168 collectPermissionNodes((AccessControlGroup) node, permissions);
169 } else {
170
171 permissions.add(node);
172 }
173 return true;
174 }
175
176
177
178
179
180
181
182 public void collectPermissionNodes(AccessControlGroup group, Set<AccessControl> permissions) {
183
184 boolean added = permissions.add(group);
185 if (!added) {
186
187 return;
188 }
189 for (AccessControlPermission permission : group.getPermissions()) {
190 permissions.add(permission);
191 }
192 for (AccessControlGroup inheritedGroup : group.getInherits()) {
193 collectPermissionNodes(inheritedGroup, permissions);
194 }
195 }
196
197 }