001    /**
002     * Copyright (c) 2000-present 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.Group;
029    import com.liferay.portal.model.GroupConstants;
030    import com.liferay.portal.model.Portlet;
031    import com.liferay.portal.model.ResourceConstants;
032    import com.liferay.portal.model.Role;
033    import com.liferay.portal.model.RoleConstants;
034    import com.liferay.portal.security.auth.PrincipalException;
035    import com.liferay.portal.security.permission.ActionKeys;
036    import com.liferay.portal.security.permission.ResourceActionsUtil;
037    import com.liferay.portal.security.permission.comparator.ActionComparator;
038    import com.liferay.portal.service.PortletLocalServiceUtil;
039    import com.liferay.portal.service.ResourceBlockLocalServiceUtil;
040    import com.liferay.portal.service.ResourceBlockServiceUtil;
041    import com.liferay.portal.service.ResourcePermissionServiceUtil;
042    import com.liferay.portal.service.RoleLocalServiceUtil;
043    import com.liferay.portal.struts.PortletAction;
044    import com.liferay.portal.theme.ThemeDisplay;
045    import com.liferay.portal.util.PortalUtil;
046    import com.liferay.portal.util.PortletCategoryKeys;
047    import com.liferay.portal.util.PortletKeys;
048    import com.liferay.portal.util.WebKeys;
049    
050    import java.util.HashMap;
051    import java.util.List;
052    import java.util.Map;
053    
054    import javax.portlet.ActionRequest;
055    import javax.portlet.ActionResponse;
056    import javax.portlet.PortletConfig;
057    import javax.portlet.PortletContext;
058    import javax.portlet.PortletRequestDispatcher;
059    import javax.portlet.RenderRequest;
060    import javax.portlet.RenderResponse;
061    import javax.portlet.ResourceRequest;
062    import javax.portlet.ResourceResponse;
063    
064    import org.apache.struts.action.ActionForm;
065    import org.apache.struts.action.ActionForward;
066    import org.apache.struts.action.ActionMapping;
067    
068    /**
069     * @author Brian Wing Shun Chan
070     * @author Jorge Ferrer
071     * @author Connor McKay
072     */
073    public class EditRolePermissionsAction extends PortletAction {
074    
075            @Override
076            public void processAction(
077                            ActionMapping actionMapping, ActionForm actionForm,
078                            PortletConfig portletConfig, ActionRequest actionRequest,
079                            ActionResponse actionResponse)
080                    throws Exception {
081    
082                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
083    
084                    try {
085                            if (cmd.equals("actions")) {
086                                    updateActions(actionRequest, actionResponse);
087                            }
088                            else if (cmd.equals("delete_permission")) {
089                                    deletePermission(actionRequest, actionResponse);
090                            }
091                    }
092                    catch (Exception e) {
093                            if (e instanceof NoSuchRoleException ||
094                                    e instanceof PrincipalException ||
095                                    e instanceof RolePermissionsException) {
096    
097                                    SessionErrors.add(actionRequest, e.getClass());
098    
099                                    setForward(actionRequest, "portlet.roles_admin.error");
100                            }
101                            else {
102                                    throw e;
103                            }
104                    }
105            }
106    
107            @Override
108            public ActionForward render(
109                            ActionMapping actionMapping, ActionForm actionForm,
110                            PortletConfig portletConfig, RenderRequest renderRequest,
111                            RenderResponse renderResponse)
112                    throws Exception {
113    
114                    try {
115                            ActionUtil.getRole(renderRequest);
116                    }
117                    catch (Exception e) {
118                            if (e instanceof NoSuchRoleException ||
119                                    e instanceof PrincipalException) {
120    
121                                    SessionErrors.add(renderRequest, e.getClass());
122    
123                                    return actionMapping.findForward("portlet.roles_admin.error");
124                            }
125                            else {
126                                    throw e;
127                            }
128                    }
129    
130                    return actionMapping.findForward(
131                            getForward(
132                                    renderRequest, "portlet.roles_admin.edit_role_permissions"));
133            }
134    
135            @Override
136            public void serveResource(
137                            ActionMapping actionMapping, ActionForm actionForm,
138                            PortletConfig portletConfig, ResourceRequest resourceRequest,
139                            ResourceResponse resourceResponse)
140                    throws Exception {
141    
142                    PortletContext portletContext = portletConfig.getPortletContext();
143    
144                    PortletRequestDispatcher portletRequestDispatcher =
145                            portletContext.getRequestDispatcher(
146                                    "/html/portlet/roles_admin/view_resources.jsp");
147    
148                    ActionUtil.getRole(resourceRequest);
149    
150                    portletRequestDispatcher.include(resourceRequest, resourceResponse);
151            }
152    
153            protected void deletePermission(
154                            ActionRequest actionRequest, ActionResponse actionResponse)
155                    throws Exception {
156    
157                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
158                            WebKeys.THEME_DISPLAY);
159    
160                    long roleId = ParamUtil.getLong(actionRequest, "roleId");
161                    String name = ParamUtil.getString(actionRequest, "name");
162                    int scope = ParamUtil.getInteger(actionRequest, "scope");
163                    String primKey = ParamUtil.getString(actionRequest, "primKey");
164                    String actionId = ParamUtil.getString(actionRequest, "actionId");
165    
166                    Role role = RoleLocalServiceUtil.getRole(roleId);
167    
168                    String roleName = role.getName();
169    
170                    if (roleName.equals(RoleConstants.ADMINISTRATOR) ||
171                            roleName.equals(RoleConstants.ORGANIZATION_ADMINISTRATOR) ||
172                            roleName.equals(RoleConstants.ORGANIZATION_OWNER) ||
173                            roleName.equals(RoleConstants.OWNER) ||
174                            roleName.equals(RoleConstants.SITE_ADMINISTRATOR) ||
175                            roleName.equals(RoleConstants.SITE_OWNER)) {
176    
177                            throw new RolePermissionsException(roleName);
178                    }
179    
180                    if (ResourceBlockLocalServiceUtil.isSupported(name)) {
181                            if (scope == ResourceConstants.SCOPE_GROUP) {
182                                    ResourceBlockServiceUtil.removeGroupScopePermission(
183                                            themeDisplay.getScopeGroupId(), themeDisplay.getCompanyId(),
184                                            GetterUtil.getLong(primKey), name, roleId, actionId);
185                            }
186                            else {
187                                    ResourceBlockServiceUtil.removeCompanyScopePermission(
188                                            themeDisplay.getScopeGroupId(), themeDisplay.getCompanyId(),
189                                            name, roleId, actionId);
190                            }
191                    }
192                    else {
193                            ResourcePermissionServiceUtil.removeResourcePermission(
194                                    themeDisplay.getScopeGroupId(), themeDisplay.getCompanyId(),
195                                    name, scope, primKey, roleId, actionId);
196                    }
197    
198                    // Send redirect
199    
200                    SessionMessages.add(actionRequest, "permissionDeleted");
201    
202                    String redirect = PortalUtil.escapeRedirect(
203                            ParamUtil.getString(actionRequest, "redirect"));
204    
205                    if (Validator.isNotNull(redirect)) {
206                            actionResponse.sendRedirect(redirect);
207                    }
208            }
209    
210            protected void updateAction(
211                            Role role, long groupId, String selResource, String actionId,
212                            boolean selected, int scope, String[] groupIds)
213                    throws Exception {
214    
215                    long companyId = role.getCompanyId();
216                    long roleId = role.getRoleId();
217    
218                    if (selected) {
219                            if (scope == ResourceConstants.SCOPE_COMPANY) {
220                                    ResourcePermissionServiceUtil.addResourcePermission(
221                                            groupId, companyId, selResource, scope,
222                                            String.valueOf(role.getCompanyId()), roleId, actionId);
223                            }
224                            else if (scope == ResourceConstants.SCOPE_GROUP_TEMPLATE) {
225                                    ResourcePermissionServiceUtil.addResourcePermission(
226                                            groupId, companyId, selResource,
227                                            ResourceConstants.SCOPE_GROUP_TEMPLATE,
228                                            String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID),
229                                            roleId, actionId);
230                            }
231                            else if (scope == ResourceConstants.SCOPE_GROUP) {
232                                    ResourcePermissionServiceUtil.removeResourcePermissions(
233                                            groupId, companyId, selResource,
234                                            ResourceConstants.SCOPE_GROUP, roleId, actionId);
235    
236                                    for (String curGroupId : groupIds) {
237                                            ResourcePermissionServiceUtil.addResourcePermission(
238                                                    groupId, companyId, selResource,
239                                                    ResourceConstants.SCOPE_GROUP, curGroupId, roleId,
240                                                    actionId);
241                                    }
242                            }
243                    }
244                    else {
245    
246                            // Remove company, group template, and group permissions
247    
248                            ResourcePermissionServiceUtil.removeResourcePermissions(
249                                    groupId, companyId, selResource,
250                                    ResourceConstants.SCOPE_COMPANY, roleId, actionId);
251    
252                            ResourcePermissionServiceUtil.removeResourcePermissions(
253                                    groupId, companyId, selResource,
254                                    ResourceConstants.SCOPE_GROUP_TEMPLATE, roleId, actionId);
255    
256                            ResourcePermissionServiceUtil.removeResourcePermissions(
257                                    groupId, companyId, selResource, ResourceConstants.SCOPE_GROUP,
258                                    roleId, actionId);
259                    }
260            }
261    
262            protected void updateActions(
263                            ActionRequest actionRequest, ActionResponse actionResponse)
264                    throws Exception {
265    
266                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
267                            WebKeys.THEME_DISPLAY);
268    
269                    long roleId = ParamUtil.getLong(actionRequest, "roleId");
270    
271                    Role role = RoleLocalServiceUtil.getRole(roleId);
272    
273                    String roleName = role.getName();
274    
275                    if (roleName.equals(RoleConstants.ADMINISTRATOR) ||
276                            roleName.equals(RoleConstants.ORGANIZATION_ADMINISTRATOR) ||
277                            roleName.equals(RoleConstants.ORGANIZATION_OWNER) ||
278                            roleName.equals(RoleConstants.OWNER) ||
279                            roleName.equals(RoleConstants.SITE_ADMINISTRATOR) ||
280                            roleName.equals(RoleConstants.SITE_OWNER)) {
281    
282                            throw new RolePermissionsException(roleName);
283                    }
284    
285                    String portletResource = ParamUtil.getString(
286                            actionRequest, "portletResource");
287                    String[] relatedPortletResources = StringUtil.split(
288                            ParamUtil.getString(actionRequest, "relatedPortletResources"));
289                    String[] modelResources = StringUtil.split(
290                            ParamUtil.getString(actionRequest, "modelResources"));
291    
292                    Map<String, List<String>> resourceActionsMap =
293                            new HashMap<String, List<String>>();
294    
295                    if (Validator.isNotNull(portletResource)) {
296                            resourceActionsMap.put(
297                                    portletResource,
298                                    ResourceActionsUtil.getResourceActions(portletResource, null));
299                    }
300    
301                    for (String relatedPortletResource : relatedPortletResources) {
302                            resourceActionsMap.put(
303                                    relatedPortletResource,
304                                    ResourceActionsUtil.getResourceActions(
305                                            relatedPortletResource, null));
306                    }
307    
308                    for (String modelResource : modelResources) {
309                            resourceActionsMap.put(
310                                    modelResource,
311                                    ResourceActionsUtil.getResourceActions(null, modelResource));
312                    }
313    
314                    int rootResourceScope = ResourceConstants.SCOPE_COMPANY;
315                    String[] rootResourceGroupIds = null;
316    
317                    String[] selectedTargets = StringUtil.split(
318                            ParamUtil.getString(actionRequest, "selectedTargets"));
319    
320                    for (Map.Entry<String, List<String>> entry :
321                                    resourceActionsMap.entrySet()) {
322    
323                            String selResource = entry.getKey();
324                            List<String> actions = entry.getValue();
325    
326                            actions = ListUtil.sort(
327                                    actions, new ActionComparator(themeDisplay.getLocale()));
328    
329                            for (String actionId : actions) {
330                                    String target = selResource + actionId;
331    
332                                    boolean selected = ArrayUtil.contains(selectedTargets, target);
333    
334                                    String[] groupIds = StringUtil.split(
335                                            ParamUtil.getString(actionRequest, "groupIds" + target));
336    
337                                    groupIds = ArrayUtil.distinct(groupIds);
338    
339                                    int scope = ResourceConstants.SCOPE_COMPANY;
340    
341                                    if ((role.getType() == RoleConstants.TYPE_ORGANIZATION) ||
342                                            (role.getType() == RoleConstants.TYPE_PROVIDER) ||
343                                            (role.getType() == RoleConstants.TYPE_SITE)) {
344    
345                                            scope = ResourceConstants.SCOPE_GROUP_TEMPLATE;
346                                    }
347                                    else {
348                                            if (groupIds.length > 0) {
349                                                    scope = ResourceConstants.SCOPE_GROUP;
350                                            }
351                                    }
352    
353                                    if (ResourceBlockLocalServiceUtil.isSupported(selResource)) {
354                                            updateActions_Blocks(
355                                                    role, themeDisplay.getScopeGroupId(), selResource,
356                                                    actionId, selected, scope, groupIds);
357                                    }
358                                    else {
359                                            updateAction(
360                                                    role, themeDisplay.getScopeGroupId(), selResource,
361                                                    actionId, selected, scope, groupIds);
362                                    }
363    
364                                    if (selected &&
365                                            (scope == ResourceConstants.SCOPE_COMPANY) &&
366                                            actionId.equals(ActionKeys.ACCESS_IN_CONTROL_PANEL)) {
367    
368                                            updateViewControlPanelPermission(
369                                                    role, themeDisplay.getScopeGroupId(), selResource,
370                                                    scope, groupIds);
371    
372                                            rootResourceScope = scope;
373                                            rootResourceGroupIds = groupIds;
374                                    }
375                            }
376                    }
377    
378                    // LPS-38031
379    
380                    if (rootResourceGroupIds != null) {
381                            updateViewRootResourcePermission(
382                                    role, themeDisplay.getScopeGroupId(), portletResource,
383                                    rootResourceScope, rootResourceGroupIds);
384                    }
385    
386                    // Send redirect
387    
388                    SessionMessages.add(actionRequest, "permissionsUpdated");
389    
390                    String redirect = PortalUtil.escapeRedirect(
391                            ParamUtil.getString(actionRequest, "redirect"));
392    
393                    if (Validator.isNotNull(redirect)) {
394                            actionResponse.sendRedirect(redirect);
395                    }
396            }
397    
398            protected void updateActions_Blocks(
399                            Role role, long scopeGroupId, String selResource, String actionId,
400                            boolean selected, int scope, String[] groupIds)
401                    throws Exception {
402    
403                    long companyId = role.getCompanyId();
404                    long roleId = role.getRoleId();
405    
406                    if (selected) {
407                            if (scope == ResourceConstants.SCOPE_GROUP) {
408                                    ResourceBlockServiceUtil.removeAllGroupScopePermissions(
409                                            scopeGroupId, companyId, selResource, roleId, actionId);
410                                    ResourceBlockServiceUtil.removeCompanyScopePermission(
411                                            scopeGroupId, companyId, selResource, roleId, actionId);
412    
413                                    for (String groupId : groupIds) {
414                                            ResourceBlockServiceUtil.addGroupScopePermission(
415                                                    scopeGroupId, companyId, GetterUtil.getLong(groupId),
416                                                    selResource, roleId, actionId);
417                                    }
418                            }
419                            else {
420                                    ResourceBlockServiceUtil.removeAllGroupScopePermissions(
421                                            scopeGroupId, companyId, selResource, roleId, actionId);
422                                    ResourceBlockServiceUtil.addCompanyScopePermission(
423                                            scopeGroupId, companyId, selResource, roleId, actionId);
424                            }
425                    }
426                    else {
427                            ResourceBlockServiceUtil.removeAllGroupScopePermissions(
428                                    scopeGroupId, companyId, selResource, roleId, actionId);
429                            ResourceBlockServiceUtil.removeCompanyScopePermission(
430                                    scopeGroupId, companyId, selResource, roleId, actionId);
431                    }
432            }
433    
434            protected void updateViewControlPanelPermission(
435                            Role role, long scopeGroupId, String portletId, int scope,
436                            String[] groupIds)
437                    throws Exception {
438    
439                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
440                            role.getCompanyId(), portletId);
441    
442                    String controlPanelCategory = portlet.getControlPanelEntryCategory();
443    
444                    if (Validator.isNull(controlPanelCategory)) {
445                            return;
446                    }
447    
448                    String selResource = null;
449                    String actionId = null;
450    
451                    if (ArrayUtil.contains(PortletCategoryKeys.ALL, controlPanelCategory)) {
452                            selResource = PortletKeys.PORTAL;
453                            actionId = ActionKeys.VIEW_CONTROL_PANEL;
454                    }
455                    else if (ArrayUtil.contains(
456                                            PortletCategoryKeys.SITE_ADMINISTRATION_ALL,
457                                            controlPanelCategory)) {
458    
459                            selResource = Group.class.getName();
460                            actionId = ActionKeys.VIEW_SITE_ADMINISTRATION;
461                    }
462    
463                    if (selResource != null) {
464                            updateAction(
465                                    role, scopeGroupId, selResource, actionId, true, scope,
466                                    groupIds);
467                    }
468            }
469    
470            protected void updateViewRootResourcePermission(
471                            Role role, long scopeGroupId, String portletId, int scope,
472                            String[] groupIds)
473                    throws Exception {
474    
475                    String modelResource = ResourceActionsUtil.getPortletRootModelResource(
476                            portletId);
477    
478                    if (modelResource != null) {
479                            List<String> actions = ResourceActionsUtil.getModelResourceActions(
480                                    modelResource);
481    
482                            if (actions.contains(ActionKeys.VIEW)) {
483                                    updateAction(
484                                            role, scopeGroupId, modelResource, ActionKeys.VIEW, true,
485                                            scope, groupIds);
486                            }
487                    }
488            }
489    
490    }