1
14
15 package com.liferay.portal.service.impl;
16
17 import com.liferay.portal.NoSuchResourcePermissionException;
18 import com.liferay.portal.PortalException;
19 import com.liferay.portal.SystemException;
20 import com.liferay.portal.kernel.concurrent.LockRegistry;
21 import com.liferay.portal.kernel.dao.db.DB;
22 import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
23 import com.liferay.portal.kernel.search.SearchEngineUtil;
24 import com.liferay.portal.kernel.util.StringBundler;
25 import com.liferay.portal.kernel.util.StringPool;
26 import com.liferay.portal.model.ResourceAction;
27 import com.liferay.portal.model.ResourceConstants;
28 import com.liferay.portal.model.ResourcePermission;
29 import com.liferay.portal.model.ResourcePermissionConstants;
30 import com.liferay.portal.model.Role;
31 import com.liferay.portal.model.RoleConstants;
32 import com.liferay.portal.security.permission.PermissionCacheUtil;
33 import com.liferay.portal.security.permission.ResourceActionsUtil;
34 import com.liferay.portal.service.base.ResourcePermissionLocalServiceBaseImpl;
35 import com.liferay.portal.util.PortalUtil;
36 import com.liferay.portal.util.ResourcePermissionsThreadLocal;
37
38 import java.util.ArrayList;
39 import java.util.Collections;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.concurrent.locks.Lock;
43
44
51 public class ResourcePermissionLocalServiceImpl
52 extends ResourcePermissionLocalServiceBaseImpl {
53
54 public void addResourcePermission(
55 long companyId, String name, int scope, String primKey, long roleId,
56 String actionId)
57 throws PortalException, SystemException {
58
59 if (scope == ResourceConstants.SCOPE_COMPANY) {
60
61
63 removeResourcePermissions(
64 companyId, name, ResourceConstants.SCOPE_GROUP, roleId,
65 actionId);
66 }
67 else if (scope == ResourceConstants.SCOPE_GROUP) {
68
69
71 removeResourcePermissions(
72 companyId, name, ResourceConstants.SCOPE_COMPANY, roleId,
73 actionId);
74 }
75 else if (scope == ResourceConstants.SCOPE_INDIVIDUAL) {
76 throw new NoSuchResourcePermissionException();
77 }
78
79 updateResourcePermission(
80 companyId, name, scope, primKey, roleId, new String[] {actionId},
81 ResourcePermissionConstants.OPERATOR_ADD);
82
83 PermissionCacheUtil.clearCache();
84 }
85
86 public List<String> getAvailableResourcePermissionActionIds(
87 long companyId, String name, int scope, String primKey, long roleId,
88 List<String> actionIds)
89 throws PortalException, SystemException {
90
91 ResourcePermission resourcePermission =
92 resourcePermissionPersistence.fetchByC_N_S_P_R(
93 companyId, name, scope, primKey, roleId);
94
95 if (resourcePermission == null) {
96 return Collections.EMPTY_LIST;
97 }
98
99 List<String> availableActionIds = new ArrayList<String>(
100 actionIds.size());
101
102 for (String actionId : actionIds) {
103 ResourceAction resourceAction =
104 resourceActionLocalService.getResourceAction(name, actionId);
105
106 if (hasActionId(resourcePermission, resourceAction)) {
107 availableActionIds.add(actionId);
108 }
109 }
110
111 return availableActionIds;
112 }
113
114 public int getResourcePermissionsCount(
115 long companyId, String name, int scope, String primKey)
116 throws SystemException {
117
118 return resourcePermissionPersistence.countByC_N_S_P(
119 companyId, name, scope, primKey);
120 }
121
122 public List<ResourcePermission> getRoleResourcePermissions(long roleId)
123 throws SystemException {
124
125 return resourcePermissionPersistence.findByRoleId(roleId);
126 }
127
128 public List<ResourcePermission> getRoleResourcePermissions(
129 long roleId, int[] scopes, int start, int end)
130 throws SystemException {
131
132 return resourcePermissionFinder.findByR_S(roleId, scopes, start, end);
133 }
134
135 public boolean hasActionId(
136 ResourcePermission resourcePermission, ResourceAction resourceAction) {
137
138 long actionIds = resourcePermission.getActionIds();
139 long bitwiseValue = resourceAction.getBitwiseValue();
140
141 if ((actionIds & bitwiseValue) == bitwiseValue) {
142 return true;
143 }
144 else {
145 return false;
146 }
147 }
148
149 public boolean hasResourcePermission(
150 long companyId, String name, int scope, String primKey, long roleId,
151 String actionId)
152 throws PortalException, SystemException {
153
154
157
158 ResourcePermission resourcePermission = null;
159
160 for (ResourcePermission curResourcePermission :
161 resourcePermissionPersistence.findByC_N_S_P(
162 companyId, name, scope, primKey)) {
163
164 if (curResourcePermission.getRoleId() == roleId) {
165 resourcePermission = curResourcePermission;
166
167 break;
168 }
169 }
170
171 if (resourcePermission == null) {
172 return false;
173 }
174
175 ResourceAction resourceAction =
176 resourceActionLocalService.getResourceAction(name, actionId);
177
178 if (hasActionId(resourcePermission, resourceAction)) {
179 return true;
180 }
181 else {
182 return false;
183 }
184 }
185
186 public boolean hasScopeResourcePermission(
187 long companyId, String name, int scope, long roleId,
188 String actionId)
189 throws PortalException, SystemException {
190
191 List<ResourcePermission> resourcePermissions =
192 resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
193
194 for (ResourcePermission resourcePermission : resourcePermissions) {
195 if (hasResourcePermission(
196 companyId, name, scope, resourcePermission.getPrimKey(),
197 roleId, actionId)) {
198
199 return true;
200 }
201 }
202
203 return false;
204 }
205
206 public void mergePermissions(long fromRoleId, long toRoleId)
207 throws PortalException, SystemException {
208
209 Role fromRole = rolePersistence.findByPrimaryKey(fromRoleId);
210 Role toRole = rolePersistence.findByPrimaryKey(toRoleId);
211
212 if (fromRole.getType() != toRole.getType()) {
213 throw new PortalException("Role types are mismatched");
214 }
215 else if (PortalUtil.isSystemRole(toRole.getName())) {
216 throw new PortalException("Cannot move permissions to system role");
217 }
218 else if (PortalUtil.isSystemRole(fromRole.getName())) {
219 throw new PortalException(
220 "Cannot move permissions from system role");
221 }
222
223 List<ResourcePermission> resourcePermissions =
224 getRoleResourcePermissions(fromRoleId);
225
226 for (ResourcePermission resourcePermission : resourcePermissions) {
227 resourcePermission.setRoleId(toRoleId);
228
229 resourcePermissionPersistence.update(resourcePermission, false);
230 }
231
232 roleLocalService.deleteRole(fromRoleId);
233
234 PermissionCacheUtil.clearCache();
235 }
236
237 public void reassignPermissions(long resourcePermissionId, long toRoleId)
238 throws PortalException, SystemException {
239
240 ResourcePermission resourcePermission = getResourcePermission(
241 resourcePermissionId);
242
243 long companyId = resourcePermission.getCompanyId();
244 String name = resourcePermission.getName();
245 int scope = resourcePermission.getScope();
246 String primKey = resourcePermission.getPrimKey();
247 long fromRoleId = resourcePermission.getRoleId();
248
249 Role toRole = roleLocalService.getRole(toRoleId);
250
251 List<String> actionIds = null;
252
253 if (toRole.getType() == RoleConstants.TYPE_REGULAR) {
254 actionIds = ResourceActionsUtil.getModelResourceActions(name);
255 }
256 else {
257 actionIds =
258 ResourceActionsUtil.getModelResourceCommunityDefaultActions(
259 name);
260 }
261
262 setResourcePermissions(
263 companyId, name, scope, primKey, toRoleId,
264 actionIds.toArray(new String[actionIds.size()]));
265
266 resourcePermissionPersistence.remove(resourcePermissionId);
267
268 List<ResourcePermission> resourcePermissions =
269 getRoleResourcePermissions(fromRoleId);
270
271 if (resourcePermissions.isEmpty()) {
272 roleLocalService.deleteRole(fromRoleId);
273 }
274 }
275
276 public void removeResourcePermission(
277 long companyId, String name, int scope, String primKey, long roleId,
278 String actionId)
279 throws PortalException, SystemException {
280
281 updateResourcePermission(
282 companyId, name, scope, primKey, roleId, new String[] {actionId},
283 ResourcePermissionConstants.OPERATOR_REMOVE);
284
285 PermissionCacheUtil.clearCache();
286 }
287
288 public void removeResourcePermissions(
289 long companyId, String name, int scope, long roleId,
290 String actionId)
291 throws PortalException, SystemException {
292
293 List<ResourcePermission> resourcePermissions =
294 resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
295
296 for (ResourcePermission resourcePermission : resourcePermissions) {
297 updateResourcePermission(
298 companyId, name, scope, resourcePermission.getPrimKey(), roleId,
299 new String[] {actionId},
300 ResourcePermissionConstants.OPERATOR_REMOVE);
301 }
302
303 PermissionCacheUtil.clearCache();
304 }
305
306 public void setResourcePermissions(
307 long companyId, String name, int scope, String primKey, long roleId,
308 String[] actionIds)
309 throws PortalException, SystemException {
310
311 updateResourcePermission(
312 companyId, name, scope, primKey, roleId, actionIds,
313 ResourcePermissionConstants.OPERATOR_SET);
314 }
315
316 protected void doUpdateResourcePermission(
317 long companyId, String name, int scope, String primKey, long roleId,
318 String[] actionIds, int operator)
319 throws PortalException, SystemException {
320
321 ResourcePermission resourcePermission = null;
322
323 Map<Long, ResourcePermission> resourcePermissions =
324 ResourcePermissionsThreadLocal.getResourcePermissions();
325
326 if (resourcePermissions != null) {
327 resourcePermission = resourcePermissions.get(roleId);
328 }
329 else {
330 resourcePermission = resourcePermissionPersistence.fetchByC_N_S_P_R(
331 companyId, name, scope, primKey, roleId);
332 }
333
334 long oldActionIds = 0;
335
336 if (resourcePermission == null) {
337 if ((operator == ResourcePermissionConstants.OPERATOR_REMOVE) ||
338 (actionIds.length == 0)) {
339
340 return;
341 }
342
343 long resourcePermissionId = counterLocalService.increment(
344 ResourcePermission.class.getName());
345
346 resourcePermission = resourcePermissionPersistence.create(
347 resourcePermissionId);
348
349 resourcePermission.setCompanyId(companyId);
350 resourcePermission.setName(name);
351 resourcePermission.setScope(scope);
352 resourcePermission.setPrimKey(primKey);
353 resourcePermission.setRoleId(roleId);
354 }
355 else {
356 oldActionIds = resourcePermission.getActionIds();
357 }
358
359 long actionIdsLong = resourcePermission.getActionIds();
360
361 if (operator == ResourcePermissionConstants.OPERATOR_SET) {
362 actionIdsLong = 0;
363 }
364
365 for (String actionId : actionIds) {
366 ResourceAction resourceAction =
367 resourceActionLocalService.getResourceAction(name, actionId);
368
369 if ((operator == ResourcePermissionConstants.OPERATOR_ADD) ||
370 (operator == ResourcePermissionConstants.OPERATOR_SET)) {
371
372 actionIdsLong |= resourceAction.getBitwiseValue();
373 }
374 else {
375 actionIdsLong =
376 actionIdsLong & (~resourceAction.getBitwiseValue());
377 }
378 }
379
380 if (oldActionIds == actionIdsLong) {
381 return;
382 }
383
384 if (actionIdsLong == 0) {
385 resourcePermissionPersistence.remove(resourcePermission);
386 }
387 else {
388 resourcePermission.setActionIds(actionIdsLong);
389
390 resourcePermissionPersistence.update(resourcePermission, false);
391 }
392
393 PermissionCacheUtil.clearCache();
394
395 SearchEngineUtil.updatePermissionFields(name, primKey);
396 }
397
398 protected void updateResourcePermission(
399 long companyId, String name, int scope, String primKey, long roleId,
400 String[] actionIds, int operator)
401 throws PortalException, SystemException {
402
403 DB db = DBFactoryUtil.getDB();
404
405 if (!db.getType().equals(DB.TYPE_HYPERSONIC)) {
406 doUpdateResourcePermission(
407 companyId, name, scope, primKey, roleId, actionIds, operator);
408
409 return;
410 }
411
412 StringBundler sb = new StringBundler(9);
413
414 sb.append(companyId);
415 sb.append(StringPool.POUND);
416 sb.append(name);
417 sb.append(StringPool.POUND);
418 sb.append(scope);
419 sb.append(StringPool.POUND);
420 sb.append(primKey);
421 sb.append(StringPool.POUND);
422 sb.append(roleId);
423
424 String groupName = getClass().getName();
425 String key = sb.toString();
426
427 Lock lock = LockRegistry.allocateLock(groupName, key);
428
429 lock.lock();
430
431 try {
432 doUpdateResourcePermission(
433 companyId, name, scope, primKey, roleId, actionIds, operator);
434 }
435 finally {
436 lock.unlock();
437
438 LockRegistry.freeLock(groupName, key);
439 }
440 }
441
442 }