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 exportLayoutRoles(
112                            LayoutCache layoutCache, long companyId, long groupId,
113                            Element rolesElement)
114                    throws Exception {
115    
116                    String resourceName = Layout.class.getName();
117    
118                    exportGroupRoles(
119                            layoutCache, companyId, groupId, resourceName, "community",
120                            rolesElement);
121    
122                    exportUserRoles(
123                            layoutCache, companyId, groupId, resourceName, rolesElement);
124    
125                    exportInheritedRoles(
126                            layoutCache, companyId, groupId, resourceName, "organization",
127                            rolesElement);
128    
129                    exportInheritedRoles(
130                            layoutCache, companyId, groupId, resourceName, "user-group",
131                            rolesElement);
132            }
133    
134            protected void exportPermissions(
135                            LayoutCache layoutCache, long companyId, long groupId,
136                            String resourceName, String resourcePrimKey,
137                            Element permissionsElement, boolean portletActions)
138                    throws Exception {
139    
140                    List<Role> roles = layoutCache.getGroupRoles_5(groupId, resourceName);
141    
142                    List<String> actionIds = null;
143    
144                    if (portletActions) {
145                            actionIds = ResourceActionsUtil.getPortletResourceActions(
146                                    resourceName);
147                    }
148                    else {
149                            actionIds = ResourceActionsUtil.getModelResourceActions(
150                                    resourceName);
151                    }
152    
153                    if (actionIds.isEmpty()) {
154                            return;
155                    }
156    
157                    PrimitiveLongList roleIds = new PrimitiveLongList(roles.size());
158                    Map<Long, Role> roleIdsToRoles = new HashMap<Long, Role>();
159    
160                    for (Role role : roles) {
161                            String name = role.getName();
162    
163                            if (name.equals(RoleConstants.ADMINISTRATOR)) {
164                                    continue;
165                            }
166    
167                            roleIds.add(role.getRoleId());
168                            roleIdsToRoles.put(role.getRoleId(), role);
169                    }
170    
171                    Map<Long, Set<String>> roleIdsToActionIds =
172                            ResourcePermissionLocalServiceUtil.
173                                    getAvailableResourcePermissionActionIds(
174                                            companyId, resourceName, ResourceConstants.SCOPE_INDIVIDUAL,
175                                            resourcePrimKey, roleIds.getArray(), actionIds);
176    
177                    for (Role role : roleIdsToRoles.values()) {
178                            Set<String> availableActionIds = roleIdsToActionIds.get(
179                                    role.getRoleId());
180    
181                            Element roleElement = permissionsElement.addElement("role");
182    
183                            roleElement.addAttribute("name", role.getName());
184                            roleElement.addAttribute("title", role.getTitle());
185                            roleElement.addAttribute("description", role.getDescription());
186                            roleElement.addAttribute("type", String.valueOf(role.getType()));
187                            roleElement.addAttribute("subtype", role.getSubtype());
188    
189                            if ((availableActionIds == null) || availableActionIds.isEmpty()) {
190                                    continue;
191                            }
192    
193                            for (String action : availableActionIds) {
194                                    Element actionKeyElement = roleElement.addElement("action-key");
195    
196                                    actionKeyElement.addText(action);
197                            }
198                    }
199            }
200    
201            protected void exportPortletDataPermissions(
202                            PortletDataContext portletDataContext)
203                    throws Exception {
204    
205                    Document document = SAXReaderUtil.createDocument();
206    
207                    Element rootElement = document.addElement("portlet-data-permissions");
208    
209                    Map<String, List<KeyValuePair>> permissionsMap =
210                            portletDataContext.getPermissions();
211    
212                    for (Map.Entry<String, List<KeyValuePair>> entry :
213                                    permissionsMap.entrySet()) {
214    
215                            String[] permissionParts = StringUtil.split(
216                                    entry.getKey(), CharPool.POUND);
217    
218                            String resourceName = permissionParts[0];
219                            long resourcePK = GetterUtil.getLong(permissionParts[1]);
220    
221                            Element portletDataElement = rootElement.addElement("portlet-data");
222    
223                            portletDataElement.addAttribute("resource-name", resourceName);
224                            portletDataElement.addAttribute(
225                                    "resource-pk", String.valueOf(resourcePK));
226    
227                            List<KeyValuePair> permissions = entry.getValue();
228    
229                            for (KeyValuePair permission : permissions) {
230                                    String roleName = permission.getKey();
231                                    String actions = permission.getValue();
232    
233                                    Element permissionsElement = portletDataElement.addElement(
234                                            "permissions");
235    
236                                    permissionsElement.addAttribute("role-name", roleName);
237                                    permissionsElement.addAttribute("actions", actions);
238                            }
239                    }
240    
241                    portletDataContext.addZipEntry(
242                            ExportImportPathUtil.getRootPath(portletDataContext) +
243                                    "/portlet-data-permissions.xml",
244                            document.formattedString());
245            }
246    
247            protected void exportPortletPermissions(
248                            PortletDataContext portletDataContext, LayoutCache layoutCache,
249                            String portletId, Layout layout, Element portletElement)
250                    throws Exception {
251    
252                    long companyId = portletDataContext.getCompanyId();
253                    long groupId = portletDataContext.getGroupId();
254    
255                    String resourceName = PortletConstants.getRootPortletId(portletId);
256                    String resourcePrimKey = PortletPermissionUtil.getPrimaryKey(
257                            layout.getPlid(), portletId);
258    
259                    Element permissionsElement = portletElement.addElement("permissions");
260    
261                    exportPermissions(
262                            layoutCache, companyId, groupId, resourceName, resourcePrimKey,
263                            permissionsElement, true);
264            }
265    
266            protected void exportPortletRoles(
267                            LayoutCache layoutCache, long companyId, long groupId,
268                            String portletId, Element rolesElement)
269                    throws Exception {
270    
271                    String resourceName = PortletConstants.getRootPortletId(portletId);
272    
273                    Element portletElement = rolesElement.addElement("portlet");
274    
275                    portletElement.addAttribute("portlet-id", portletId);
276    
277                    exportGroupRoles(
278                            layoutCache, companyId, groupId, resourceName, "community",
279                            portletElement);
280    
281                    exportUserRoles(
282                            layoutCache, companyId, groupId, resourceName, portletElement);
283    
284                    exportInheritedRoles(
285                            layoutCache, companyId, groupId, resourceName, "organization",
286                            portletElement);
287    
288                    exportInheritedRoles(
289                            layoutCache, companyId, groupId, resourceName, "user-group",
290                            portletElement);
291    
292                    if (portletElement.elements().isEmpty()) {
293                            rolesElement.remove(portletElement);
294                    }
295            }
296    
297            protected Element exportRoles(
298                            long companyId, String resourceName, int scope,
299                            String resourcePrimKey, Element parentElement, String elName,
300                            List<Role> roles)
301                    throws Exception {
302    
303                    Element element = parentElement.addElement(elName);
304    
305                    Map<String, List<String>> resourceRoles =
306                            RoleLocalServiceUtil.getResourceRoles(
307                                    companyId, resourceName, scope, resourcePrimKey);
308    
309                    for (Map.Entry<String, List<String>> entry : resourceRoles.entrySet()) {
310                            String roleName = entry.getKey();
311    
312                            if (!hasRole(roles, roleName)) {
313                                    continue;
314                            }
315    
316                            Element roleElement = element.addElement("role");
317    
318                            roleElement.addAttribute("name", roleName);
319    
320                            List<String> actions = entry.getValue();
321    
322                            for (String action : actions) {
323                                    Element actionKeyElement = roleElement.addElement("action-key");
324    
325                                    actionKeyElement.addText(action);
326                                    actionKeyElement.addAttribute("scope", String.valueOf(scope));
327                            }
328                    }
329    
330                    return element;
331            }
332    
333            protected void exportUserRoles(
334                            LayoutCache layoutCache, long companyId, long groupId,
335                            String resourceName, Element parentElement)
336                    throws Exception {
337    
338                    Element userRolesElement = SAXReaderUtil.createElement("user-roles");
339    
340                    List<User> users = layoutCache.getGroupUsers(groupId);
341    
342                    for (User user : users) {
343                            long userId = user.getUserId();
344                            String uuid = user.getUuid();
345    
346                            List<Role> userRoles = layoutCache.getUserRoles(userId);
347    
348                            Element userElement = exportRoles(
349                                    companyId, resourceName, ResourceConstants.SCOPE_GROUP,
350                                    String.valueOf(groupId), userRolesElement, "user", userRoles);
351    
352                            if (userElement.elements().isEmpty()) {
353                                    userRolesElement.remove(userElement);
354                            }
355                            else {
356                                    userElement.addAttribute("uuid", uuid);
357                            }
358                    }
359    
360                    if (!userRolesElement.elements().isEmpty()) {
361                            parentElement.add(userRolesElement);
362                    }
363            }
364    
365            protected boolean hasRole(List<Role> roles, String roleName) {
366                    if ((roles == null) || (roles.size() == 0)) {
367                            return false;
368                    }
369    
370                    for (Role role : roles) {
371                            if (roleName.equals(role.getName())) {
372                                    return true;
373                            }
374                    }
375    
376                    return false;
377            }
378    
379    }