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