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.portal.lar;
016    
017    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
018    import com.liferay.portal.kernel.lar.PortletDataContext;
019    import com.liferay.portal.kernel.util.CharPool;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.kernel.util.KeyValuePair;
022    import com.liferay.portal.kernel.util.PrimitiveLongList;
023    import com.liferay.portal.kernel.util.StringUtil;
024    import com.liferay.portal.kernel.xml.Document;
025    import com.liferay.portal.kernel.xml.Element;
026    import com.liferay.portal.kernel.xml.SAXReaderUtil;
027    import com.liferay.portal.model.Layout;
028    import com.liferay.portal.model.PortletConstants;
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.model.User;
033    import com.liferay.portal.security.permission.ResourceActionsUtil;
034    import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
035    import com.liferay.portal.service.RoleLocalServiceUtil;
036    import com.liferay.portal.service.permission.PortletPermissionUtil;
037    
038    import java.util.HashMap;
039    import java.util.List;
040    import java.util.Map;
041    import java.util.Set;
042    
043    /**
044     * @author Brian Wing Shun Chan
045     * @author Joel Kozikowski
046     * @author Charles May
047     * @author Raymond Augé
048     * @author Jorge Ferrer
049     * @author Bruno Farache
050     * @author Zsigmond Rab
051     * @author Douglas Wong
052     */
053    public class PermissionExporter {
054    
055            public static final String ROLE_TEAM_PREFIX = "ROLE_TEAM_,*";
056    
057            protected void exportGroupRoles(
058                            LayoutCache layoutCache, long companyId, long groupId,
059                            String resourceName, String entityName, Element parentElement)
060                    throws Exception {
061    
062                    List<Role> roles = layoutCache.getGroupRoles_1to4(groupId);
063    
064                    Element groupElement = exportRoles(
065                            companyId, resourceName, ResourceConstants.SCOPE_GROUP,
066                            String.valueOf(groupId), parentElement, entityName + "-roles",
067                            roles);
068    
069                    if (groupElement.elements().isEmpty()) {
070                            parentElement.remove(groupElement);
071                    }
072            }
073    
074            protected void exportInheritedRoles(
075                            LayoutCache layoutCache, long companyId, long groupId,
076                            String resourceName, String entityName, Element parentElement)
077                    throws Exception {
078    
079                    Element entityRolesElement = SAXReaderUtil.createElement(
080                            entityName + "-roles");
081    
082                    Map<String, Long> entityMap = layoutCache.getEntityMap(
083                            companyId, entityName);
084    
085                    for (Map.Entry<String, Long> entry : entityMap.entrySet()) {
086                            String name = entry.getKey();
087    
088                            long entityGroupId = entry.getValue();
089    
090                            List<Role> entityRoles = layoutCache.getGroupRoles_1to4(
091                                    entityGroupId);
092    
093                            Element entityElement = exportRoles(
094                                    companyId, resourceName, ResourceConstants.SCOPE_GROUP,
095                                    String.valueOf(groupId), entityRolesElement, entityName,
096                                    entityRoles);
097    
098                            if (entityElement.elements().isEmpty()) {
099                                    entityRolesElement.remove(entityElement);
100                            }
101                            else {
102                                    entityElement.addAttribute("name", name);
103                            }
104                    }
105    
106                    if (!entityRolesElement.elements().isEmpty()) {
107                            parentElement.add(entityRolesElement);
108                    }
109            }
110    
111            protected void exportLayoutPermissions(
112                            PortletDataContext portletDataContext, LayoutCache layoutCache,
113                            long companyId, long groupId, Layout layout, Element layoutElement)
114                    throws Exception {
115    
116                    String resourceName = Layout.class.getName();
117                    String resourcePrimKey = String.valueOf(layout.getPlid());
118    
119                    Element permissionsElement = layoutElement.addElement("permissions");
120    
121                    exportPermissions(
122                            layoutCache, companyId, groupId, resourceName, resourcePrimKey,
123                            permissionsElement, false);
124            }
125    
126            protected void exportLayoutRoles(
127                            LayoutCache layoutCache, long companyId, long groupId,
128                            Element rolesElement)
129                    throws Exception {
130    
131                    String resourceName = Layout.class.getName();
132    
133                    exportGroupRoles(
134                            layoutCache, companyId, groupId, resourceName, "community",
135                            rolesElement);
136    
137                    exportUserRoles(
138                            layoutCache, companyId, groupId, resourceName, rolesElement);
139    
140                    exportInheritedRoles(
141                            layoutCache, companyId, groupId, resourceName, "organization",
142                            rolesElement);
143    
144                    exportInheritedRoles(
145                            layoutCache, companyId, groupId, resourceName, "user-group",
146                            rolesElement);
147            }
148    
149            protected void exportPermissions(
150                            LayoutCache layoutCache, long companyId, long groupId,
151                            String resourceName, String resourcePrimKey,
152                            Element permissionsElement, boolean portletActions)
153                    throws Exception {
154    
155                    List<Role> roles = layoutCache.getGroupRoles_5(groupId, resourceName);
156    
157                    List<String> actionIds = null;
158    
159                    if (portletActions) {
160                            actionIds = ResourceActionsUtil.getPortletResourceActions(
161                                    resourceName);
162                    }
163                    else {
164                            actionIds = ResourceActionsUtil.getModelResourceActions(
165                                    resourceName);
166                    }
167    
168                    if (actionIds.isEmpty()) {
169                            return;
170                    }
171    
172                    PrimitiveLongList roleIds = new PrimitiveLongList(roles.size());
173                    Map<Long, Role> roleIdsToRoles = new HashMap<Long, Role>();
174    
175                    for (Role role : roles) {
176                            String name = role.getName();
177    
178                            if (name.equals(RoleConstants.ADMINISTRATOR)) {
179                                    continue;
180                            }
181    
182                            roleIds.add(role.getRoleId());
183                            roleIdsToRoles.put(role.getRoleId(), role);
184                    }
185    
186                    Map<Long, Set<String>> roleIdsToActionIds =
187                            ResourcePermissionLocalServiceUtil.
188                                    getAvailableResourcePermissionActionIds(
189                                            companyId, resourceName, ResourceConstants.SCOPE_INDIVIDUAL,
190                                            resourcePrimKey, roleIds.getArray(), actionIds);
191    
192                    for (Role role : roleIdsToRoles.values()) {
193                            Set<String> availableActionIds = roleIdsToActionIds.get(
194                                    role.getRoleId());
195    
196                            Element roleElement = permissionsElement.addElement("role");
197    
198                            roleElement.addAttribute("name", role.getName());
199                            roleElement.addAttribute("title", role.getTitle());
200                            roleElement.addAttribute("description", role.getDescription());
201                            roleElement.addAttribute("type", String.valueOf(role.getType()));
202                            roleElement.addAttribute("subType", role.getSubtype());
203    
204                            if ((availableActionIds == null) || availableActionIds.isEmpty()) {
205                                    continue;
206                            }
207    
208                            for (String action : availableActionIds) {
209                                    Element actionKeyElement = roleElement.addElement("action-key");
210    
211                                    actionKeyElement.addText(action);
212                            }
213                    }
214            }
215    
216            protected void exportPortletDataPermissions(
217                            PortletDataContext portletDataContext)
218                    throws Exception {
219    
220                    Document document = SAXReaderUtil.createDocument();
221    
222                    Element rootElement = document.addElement("portlet-data-permissions");
223    
224                    Map<String, List<KeyValuePair>> permissionsMap =
225                            portletDataContext.getPermissions();
226    
227                    for (Map.Entry<String, List<KeyValuePair>> entry :
228                                    permissionsMap.entrySet()) {
229    
230                            String[] permissionParts = StringUtil.split(
231                                    entry.getKey(), CharPool.POUND);
232    
233                            String resourceName = permissionParts[0];
234                            long resourcePK = GetterUtil.getLong(permissionParts[1]);
235    
236                            Element portletDataElement = rootElement.addElement("portlet-data");
237    
238                            portletDataElement.addAttribute("resource-name", resourceName);
239                            portletDataElement.addAttribute(
240                                    "resource-pk", String.valueOf(resourcePK));
241    
242                            List<KeyValuePair> permissions = entry.getValue();
243    
244                            for (KeyValuePair permission : permissions) {
245                                    String roleName = permission.getKey();
246                                    String actions = permission.getValue();
247    
248                                    Element permissionsElement = portletDataElement.addElement(
249                                            "permissions");
250    
251                                    permissionsElement.addAttribute("role-name", roleName);
252                                    permissionsElement.addAttribute("actions", actions);
253                            }
254                    }
255    
256                    portletDataContext.addZipEntry(
257                            ExportImportPathUtil.getRootPath(portletDataContext) +
258                                    "/portlet-data-permissions.xml",
259                            document.formattedString());
260            }
261    
262            protected void exportPortletPermissions(
263                            PortletDataContext portletDataContext, LayoutCache layoutCache,
264                            String portletId, Layout layout, Element portletElement)
265                    throws Exception {
266    
267                    long companyId = portletDataContext.getCompanyId();
268                    long groupId = portletDataContext.getGroupId();
269    
270                    String resourceName = PortletConstants.getRootPortletId(portletId);
271                    String resourcePrimKey = PortletPermissionUtil.getPrimaryKey(
272                            layout.getPlid(), portletId);
273    
274                    Element permissionsElement = portletElement.addElement("permissions");
275    
276                    exportPermissions(
277                            layoutCache, companyId, groupId, resourceName, resourcePrimKey,
278                            permissionsElement, true);
279            }
280    
281            protected void exportPortletRoles(
282                            LayoutCache layoutCache, long companyId, long groupId,
283                            String portletId, Element rolesElement)
284                    throws Exception {
285    
286                    String resourceName = PortletConstants.getRootPortletId(portletId);
287    
288                    Element portletElement = rolesElement.addElement("portlet");
289    
290                    portletElement.addAttribute("portlet-id", portletId);
291    
292                    exportGroupRoles(
293                            layoutCache, companyId, groupId, resourceName, "community",
294                            portletElement);
295    
296                    exportUserRoles(
297                            layoutCache, companyId, groupId, resourceName, portletElement);
298    
299                    exportInheritedRoles(
300                            layoutCache, companyId, groupId, resourceName, "organization",
301                            portletElement);
302    
303                    exportInheritedRoles(
304                            layoutCache, companyId, groupId, resourceName, "user-group",
305                            portletElement);
306    
307                    if (portletElement.elements().isEmpty()) {
308                            rolesElement.remove(portletElement);
309                    }
310            }
311    
312            protected Element exportRoles(
313                            long companyId, String resourceName, int scope,
314                            String resourcePrimKey, Element parentElement, String elName,
315                            List<Role> roles)
316                    throws Exception {
317    
318                    Element element = parentElement.addElement(elName);
319    
320                    Map<String, List<String>> resourceRoles =
321                            RoleLocalServiceUtil.getResourceRoles(
322                                    companyId, resourceName, scope, resourcePrimKey);
323    
324                    for (Map.Entry<String, List<String>> entry : resourceRoles.entrySet()) {
325                            String roleName = entry.getKey();
326    
327                            if (!hasRole(roles, roleName)) {
328                                    continue;
329                            }
330    
331                            Element roleElement = element.addElement("role");
332    
333                            roleElement.addAttribute("name", roleName);
334    
335                            List<String> actions = entry.getValue();
336    
337                            for (String action : actions) {
338                                    Element actionKeyElement = roleElement.addElement("action-key");
339    
340                                    actionKeyElement.addText(action);
341                                    actionKeyElement.addAttribute("scope", String.valueOf(scope));
342                            }
343                    }
344    
345                    return element;
346            }
347    
348            protected void exportUserRoles(
349                            LayoutCache layoutCache, long companyId, long groupId,
350                            String resourceName, Element parentElement)
351                    throws Exception {
352    
353                    Element userRolesElement = SAXReaderUtil.createElement("user-roles");
354    
355                    List<User> users = layoutCache.getGroupUsers(groupId);
356    
357                    for (User user : users) {
358                            long userId = user.getUserId();
359                            String uuid = user.getUuid();
360    
361                            List<Role> userRoles = layoutCache.getUserRoles(userId);
362    
363                            Element userElement = exportRoles(
364                                    companyId, resourceName, ResourceConstants.SCOPE_GROUP,
365                                    String.valueOf(groupId), userRolesElement, "user", userRoles);
366    
367                            if (userElement.elements().isEmpty()) {
368                                    userRolesElement.remove(userElement);
369                            }
370                            else {
371                                    userElement.addAttribute("uuid", uuid);
372                            }
373                    }
374    
375                    if (!userRolesElement.elements().isEmpty()) {
376                            parentElement.add(userRolesElement);
377                    }
378            }
379    
380            protected boolean hasRole(List<Role> roles, String roleName) {
381                    if ((roles == null) || (roles.size() == 0)) {
382                            return false;
383                    }
384    
385                    for (Role role : roles) {
386                            if (roleName.equals(role.getName())) {
387                                    return true;
388                            }
389                    }
390    
391                    return false;
392            }
393    
394    }