1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.authorization.xacml.manager.impl;
23
24 import org.opencastproject.authorization.xacml.manager.api.AclService;
25 import org.opencastproject.authorization.xacml.manager.api.AclServiceException;
26 import org.opencastproject.authorization.xacml.manager.api.ManagedAcl;
27 import org.opencastproject.elasticsearch.api.SearchIndexException;
28 import org.opencastproject.elasticsearch.api.SearchResult;
29 import org.opencastproject.elasticsearch.api.SearchResultItem;
30 import org.opencastproject.elasticsearch.index.ElasticsearchIndex;
31 import org.opencastproject.elasticsearch.index.objects.event.Event;
32 import org.opencastproject.elasticsearch.index.objects.event.EventSearchQuery;
33 import org.opencastproject.elasticsearch.index.objects.series.Series;
34 import org.opencastproject.elasticsearch.index.objects.series.SeriesSearchQuery;
35 import org.opencastproject.security.api.AccessControlList;
36 import org.opencastproject.security.api.Organization;
37 import org.opencastproject.security.api.SecurityService;
38 import org.opencastproject.security.api.User;
39 import org.opencastproject.util.NotFoundException;
40
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 import java.util.List;
45 import java.util.Optional;
46 import java.util.function.Function;
47
48
49 public final class AclServiceImpl implements AclService {
50
51 private static final Logger logger = LoggerFactory.getLogger(AclServiceImpl.class);
52
53
54 private final Organization organization;
55
56
57 private final AclDb aclDb;
58 private final SecurityService securityService;
59
60
61 protected ElasticsearchIndex index;
62
63 public AclServiceImpl(Organization organization, AclDb aclDb, ElasticsearchIndex index,
64 SecurityService securityService) {
65 this.organization = organization;
66 this.aclDb = aclDb;
67 this.index = index;
68 this.securityService = securityService;
69 }
70
71 @Override
72 public List<ManagedAcl> getAcls() {
73 return aclDb.getAcls(organization);
74 }
75
76 @Override
77 public Optional<ManagedAcl> getAcl(long id) {
78 return aclDb.getAcl(organization, id);
79 }
80
81 @Override
82 public Optional<ManagedAcl> getAcl(String name) {
83 return aclDb.getAcl(organization, name);
84 }
85
86 @Override
87 public boolean updateAcl(ManagedAcl acl) {
88 Optional<ManagedAcl> oldName = getAcl(acl.getId());
89 boolean updateAcl = aclDb.updateAcl(acl);
90 if (updateAcl) {
91 if (oldName.isPresent() && !(oldName.get().getName().equals(acl.getName()))) {
92 User user = securityService.getUser();
93 updateAclInIndex(oldName.get().getName(), acl.getName(), index, organization.getId(), user);
94 }
95 }
96 return updateAcl;
97 }
98
99 @Override
100 public Optional<ManagedAcl> createAcl(AccessControlList acl, String name) {
101
102 return aclDb.createAcl(organization, acl, name);
103 }
104
105 @Override
106 public boolean deleteAcl(long id) throws AclServiceException, NotFoundException {
107 Optional<ManagedAcl> deletedAcl = getAcl(id);
108 if (aclDb.deleteAcl(organization, id)) {
109 if (deletedAcl.isPresent()) {
110 User user = securityService.getUser();
111 removeAclFromIndex(deletedAcl.get().getName(), index, organization.getId(), user);
112 }
113 return true;
114 }
115 throw new NotFoundException("Managed acl with id " + id + " not found.");
116 }
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132 private void updateAclInIndex(String currentAclName, String newAclName, ElasticsearchIndex index, String orgId,
133 User user) {
134 logger.debug("Update the events to change the managed acl name from '{}' to '{}'.", currentAclName, newAclName);
135 updateManagedAclForEvents(currentAclName, Optional.of(newAclName), index, orgId, user);
136
137 logger.debug("Update the series to change the managed acl name from '{}' to '{}'.", currentAclName, newAclName);
138 updateManagedAclForSeries(currentAclName, Optional.of(newAclName), index, orgId, user);
139 }
140
141
142
143
144
145
146
147
148
149
150
151
152
153 private void removeAclFromIndex(String currentAclName, ElasticsearchIndex index, String orgId,
154 User user) {
155 logger.debug("Update the events to remove the managed acl name '{}'.", currentAclName);
156 updateManagedAclForEvents(currentAclName, Optional.empty(), index, orgId, user);
157
158 logger.debug("Update the series to remove the managed acl name '{}'.", currentAclName);
159 updateManagedAclForSeries(currentAclName, Optional.empty(), index, orgId, user);
160 }
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175 private void updateManagedAclForSeries(String currentAclName, Optional<String> newAclNameOpt,
176 ElasticsearchIndex index, String orgId, User user) {
177 SearchResult<Series> result;
178 try {
179 result = index.getByQuery(new SeriesSearchQuery(orgId, user).withoutActions()
180 .withManagedAcl(currentAclName));
181 } catch (SearchIndexException e) {
182 logger.error("Unable to find the series in org '{}' with current managed acl name '{}'", orgId, currentAclName,
183 e);
184 return;
185 }
186
187 for (SearchResultItem<Series> seriesItem : result.getItems()) {
188 String seriesId = seriesItem.getSource().getIdentifier();
189
190 Function<Optional<Series>, Optional<Series>> updateFunction = (Optional<Series> seriesOpt) -> {
191 if (seriesOpt.isPresent() && seriesOpt.get().getManagedAcl().equals(currentAclName)) {
192 Series series = seriesOpt.get();
193 series.setManagedAcl(newAclNameOpt.orElse(null));
194 return Optional.of(series);
195 }
196 return Optional.empty();
197 };
198
199 try {
200 index.addOrUpdateSeries(seriesId, updateFunction, orgId, user);
201 } catch (SearchIndexException e) {
202 if (newAclNameOpt.isPresent()) {
203 logger.warn("Unable to update series'{}' from current managed acl '{}' to new managed acl name '{}'",
204 seriesId, currentAclName, newAclNameOpt.get(), e);
205 } else {
206 logger.warn("Unable to update series '{}' to remove managed acl '{}'", seriesId, currentAclName, e);
207 }
208 }
209 }
210 }
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225 private void updateManagedAclForEvents(String currentAclName, Optional<String> newAclNameOpt,
226 ElasticsearchIndex index, String orgId, User user) {
227 SearchResult<Event> result;
228 try {
229 result = index.getByQuery(new EventSearchQuery(orgId, user).withoutActions()
230 .withManagedAcl(currentAclName));
231 } catch (SearchIndexException e) {
232 logger.error("Unable to find the events in org '{}' with current managed acl name '{}' for event",
233 orgId, currentAclName, e);
234 return;
235 }
236
237 for (SearchResultItem<Event> eventItem : result.getItems()) {
238 String eventId = eventItem.getSource().getIdentifier();
239
240 Function<Optional<Event>, Optional<Event>> updateFunction = (Optional<Event> eventOpt) -> {
241 if (eventOpt.isPresent() && eventOpt.get().getManagedAcl().equals(currentAclName)) {
242 Event event = eventOpt.get();
243 event.setManagedAcl(newAclNameOpt.orElse(null));
244 return Optional.of(event);
245 }
246 return Optional.empty();
247 };
248
249 try {
250 index.addOrUpdateEvent(eventId, updateFunction, orgId, user);
251 } catch (SearchIndexException e) {
252 if (newAclNameOpt.isPresent()) {
253 logger.warn(
254 "Unable to update event '{}' from current managed acl '{}' to new managed acl name '{}'",
255 eventId, currentAclName, newAclNameOpt.get(), e);
256 } else {
257 logger.warn("Unable to update event '{}' to remove managed acl '{}'", eventId, currentAclName, e);
258 }
259 }
260 }
261 }
262 }