001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.rolesadmin.action;
016    
017    import com.liferay.portal.NoSuchRoleException;
018    import com.liferay.portal.RolePermissionsException;
019    import com.liferay.portal.kernel.servlet.SessionErrors;
020    import com.liferay.portal.kernel.servlet.SessionMessages;
021    import com.liferay.portal.kernel.util.ArrayUtil;
022    import com.liferay.portal.kernel.util.Constants;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.ListUtil;
025    import com.liferay.portal.kernel.util.ParamUtil;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.kernel.util.Validator;
028    import com.liferay.portal.model.GroupConstants;
029    import com.liferay.portal.model.ResourceConstants;
030    import com.liferay.portal.model.Role;
031    import com.liferay.portal.model.RoleConstants;
032    import com.liferay.portal.security.auth.PrincipalException;
033    import com.liferay.portal.security.permission.ResourceActionsUtil;
034    import com.liferay.portal.security.permission.comparator.ActionComparator;
035    import com.liferay.portal.service.ResourceBlockLocalServiceUtil;
036    import com.liferay.portal.service.ResourceBlockServiceUtil;
037    import com.liferay.portal.service.ResourcePermissionServiceUtil;
038    import com.liferay.portal.service.RoleLocalServiceUtil;
039    import com.liferay.portal.struts.PortletAction;
040    import com.liferay.portal.theme.ThemeDisplay;
041    import com.liferay.portal.util.PortalUtil;
042    import com.liferay.portal.util.WebKeys;
043    
044    import java.util.HashMap;
045    import java.util.List;
046    import java.util.Map;
047    
048    import javax.portlet.ActionRequest;
049    import javax.portlet.ActionResponse;
050    import javax.portlet.PortletConfig;
051    import javax.portlet.RenderRequest;
052    import javax.portlet.RenderResponse;
053    
054    import org.apache.struts.action.ActionForm;
055    import org.apache.struts.action.ActionForward;
056    import org.apache.struts.action.ActionMapping;
057    
058    /**
059     * @author Brian Wing Shun Chan
060     * @author Jorge Ferrer
061     * @author Connor McKay
062     */
063    public class EditRolePermissionsAction extends PortletAction {
064    
065            @Override
066            public void processAction(
067                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
068                            ActionRequest actionRequest, ActionResponse actionResponse)
069                    throws Exception {
070    
071                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
072    
073                    try {
074                            if (cmd.equals("actions")) {
075                                    updateActions(actionRequest, actionResponse);
076                            }
077                            else if (cmd.equals("delete_permission")) {
078                                    deletePermission(actionRequest, actionResponse);
079                            }
080                    }
081                    catch (Exception e) {
082                            if (e instanceof NoSuchRoleException ||
083                                    e instanceof PrincipalException ||
084                                    e instanceof RolePermissionsException) {
085    
086                                    SessionErrors.add(actionRequest, e.getClass());
087    
088                                    setForward(actionRequest, "portlet.roles_admin.error");
089                            }
090                            else {
091                                    throw e;
092                            }
093                    }
094            }
095    
096            @Override
097            public ActionForward render(
098                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
099                            RenderRequest renderRequest, RenderResponse renderResponse)
100                    throws Exception {
101    
102                    try {
103                            ActionUtil.getRole(renderRequest);
104                    }
105                    catch (Exception e) {
106                            if (e instanceof NoSuchRoleException ||
107                                    e instanceof PrincipalException) {
108    
109                                    SessionErrors.add(renderRequest, e.getClass());
110    
111                                    return mapping.findForward("portlet.roles_admin.error");
112                            }
113                            else {
114                                    throw e;
115                            }
116                    }
117    
118                    return mapping.findForward(
119                            getForward(
120                                    renderRequest, "portlet.roles_admin.edit_role_permissions"));
121            }
122    
123            protected void deletePermission(
124                            ActionRequest actionRequest, ActionResponse actionResponse)
125                    throws Exception {
126    
127                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
128                            WebKeys.THEME_DISPLAY);
129    
130                    long roleId = ParamUtil.getLong(actionRequest, "roleId");
131                    String name = ParamUtil.getString(actionRequest, "name");
132                    int scope = ParamUtil.getInteger(actionRequest, "scope");
133                    String primKey = ParamUtil.getString(actionRequest, "primKey");
134                    String actionId = ParamUtil.getString(actionRequest, "actionId");
135    
136                    Role role = RoleLocalServiceUtil.getRole(roleId);
137    
138                    String roleName = role.getName();
139    
140                    if (roleName.equals(RoleConstants.ADMINISTRATOR) ||
141                            roleName.equals(RoleConstants.ORGANIZATION_ADMINISTRATOR) ||
142                            roleName.equals(RoleConstants.ORGANIZATION_OWNER) ||
143                            roleName.equals(RoleConstants.OWNER) ||
144                            roleName.equals(RoleConstants.SITE_ADMINISTRATOR) ||
145                            roleName.equals(RoleConstants.SITE_OWNER)) {
146    
147                            throw new RolePermissionsException(roleName);
148                    }
149    
150                    if (ResourceBlockLocalServiceUtil.isSupported(name)) {
151                            if (scope == ResourceConstants.SCOPE_GROUP) {
152                                    ResourceBlockServiceUtil.removeGroupScopePermission(
153                                            themeDisplay.getScopeGroupId(), themeDisplay.getCompanyId(),
154                                            GetterUtil.getLong(primKey), name, roleId, actionId);
155                            }
156                            else {
157                                    ResourceBlockServiceUtil.removeCompanyScopePermission(
158                                            themeDisplay.getScopeGroupId(), themeDisplay.getCompanyId(),
159                                            name, roleId, actionId);
160                            }
161                    }
162                    else {
163                            ResourcePermissionServiceUtil.removeResourcePermission(
164                                    themeDisplay.getScopeGroupId(), themeDisplay.getCompanyId(),
165                                    name, scope, primKey, roleId, actionId);
166                    }
167    
168                    // Send redirect
169    
170                    SessionMessages.add(actionRequest, "permissionDeleted");
171    
172                    String redirect = PortalUtil.escapeRedirect(
173                            ParamUtil.getString(actionRequest, "redirect"));
174    
175                    if (Validator.isNotNull(redirect)) {
176                            actionResponse.sendRedirect(redirect);
177                    }
178            }
179    
180            protected void updateAction(
181                            Role role, long groupId, String selResource, String actionId,
182                            boolean selected, int scope, String[] groupIds)
183                    throws Exception {
184    
185                    long companyId = role.getCompanyId();
186                    long roleId = role.getRoleId();
187    
188                    if (selected) {
189                            if (scope == ResourceConstants.SCOPE_COMPANY) {
190                                    ResourcePermissionServiceUtil.addResourcePermission(
191                                            groupId, companyId, selResource, scope,
192                                            String.valueOf(role.getCompanyId()), roleId, actionId);
193                            }
194                            else if (scope == ResourceConstants.SCOPE_GROUP_TEMPLATE) {
195                                    ResourcePermissionServiceUtil.addResourcePermission(
196                                            groupId, companyId, selResource,
197                                            ResourceConstants.SCOPE_GROUP_TEMPLATE,
198                                            String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID),
199                                            roleId, actionId);
200                            }
201                            else if (scope == ResourceConstants.SCOPE_GROUP) {
202                                    ResourcePermissionServiceUtil.removeResourcePermissions(
203                                            groupId, companyId, selResource,
204                                            ResourceConstants.SCOPE_GROUP, roleId, actionId);
205    
206                                    for (String curGroupId : groupIds) {
207                                            ResourcePermissionServiceUtil.addResourcePermission(
208                                                    groupId, companyId, selResource,
209                                                    ResourceConstants.SCOPE_GROUP, curGroupId, roleId,
210                                                    actionId);
211                                    }
212                            }
213                    }
214                    else {
215    
216                            // Remove company, group template, and group permissions
217    
218                            ResourcePermissionServiceUtil.removeResourcePermissions(
219                                    groupId, companyId, selResource,
220                                    ResourceConstants.SCOPE_COMPANY, roleId, actionId);
221    
222                            ResourcePermissionServiceUtil.removeResourcePermissions(
223                                    groupId, companyId, selResource,
224                                    ResourceConstants.SCOPE_GROUP_TEMPLATE, roleId, actionId);
225    
226                            ResourcePermissionServiceUtil.removeResourcePermissions(
227                                    groupId, companyId, selResource, ResourceConstants.SCOPE_GROUP,
228                                    roleId, actionId);
229                    }
230            }
231    
232            protected void updateActions(
233                            ActionRequest actionRequest, ActionResponse actionResponse)
234                    throws Exception {
235    
236                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
237                            WebKeys.THEME_DISPLAY);
238    
239                    long roleId = ParamUtil.getLong(actionRequest, "roleId");
240    
241                    Role role = RoleLocalServiceUtil.getRole(roleId);
242    
243                    String roleName = role.getName();
244    
245                    if (roleName.equals(RoleConstants.ADMINISTRATOR) ||
246                            roleName.equals(RoleConstants.ORGANIZATION_ADMINISTRATOR) ||
247                            roleName.equals(RoleConstants.ORGANIZATION_OWNER) ||
248                            roleName.equals(RoleConstants.OWNER) ||
249                            roleName.equals(RoleConstants.SITE_ADMINISTRATOR) ||
250                            roleName.equals(RoleConstants.SITE_OWNER)) {
251    
252                            throw new RolePermissionsException(roleName);
253                    }
254    
255                    String portletResource = ParamUtil.getString(
256                            actionRequest, "portletResource");
257                    String[] modelResources = StringUtil.split(
258                            ParamUtil.getString(actionRequest, "modelResources"));
259                    boolean showModelResources = ParamUtil.getBoolean(
260                            actionRequest, "showModelResources");
261    
262                    Map<String, List<String>> resourceActionsMap =
263                            new HashMap<String, List<String>>();
264    
265                    if (showModelResources) {
266                            for (String modelResource : modelResources) {
267                                    resourceActionsMap.put(
268                                            modelResource,
269                                            ResourceActionsUtil.getResourceActions(
270                                                    null, modelResource));
271                            }
272                    }
273                    else if (Validator.isNotNull(portletResource)) {
274                            resourceActionsMap.put(
275                                    portletResource,
276                                    ResourceActionsUtil.getResourceActions(portletResource, null));
277                    }
278    
279                    String[] selectedTargets = StringUtil.split(
280                            ParamUtil.getString(actionRequest, "selectedTargets"));
281    
282                    for (Map.Entry<String, List<String>> entry :
283                                    resourceActionsMap.entrySet()) {
284    
285                            String selResource = entry.getKey();
286                            List<String> actions = entry.getValue();
287    
288                            actions = ListUtil.sort(
289                                    actions, new ActionComparator(themeDisplay.getLocale()));
290    
291                            for (String actionId : actions) {
292                                    String target = selResource + actionId;
293    
294                                    boolean selected = ArrayUtil.contains(selectedTargets, target);
295    
296                                    String[] groupIds = StringUtil.split(
297                                            ParamUtil.getString(actionRequest, "groupIds" + target));
298    
299                                    groupIds = ArrayUtil.distinct(groupIds);
300    
301                                    int scope = ResourceConstants.SCOPE_COMPANY;
302    
303                                    if ((role.getType() == RoleConstants.TYPE_ORGANIZATION) ||
304                                            (role.getType() == RoleConstants.TYPE_PROVIDER) ||
305                                            (role.getType() == RoleConstants.TYPE_SITE)) {
306    
307                                            scope = ResourceConstants.SCOPE_GROUP_TEMPLATE;
308                                    }
309                                    else {
310                                            if (groupIds.length > 0) {
311                                                    scope = ResourceConstants.SCOPE_GROUP;
312                                            }
313                                    }
314    
315                                    if (ResourceBlockLocalServiceUtil.isSupported(selResource)) {
316                                            updateActions_Blocks(
317                                                    role, themeDisplay.getScopeGroupId(), selResource,
318                                                    actionId, selected, scope, groupIds);
319                                    }
320                                    else {
321                                            updateAction(
322                                                    role, themeDisplay.getScopeGroupId(), selResource,
323                                                    actionId, selected, scope, groupIds);
324                                    }
325                            }
326                    }
327    
328                    // Send redirect
329    
330                    SessionMessages.add(actionRequest, "permissionsUpdated");
331    
332                    String redirect = PortalUtil.escapeRedirect(
333                            ParamUtil.getString(actionRequest, "redirect"));
334    
335                    if (Validator.isNotNull(redirect)) {
336                            redirect = redirect + "&" + Constants.CMD + "=" + Constants.VIEW;
337    
338                            actionResponse.sendRedirect(redirect);
339                    }
340            }
341    
342            protected void updateActions_Blocks(
343                            Role role, long scopeGroupId, String selResource, String actionId,
344                            boolean selected, int scope, String[] groupIds)
345                    throws Exception {
346    
347                    long companyId = role.getCompanyId();
348                    long roleId = role.getRoleId();
349    
350                    if (selected) {
351                            if (scope == ResourceConstants.SCOPE_GROUP) {
352                                    ResourceBlockServiceUtil.removeAllGroupScopePermissions(
353                                            scopeGroupId, companyId, selResource, roleId, actionId);
354                                    ResourceBlockServiceUtil.removeCompanyScopePermission(
355                                            scopeGroupId, companyId, selResource, roleId, actionId);
356    
357                                    for (String groupId : groupIds) {
358                                            ResourceBlockServiceUtil.addGroupScopePermission(
359                                                    scopeGroupId, companyId, GetterUtil.getLong(groupId),
360                                                    selResource, roleId, actionId);
361                                    }
362                            }
363                            else {
364                                    ResourceBlockServiceUtil.removeAllGroupScopePermissions(
365                                            scopeGroupId, companyId, selResource, roleId, actionId);
366                                    ResourceBlockServiceUtil.addCompanyScopePermission(
367                                            scopeGroupId, companyId, selResource, roleId, actionId);
368                            }
369                    }
370                    else {
371                            ResourceBlockServiceUtil.removeAllGroupScopePermissions(
372                                    scopeGroupId, companyId, selResource, roleId, actionId);
373                            ResourceBlockServiceUtil.removeCompanyScopePermission(
374                                    scopeGroupId, companyId, selResource, roleId, actionId);
375                    }
376            }
377    
378    }