1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
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.model.ResourceAction;
21  import com.liferay.portal.model.ResourceConstants;
22  import com.liferay.portal.model.ResourcePermission;
23  import com.liferay.portal.model.ResourcePermissionConstants;
24  import com.liferay.portal.model.Role;
25  import com.liferay.portal.model.RoleConstants;
26  import com.liferay.portal.security.permission.PermissionCacheUtil;
27  import com.liferay.portal.security.permission.ResourceActionsUtil;
28  import com.liferay.portal.service.base.ResourcePermissionLocalServiceBaseImpl;
29  import com.liferay.portal.util.PortalUtil;
30  
31  import java.util.ArrayList;
32  import java.util.Collections;
33  import java.util.List;
34  
35  /**
36   * <a href="ResourcePermissionLocalServiceImpl.java.html"><b><i>View Source</i>
37   * </b></a>
38   *
39   * @author Brian Wing Shun Chan
40   */
41  public class ResourcePermissionLocalServiceImpl
42      extends ResourcePermissionLocalServiceBaseImpl {
43  
44      public void addResourcePermission(
45              long companyId, String name, int scope, String primKey, long roleId,
46              String actionId)
47          throws PortalException, SystemException {
48  
49          if (scope == ResourceConstants.SCOPE_COMPANY) {
50  
51              // Remove group permission
52  
53              removeResourcePermissions(
54                  companyId, name, ResourceConstants.SCOPE_GROUP, roleId,
55                  actionId);
56          }
57          else if (scope == ResourceConstants.SCOPE_GROUP) {
58  
59              // Remove company permission
60  
61              removeResourcePermissions(
62                  companyId, name, ResourceConstants.SCOPE_COMPANY, roleId,
63                  actionId);
64          }
65          else if (scope == ResourceConstants.SCOPE_INDIVIDUAL) {
66              throw new NoSuchResourcePermissionException();
67          }
68  
69          updateResourcePermission(
70              companyId, name, scope, primKey, roleId, new String[] {actionId},
71              ResourcePermissionConstants.OPERATOR_ADD);
72  
73          PermissionCacheUtil.clearCache();
74      }
75  
76      public List<String> getAvailableResourcePermissionActionIds(
77              long companyId, String name, int scope, String primKey, long roleId,
78              List<String> actionIds)
79          throws PortalException, SystemException {
80  
81          ResourcePermission resourcePermission =
82              resourcePermissionPersistence.fetchByC_N_S_P_R(
83                  companyId, name, scope, primKey, roleId);
84  
85          if (resourcePermission == null) {
86              return Collections.EMPTY_LIST;
87          }
88  
89          List<String> availableActionIds = new ArrayList<String>(
90              actionIds.size());
91  
92          for (String actionId : actionIds) {
93              ResourceAction resourceAction =
94                  resourceActionLocalService.getResourceAction(name, actionId);
95  
96              if (hasActionId(resourcePermission, resourceAction)) {
97                  availableActionIds.add(actionId);
98              }
99          }
100 
101         return availableActionIds;
102     }
103 
104     public int getResourcePermissionsCount(
105             long companyId, String name, int scope, String primKey)
106         throws SystemException {
107 
108         return resourcePermissionPersistence.countByC_N_S_P(
109             companyId, name, scope, primKey);
110     }
111 
112     public List<ResourcePermission> getRoleResourcePermissions(long roleId)
113         throws SystemException {
114 
115         return resourcePermissionPersistence.findByRoleId(roleId);
116     }
117 
118     public List<ResourcePermission> getRoleResourcePermissions(
119             long roleId, int[] scopes, int start, int end)
120         throws SystemException {
121 
122         return resourcePermissionFinder.findByR_S(roleId, scopes, start, end);
123     }
124 
125     public boolean hasActionId(
126         ResourcePermission resourcePermission, ResourceAction resourceAction) {
127 
128         long actionIds = resourcePermission.getActionIds();
129         long bitwiseValue = resourceAction.getBitwiseValue();
130 
131         if ((actionIds & bitwiseValue) == bitwiseValue) {
132             return true;
133         }
134         else {
135             return false;
136         }
137     }
138 
139     public boolean hasResourcePermission(
140             long companyId, String name, int scope, String primKey, long roleId,
141             String actionId)
142         throws PortalException, SystemException {
143 
144         ResourcePermission resourcePermission =
145             resourcePermissionPersistence.fetchByC_N_S_P_R(
146                 companyId, name, scope, primKey, roleId);
147 
148         if (resourcePermission == null) {
149             return false;
150         }
151 
152         ResourceAction resourceAction =
153             resourceActionLocalService.getResourceAction(name, actionId);
154 
155         if (hasActionId(resourcePermission, resourceAction)) {
156             return true;
157         }
158         else {
159             return false;
160         }
161     }
162 
163     public boolean hasScopeResourcePermission(
164             long companyId, String name, int scope, long roleId,
165             String actionId)
166         throws PortalException, SystemException {
167 
168         List<ResourcePermission> resourcePermissions =
169             resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
170 
171         for (ResourcePermission resourcePermission : resourcePermissions) {
172             if (hasResourcePermission(
173                     companyId, name, scope, resourcePermission.getPrimKey(),
174                     roleId, actionId)) {
175 
176                 return true;
177             }
178         }
179 
180         return false;
181     }
182 
183     public void mergePermissions(long fromRoleId, long toRoleId)
184         throws PortalException, SystemException {
185 
186         Role fromRole = rolePersistence.findByPrimaryKey(fromRoleId);
187         Role toRole = rolePersistence.findByPrimaryKey(toRoleId);
188 
189         if (fromRole.getType() != toRole.getType()) {
190             throw new PortalException("Role types are mismatched");
191         }
192         else if (PortalUtil.isSystemRole(toRole.getName())) {
193             throw new PortalException("Cannot move permissions to system role");
194         }
195         else if (PortalUtil.isSystemRole(fromRole.getName())) {
196             throw new PortalException(
197                 "Cannot move permissions from system role");
198         }
199 
200         List<ResourcePermission> resourcePermissions =
201             getRoleResourcePermissions(fromRoleId);
202 
203         for (ResourcePermission resourcePermission : resourcePermissions) {
204             resourcePermission.setRoleId(toRoleId);
205 
206             resourcePermissionPersistence.update(resourcePermission, false);
207         }
208 
209         roleLocalService.deleteRole(fromRoleId);
210 
211         PermissionCacheUtil.clearCache();
212     }
213 
214     public void reassignPermissions(long resourcePermissionId, long toRoleId)
215         throws PortalException, SystemException {
216 
217         ResourcePermission resourcePermission = getResourcePermission(
218             resourcePermissionId);
219 
220         long companyId = resourcePermission.getCompanyId();
221         String name = resourcePermission.getName();
222         int scope = resourcePermission.getScope();
223         String primKey = resourcePermission.getPrimKey();
224         long fromRoleId = resourcePermission.getRoleId();
225 
226         Role toRole = roleLocalService.getRole(toRoleId);
227 
228         List<String> actionIds = null;
229 
230         if (toRole.getType() == RoleConstants.TYPE_REGULAR) {
231             actionIds = ResourceActionsUtil.getModelResourceActions(name);
232         }
233         else {
234             actionIds =
235                 ResourceActionsUtil.getModelResourceCommunityDefaultActions(
236                     name);
237         }
238 
239         setResourcePermissions(
240             companyId, name, scope, primKey, toRoleId,
241             actionIds.toArray(new String[actionIds.size()]));
242 
243         resourcePermissionPersistence.remove(resourcePermissionId);
244 
245         List<ResourcePermission> resourcePermissions =
246             getRoleResourcePermissions(fromRoleId);
247 
248         if (resourcePermissions.isEmpty()) {
249             roleLocalService.deleteRole(fromRoleId);
250         }
251     }
252 
253     public void removeResourcePermission(
254             long companyId, String name, int scope, String primKey, long roleId,
255             String actionId)
256         throws PortalException, SystemException {
257 
258         updateResourcePermission(
259             companyId, name, scope, primKey, roleId, new String[] {actionId},
260             ResourcePermissionConstants.OPERATOR_REMOVE);
261 
262         PermissionCacheUtil.clearCache();
263     }
264 
265     public void removeResourcePermissions(
266             long companyId, String name, int scope, long roleId,
267             String actionId)
268         throws PortalException, SystemException {
269 
270         List<ResourcePermission> resourcePermissions =
271             resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
272 
273         for (ResourcePermission resourcePermission : resourcePermissions) {
274             updateResourcePermission(
275                 companyId, name, scope, resourcePermission.getPrimKey(), roleId,
276                 new String[] {actionId},
277                 ResourcePermissionConstants.OPERATOR_REMOVE);
278         }
279 
280         PermissionCacheUtil.clearCache();
281     }
282 
283     public void setResourcePermissions(
284             long companyId, String name, int scope, String primKey, long roleId,
285             String[] actionIds)
286         throws PortalException, SystemException {
287 
288         updateResourcePermission(
289             companyId, name, scope, primKey, roleId, actionIds,
290             ResourcePermissionConstants.OPERATOR_SET);
291     }
292 
293     protected void updateResourcePermission(
294             long companyId, String name, int scope, String primKey, long roleId,
295             String[] actionIds, int operator)
296         throws PortalException, SystemException {
297 
298         ResourcePermission resourcePermission =
299             resourcePermissionPersistence.fetchByC_N_S_P_R(
300                 companyId, name, scope, primKey, roleId);
301 
302         if (resourcePermission == null) {
303             if (operator == ResourcePermissionConstants.OPERATOR_REMOVE) {
304                 return;
305             }
306 
307             long resourcePermissionId = counterLocalService.increment(
308                 ResourcePermission.class.getName());
309 
310             resourcePermission = resourcePermissionPersistence.create(
311                 resourcePermissionId);
312 
313             resourcePermission.setCompanyId(companyId);
314             resourcePermission.setName(name);
315             resourcePermission.setScope(scope);
316             resourcePermission.setPrimKey(primKey);
317             resourcePermission.setRoleId(roleId);
318         }
319 
320         long actionIdsLong = resourcePermission.getActionIds();
321 
322         if (operator == ResourcePermissionConstants.OPERATOR_SET) {
323             actionIdsLong = 0;
324         }
325 
326         for (String actionId : actionIds) {
327             ResourceAction resourceAction =
328                 resourceActionLocalService.getResourceAction(name, actionId);
329 
330             if ((operator == ResourcePermissionConstants.OPERATOR_ADD) ||
331                 (operator == ResourcePermissionConstants.OPERATOR_SET)) {
332 
333                 actionIdsLong |= resourceAction.getBitwiseValue();
334             }
335             else {
336                 actionIdsLong =
337                     actionIdsLong & (~resourceAction.getBitwiseValue());
338             }
339         }
340 
341         resourcePermission.setActionIds(actionIdsLong);
342 
343         resourcePermissionPersistence.update(resourcePermission, false);
344 
345         PermissionCacheUtil.clearCache();
346     }
347 
348 }