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.portletconfiguration.action;
016    
017    import com.liferay.portal.kernel.servlet.SessionErrors;
018    import com.liferay.portal.kernel.util.GetterUtil;
019    import com.liferay.portal.kernel.util.ParamUtil;
020    import com.liferay.portal.kernel.util.StringUtil;
021    import com.liferay.portal.kernel.util.Validator;
022    import com.liferay.portal.model.Layout;
023    import com.liferay.portal.model.PersistedModel;
024    import com.liferay.portal.model.Portlet;
025    import com.liferay.portal.model.PortletConstants;
026    import com.liferay.portal.security.auth.PrincipalException;
027    import com.liferay.portal.security.permission.PermissionPropagator;
028    import com.liferay.portal.service.LayoutLocalServiceUtil;
029    import com.liferay.portal.service.PermissionServiceUtil;
030    import com.liferay.portal.service.PersistedModelLocalService;
031    import com.liferay.portal.service.PersistedModelLocalServiceRegistryUtil;
032    import com.liferay.portal.service.PortletLocalServiceUtil;
033    import com.liferay.portal.service.ResourceBlockLocalServiceUtil;
034    import com.liferay.portal.service.ResourceBlockServiceUtil;
035    import com.liferay.portal.service.ResourcePermissionServiceUtil;
036    import com.liferay.portal.servlet.filters.cache.CacheUtil;
037    import com.liferay.portal.struts.PortletAction;
038    import com.liferay.portal.theme.ThemeDisplay;
039    import com.liferay.portal.util.PropsValues;
040    import com.liferay.portal.util.WebKeys;
041    import com.liferay.portlet.StrictPortletPreferencesImpl;
042    import com.liferay.portlet.blogs.model.BlogsEntry;
043    import com.liferay.portlet.blogs.service.BlogsEntryLocalServiceUtil;
044    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
045    import com.liferay.portlet.documentlibrary.model.DLFileVersion;
046    import com.liferay.portlet.documentlibrary.service.DLFileVersionLocalServiceUtil;
047    import com.liferay.portlet.portletconfiguration.util.ConfigurationActionRequest;
048    import com.liferay.portlet.portletconfiguration.util.ConfigurationRenderRequest;
049    
050    import java.util.ArrayList;
051    import java.util.Date;
052    import java.util.Enumeration;
053    import java.util.HashMap;
054    import java.util.List;
055    import java.util.Map;
056    
057    import javax.portlet.ActionRequest;
058    import javax.portlet.ActionResponse;
059    import javax.portlet.PortletConfig;
060    import javax.portlet.RenderRequest;
061    import javax.portlet.RenderResponse;
062    
063    import org.apache.struts.action.ActionForm;
064    import org.apache.struts.action.ActionForward;
065    import org.apache.struts.action.ActionMapping;
066    
067    /**
068     * @author Brian Wing Shun Chan
069     * @author Connor McKay
070     */
071    public class EditPermissionsAction extends PortletAction {
072    
073            @Override
074            public void processAction(
075                            ActionMapping actionMapping, ActionForm actionForm,
076                            PortletConfig portletConfig, ActionRequest actionRequest,
077                            ActionResponse actionResponse)
078                    throws Exception {
079    
080                    try {
081                            actionRequest = new ConfigurationActionRequest(
082                                    actionRequest, new StrictPortletPreferencesImpl());
083    
084                            updateRolePermissions(actionRequest);
085    
086                            addSuccessMessage(actionRequest, actionResponse);
087                    }
088                    catch (Exception e) {
089                            if (e instanceof PrincipalException) {
090                                    SessionErrors.add(actionRequest, e.getClass());
091    
092                                    setForward(
093                                            actionRequest, "portlet.portlet_configuration.error");
094                            }
095                            else {
096                                    throw e;
097                            }
098                    }
099            }
100    
101            @Override
102            public ActionForward render(
103                            ActionMapping actionMapping, ActionForm actionForm,
104                            PortletConfig portletConfig, RenderRequest renderRequest,
105                            RenderResponse renderResponse)
106                    throws Exception {
107    
108                    renderRequest = new ConfigurationRenderRequest(
109                            renderRequest, new StrictPortletPreferencesImpl());
110    
111                    ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
112                            WebKeys.THEME_DISPLAY);
113    
114                    long groupId = ParamUtil.getLong(
115                            renderRequest, "resourceGroupId", themeDisplay.getScopeGroupId());
116    
117                    String portletResource = ParamUtil.getString(
118                            renderRequest, "portletResource");
119                    String modelResource = ParamUtil.getString(
120                            renderRequest, "modelResource");
121                    String resourcePrimKey = ParamUtil.getString(
122                            renderRequest, "resourcePrimKey");
123    
124                    String selResource = portletResource;
125    
126                    if (Validator.isNotNull(modelResource)) {
127                            selResource = modelResource;
128                    }
129    
130                    try {
131                            PermissionServiceUtil.checkPermission(
132                                    groupId, selResource, resourcePrimKey);
133                    }
134                    catch (PrincipalException pe) {
135                            SessionErrors.add(
136                                    renderRequest, PrincipalException.class.getName());
137    
138                            return actionMapping.findForward(
139                                    "portlet.portlet_configuration.error");
140                    }
141    
142                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
143                            themeDisplay.getCompanyId(), portletResource);
144    
145                    if (portlet != null) {
146                            renderResponse.setTitle(
147                                    ActionUtil.getTitle(portlet, renderRequest));
148                    }
149    
150                    return actionMapping.findForward(
151                            getForward(
152                                    renderRequest,
153                                    "portlet.portlet_configuration.edit_permissions"));
154            }
155    
156            protected String[] getActionIds(
157                    ActionRequest actionRequest, long roleId, boolean includePreselected) {
158    
159                    List<String> actionIds = getActionIdsList(
160                            actionRequest, roleId, includePreselected);
161    
162                    return actionIds.toArray(new String[actionIds.size()]);
163            }
164    
165            protected List<String> getActionIdsList(
166                    ActionRequest actionRequest, long roleId, boolean includePreselected) {
167    
168                    List<String> actionIds = new ArrayList<String>();
169    
170                    Enumeration<String> enu = actionRequest.getParameterNames();
171    
172                    while (enu.hasMoreElements()) {
173                            String name = enu.nextElement();
174    
175                            if (name.startsWith(roleId + ActionUtil.ACTION)) {
176                                    int pos = name.indexOf(ActionUtil.ACTION);
177    
178                                    String actionId = name.substring(
179                                            pos + ActionUtil.ACTION.length());
180    
181                                    actionIds.add(actionId);
182                            }
183                            else if (includePreselected &&
184                                             name.startsWith(roleId + ActionUtil.PRESELECTED)) {
185    
186                                    int pos = name.indexOf(ActionUtil.PRESELECTED);
187    
188                                    String actionId = name.substring(
189                                            pos + ActionUtil.PRESELECTED.length());
190    
191                                    actionIds.add(actionId);
192                            }
193                    }
194    
195                    return actionIds;
196            }
197    
198            protected void updateLayoutModifiedDate(
199                            String selResource, String resourcePrimKey)
200                    throws Exception {
201    
202                    long plid = 0;
203    
204                    int pos = resourcePrimKey.indexOf(PortletConstants.LAYOUT_SEPARATOR);
205    
206                    if (pos != -1) {
207                            plid = GetterUtil.getLong(resourcePrimKey.substring(0, pos));
208                    }
209                    else if (selResource.equals(Layout.class.getName())) {
210                            plid = GetterUtil.getLong(resourcePrimKey);
211                    }
212    
213                    if (plid <= 0) {
214                            return;
215                    }
216    
217                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
218    
219                    if (layout != null) {
220                            layout.setModifiedDate(new Date());
221    
222                            LayoutLocalServiceUtil.updateLayout(layout);
223    
224                            CacheUtil.clearCache(layout.getCompanyId());
225                    }
226            }
227    
228            protected void updateModifiedDate(String className, String classPK)
229                    throws Exception {
230    
231                    PersistedModelLocalService persistedModelLocalService =
232                            PersistedModelLocalServiceRegistryUtil.
233                                    getPersistedModelLocalService(className);
234    
235                    PersistedModel persistedModel =
236                            persistedModelLocalService.getPersistedModel(Long.valueOf(classPK));
237    
238                    if (persistedModel instanceof DLFileEntry) {
239                            DLFileEntry dlFileEntry = (DLFileEntry)persistedModel;
240    
241                            DLFileVersion dlFileVersion = dlFileEntry.getFileVersion();
242    
243                            dlFileVersion.setModifiedDate(new Date());
244                            dlFileVersion.setStatusDate(new Date());
245    
246                            DLFileVersionLocalServiceUtil.updateDLFileVersion(dlFileVersion);
247                    }
248                    else if (persistedModel instanceof BlogsEntry) {
249                            BlogsEntry blogsEntry = (BlogsEntry)persistedModel;
250    
251                            blogsEntry.setModifiedDate(new Date());
252    
253                            BlogsEntryLocalServiceUtil.updateBlogsEntry(blogsEntry);
254                    }
255            }
256    
257            protected void updateRolePermissions(ActionRequest actionRequest)
258                    throws Exception {
259    
260                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
261                            WebKeys.THEME_DISPLAY);
262    
263                    String portletResource = ParamUtil.getString(
264                            actionRequest, "portletResource");
265                    String modelResource = ParamUtil.getString(
266                            actionRequest, "modelResource");
267                    long[] roleIds = StringUtil.split(
268                            ParamUtil.getString(
269                                    actionRequest, "rolesSearchContainerPrimaryKeys"), 0L);
270    
271                    String selResource = PortletConstants.getRootPortletId(portletResource);
272    
273                    if (Validator.isNotNull(modelResource)) {
274                            selResource = modelResource;
275                    }
276    
277                    long resourceGroupId = ParamUtil.getLong(
278                            actionRequest, "resourceGroupId", themeDisplay.getScopeGroupId());
279                    String resourcePrimKey = ParamUtil.getString(
280                            actionRequest, "resourcePrimKey");
281    
282                    Map<Long, String[]> roleIdsToActionIds = new HashMap<Long, String[]>();
283    
284                    if (ResourceBlockLocalServiceUtil.isSupported(selResource)) {
285                            for (long roleId : roleIds) {
286                                    List<String> actionIds = getActionIdsList(
287                                            actionRequest, roleId, true);
288    
289                                    roleIdsToActionIds.put(
290                                            roleId, actionIds.toArray(new String[actionIds.size()]));
291                            }
292    
293                            ResourceBlockServiceUtil.setIndividualScopePermissions(
294                                    themeDisplay.getCompanyId(), resourceGroupId, selResource,
295                                    GetterUtil.getLong(resourcePrimKey), roleIdsToActionIds);
296                    }
297                    else {
298                            for (long roleId : roleIds) {
299                                    String[] actionIds = getActionIds(actionRequest, roleId, false);
300    
301                                    roleIdsToActionIds.put(roleId, actionIds);
302                            }
303    
304                            ResourcePermissionServiceUtil.setIndividualResourcePermissions(
305                                    resourceGroupId, themeDisplay.getCompanyId(), selResource,
306                                    resourcePrimKey, roleIdsToActionIds);
307                    }
308    
309                    try {
310                            updateModifiedDate(selResource, resourcePrimKey);
311                    }
312                    catch (Exception e) {
313                    }
314    
315                    updateLayoutModifiedDate(selResource, resourcePrimKey);
316    
317                    if (PropsValues.PERMISSIONS_PROPAGATION_ENABLED) {
318                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
319                                    themeDisplay.getCompanyId(), portletResource);
320    
321                            PermissionPropagator permissionPropagator =
322                                    portlet.getPermissionPropagatorInstance();
323    
324                            if (permissionPropagator != null) {
325                                    permissionPropagator.propagateRolePermissions(
326                                            actionRequest, modelResource, resourcePrimKey, roleIds);
327                            }
328                    }
329            }
330    
331    }