001
014
015 package com.liferay.portal.service.impl;
016
017 import com.liferay.portal.NoSuchResourcePermissionException;
018 import com.liferay.portal.kernel.concurrent.LockRegistry;
019 import com.liferay.portal.kernel.dao.db.DB;
020 import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
021 import com.liferay.portal.kernel.exception.PortalException;
022 import com.liferay.portal.kernel.exception.SystemException;
023 import com.liferay.portal.kernel.search.SearchEngineUtil;
024 import com.liferay.portal.kernel.util.StringBundler;
025 import com.liferay.portal.kernel.util.StringPool;
026 import com.liferay.portal.model.ResourceAction;
027 import com.liferay.portal.model.ResourceConstants;
028 import com.liferay.portal.model.ResourcePermission;
029 import com.liferay.portal.model.ResourcePermissionConstants;
030 import com.liferay.portal.model.Role;
031 import com.liferay.portal.model.RoleConstants;
032 import com.liferay.portal.security.permission.PermissionCacheUtil;
033 import com.liferay.portal.security.permission.ResourceActionsUtil;
034 import com.liferay.portal.service.base.ResourcePermissionLocalServiceBaseImpl;
035 import com.liferay.portal.util.PortalUtil;
036
037 import java.util.ArrayList;
038 import java.util.Collections;
039 import java.util.List;
040 import java.util.concurrent.locks.Lock;
041
042
046 public class ResourcePermissionLocalServiceImpl
047 extends ResourcePermissionLocalServiceBaseImpl {
048
049 public void addResourcePermission(
050 long companyId, String name, int scope, String primKey, long roleId,
051 String actionId)
052 throws PortalException, SystemException {
053
054 if (scope == ResourceConstants.SCOPE_COMPANY) {
055
056
057
058 removeResourcePermissions(
059 companyId, name, ResourceConstants.SCOPE_GROUP, roleId,
060 actionId);
061 }
062 else if (scope == ResourceConstants.SCOPE_GROUP) {
063
064
065
066 removeResourcePermissions(
067 companyId, name, ResourceConstants.SCOPE_COMPANY, roleId,
068 actionId);
069 }
070 else if (scope == ResourceConstants.SCOPE_INDIVIDUAL) {
071 throw new NoSuchResourcePermissionException();
072 }
073
074 updateResourcePermission(
075 companyId, name, scope, primKey, roleId, new String[] {actionId},
076 ResourcePermissionConstants.OPERATOR_ADD);
077
078 PermissionCacheUtil.clearCache();
079 }
080
081 public List<String> getAvailableResourcePermissionActionIds(
082 long companyId, String name, int scope, String primKey, long roleId,
083 List<String> actionIds)
084 throws PortalException, SystemException {
085
086 ResourcePermission resourcePermission =
087 resourcePermissionPersistence.fetchByC_N_S_P_R(
088 companyId, name, scope, primKey, roleId);
089
090 if (resourcePermission == null) {
091 return Collections.EMPTY_LIST;
092 }
093
094 List<String> availableActionIds = new ArrayList<String>(
095 actionIds.size());
096
097 for (String actionId : actionIds) {
098 ResourceAction resourceAction =
099 resourceActionLocalService.getResourceAction(name, actionId);
100
101 if (hasActionId(resourcePermission, resourceAction)) {
102 availableActionIds.add(actionId);
103 }
104 }
105
106 return availableActionIds;
107 }
108
109 public List<ResourcePermission> getResourcePermissions(
110 long companyId, String name, int scope, String primKey)
111 throws SystemException {
112
113 return resourcePermissionPersistence.findByC_N_S_P(
114 companyId, name, scope, primKey);
115 }
116
117 public int getResourcePermissionsCount(
118 long companyId, String name, int scope, String primKey)
119 throws SystemException {
120
121 return resourcePermissionPersistence.countByC_N_S_P(
122 companyId, name, scope, primKey);
123 }
124
125 public List<ResourcePermission> getRoleResourcePermissions(long roleId)
126 throws SystemException {
127
128 return resourcePermissionPersistence.findByRoleId(roleId);
129 }
130
131 public List<ResourcePermission> getRoleResourcePermissions(
132 long roleId, int[] scopes, int start, int end)
133 throws SystemException {
134
135 return resourcePermissionFinder.findByR_S(roleId, scopes, start, end);
136 }
137
138 public boolean hasActionId(
139 ResourcePermission resourcePermission, ResourceAction resourceAction) {
140
141 long actionIds = resourcePermission.getActionIds();
142 long bitwiseValue = resourceAction.getBitwiseValue();
143
144 if ((actionIds & bitwiseValue) == bitwiseValue) {
145 return true;
146 }
147 else {
148 return false;
149 }
150 }
151
152 public boolean hasResourcePermission(
153 long companyId, String name, int scope, String primKey, long roleId,
154 String actionId)
155 throws PortalException, SystemException {
156
157 ResourcePermission resourcePermission =
158 resourcePermissionPersistence.fetchByC_N_S_P_R(
159 companyId, name, scope, primKey, roleId);
160
161 if (resourcePermission == null) {
162 return false;
163 }
164
165 ResourceAction resourceAction =
166 resourceActionLocalService.getResourceAction(name, actionId);
167
168 if (hasActionId(resourcePermission, resourceAction)) {
169 return true;
170 }
171 else {
172 return false;
173 }
174 }
175
176 public boolean hasScopeResourcePermission(
177 long companyId, String name, int scope, long roleId,
178 String actionId)
179 throws PortalException, SystemException {
180
181 List<ResourcePermission> resourcePermissions =
182 resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
183
184 for (ResourcePermission resourcePermission : resourcePermissions) {
185 if (hasResourcePermission(
186 companyId, name, scope, resourcePermission.getPrimKey(),
187 roleId, actionId)) {
188
189 return true;
190 }
191 }
192
193 return false;
194 }
195
196 public void mergePermissions(long fromRoleId, long toRoleId)
197 throws PortalException, SystemException {
198
199 Role fromRole = rolePersistence.findByPrimaryKey(fromRoleId);
200 Role toRole = rolePersistence.findByPrimaryKey(toRoleId);
201
202 if (fromRole.getType() != toRole.getType()) {
203 throw new PortalException("Role types are mismatched");
204 }
205 else if (PortalUtil.isSystemRole(toRole.getName())) {
206 throw new PortalException("Cannot move permissions to system role");
207 }
208 else if (PortalUtil.isSystemRole(fromRole.getName())) {
209 throw new PortalException(
210 "Cannot move permissions from system role");
211 }
212
213 List<ResourcePermission> resourcePermissions =
214 getRoleResourcePermissions(fromRoleId);
215
216 for (ResourcePermission resourcePermission : resourcePermissions) {
217 resourcePermission.setRoleId(toRoleId);
218
219 resourcePermissionPersistence.update(resourcePermission, false);
220 }
221
222 roleLocalService.deleteRole(fromRoleId);
223
224 PermissionCacheUtil.clearCache();
225 }
226
227 public void reassignPermissions(long resourcePermissionId, long toRoleId)
228 throws PortalException, SystemException {
229
230 ResourcePermission resourcePermission = getResourcePermission(
231 resourcePermissionId);
232
233 long companyId = resourcePermission.getCompanyId();
234 String name = resourcePermission.getName();
235 int scope = resourcePermission.getScope();
236 String primKey = resourcePermission.getPrimKey();
237 long fromRoleId = resourcePermission.getRoleId();
238
239 Role toRole = roleLocalService.getRole(toRoleId);
240
241 List<String> actionIds = null;
242
243 if (toRole.getType() == RoleConstants.TYPE_REGULAR) {
244 actionIds = ResourceActionsUtil.getModelResourceActions(name);
245 }
246 else {
247 actionIds =
248 ResourceActionsUtil.getModelResourceCommunityDefaultActions(
249 name);
250 }
251
252 setResourcePermissions(
253 companyId, name, scope, primKey, toRoleId,
254 actionIds.toArray(new String[actionIds.size()]));
255
256 resourcePermissionPersistence.remove(resourcePermissionId);
257
258 List<ResourcePermission> resourcePermissions =
259 getRoleResourcePermissions(fromRoleId);
260
261 if (resourcePermissions.isEmpty()) {
262 roleLocalService.deleteRole(fromRoleId);
263 }
264 }
265
266 public void removeResourcePermission(
267 long companyId, String name, int scope, String primKey, long roleId,
268 String actionId)
269 throws PortalException, SystemException {
270
271 updateResourcePermission(
272 companyId, name, scope, primKey, roleId, new String[] {actionId},
273 ResourcePermissionConstants.OPERATOR_REMOVE);
274
275 PermissionCacheUtil.clearCache();
276 }
277
278 public void removeResourcePermissions(
279 long companyId, String name, int scope, long roleId,
280 String actionId)
281 throws PortalException, SystemException {
282
283 List<ResourcePermission> resourcePermissions =
284 resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
285
286 for (ResourcePermission resourcePermission : resourcePermissions) {
287 updateResourcePermission(
288 companyId, name, scope, resourcePermission.getPrimKey(), roleId,
289 new String[] {actionId},
290 ResourcePermissionConstants.OPERATOR_REMOVE);
291 }
292
293 PermissionCacheUtil.clearCache();
294 }
295
296 public void setResourcePermissions(
297 long companyId, String name, int scope, String primKey, long roleId,
298 String[] actionIds)
299 throws PortalException, SystemException {
300
301 updateResourcePermission(
302 companyId, name, scope, primKey, roleId, actionIds,
303 ResourcePermissionConstants.OPERATOR_SET);
304 }
305
306 protected void doUpdateResourcePermission(
307 long companyId, String name, int scope, String primKey, long roleId,
308 String[] actionIds, int operator)
309 throws PortalException, SystemException {
310
311 ResourcePermission resourcePermission =
312 resourcePermissionPersistence.fetchByC_N_S_P_R(
313 companyId, name, scope, primKey, roleId);
314
315 long oldActionIds = 0;
316
317 if (resourcePermission == null) {
318 if ((operator == ResourcePermissionConstants.OPERATOR_REMOVE) ||
319 (actionIds.length == 0)) {
320
321 return;
322 }
323
324 long resourcePermissionId = counterLocalService.increment(
325 ResourcePermission.class.getName());
326
327 resourcePermission = resourcePermissionPersistence.create(
328 resourcePermissionId);
329
330 resourcePermission.setCompanyId(companyId);
331 resourcePermission.setName(name);
332 resourcePermission.setScope(scope);
333 resourcePermission.setPrimKey(primKey);
334 resourcePermission.setRoleId(roleId);
335 }
336 else {
337 oldActionIds = resourcePermission.getActionIds();
338 }
339
340 long actionIdsLong = resourcePermission.getActionIds();
341
342 if (operator == ResourcePermissionConstants.OPERATOR_SET) {
343 actionIdsLong = 0;
344 }
345
346 for (String actionId : actionIds) {
347 ResourceAction resourceAction =
348 resourceActionLocalService.getResourceAction(name, actionId);
349
350 if ((operator == ResourcePermissionConstants.OPERATOR_ADD) ||
351 (operator == ResourcePermissionConstants.OPERATOR_SET)) {
352
353 actionIdsLong |= resourceAction.getBitwiseValue();
354 }
355 else {
356 actionIdsLong =
357 actionIdsLong & (~resourceAction.getBitwiseValue());
358 }
359 }
360
361 if (oldActionIds == actionIdsLong) {
362 return;
363 }
364
365 if (actionIdsLong == 0) {
366 resourcePermissionPersistence.remove(resourcePermission);
367 }
368 else {
369 resourcePermission.setActionIds(actionIdsLong);
370
371 resourcePermissionPersistence.update(resourcePermission, false);
372 }
373
374 PermissionCacheUtil.clearCache();
375
376 SearchEngineUtil.updatePermissionFields(name, primKey);
377 }
378
379 protected void updateResourcePermission(
380 long companyId, String name, int scope, String primKey, long roleId,
381 String[] actionIds, int operator)
382 throws PortalException, SystemException {
383
384 DB db = DBFactoryUtil.getDB();
385
386 if (!db.getType().equals(DB.TYPE_HYPERSONIC)) {
387 doUpdateResourcePermission(
388 companyId, name, scope, primKey, roleId, actionIds, operator);
389
390 return;
391 }
392
393 StringBundler sb = new StringBundler(9);
394
395 sb.append(companyId);
396 sb.append(StringPool.POUND);
397 sb.append(name);
398 sb.append(StringPool.POUND);
399 sb.append(scope);
400 sb.append(StringPool.POUND);
401 sb.append(primKey);
402 sb.append(StringPool.POUND);
403 sb.append(roleId);
404
405 String groupName = getClass().getName();
406 String key = sb.toString();
407
408 Lock lock = LockRegistry.allocateLock(groupName, key);
409
410 lock.lock();
411
412 try {
413 doUpdateResourcePermission(
414 companyId, name, scope, primKey, roleId, actionIds, operator);
415 }
416 finally {
417 lock.unlock();
418
419 LockRegistry.freeLock(groupName, key);
420 }
421 }
422
423 }