1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.lar;
16  
17  import com.liferay.portal.kernel.exception.PortalException;
18  import com.liferay.portal.kernel.exception.SystemException;
19  import com.liferay.portal.kernel.log.Log;
20  import com.liferay.portal.kernel.log.LogFactoryUtil;
21  import com.liferay.portal.kernel.util.KeyValuePair;
22  import com.liferay.portal.kernel.util.MapUtil;
23  import com.liferay.portal.kernel.util.StringPool;
24  import com.liferay.portal.kernel.xml.Document;
25  import com.liferay.portal.kernel.xml.Element;
26  import com.liferay.portal.kernel.xml.SAXReaderUtil;
27  import com.liferay.portal.model.Group;
28  import com.liferay.portal.model.GroupConstants;
29  import com.liferay.portal.model.Layout;
30  import com.liferay.portal.model.Permission;
31  import com.liferay.portal.model.PortletConstants;
32  import com.liferay.portal.model.Resource;
33  import com.liferay.portal.model.ResourceConstants;
34  import com.liferay.portal.model.Role;
35  import com.liferay.portal.model.RoleConstants;
36  import com.liferay.portal.model.User;
37  import com.liferay.portal.security.permission.ResourceActionsUtil;
38  import com.liferay.portal.service.GroupLocalServiceUtil;
39  import com.liferay.portal.service.PermissionLocalServiceUtil;
40  import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
41  import com.liferay.portal.service.RoleLocalServiceUtil;
42  import com.liferay.portal.service.permission.PortletPermissionUtil;
43  import com.liferay.portal.util.PropsValues;
44  
45  import java.io.IOException;
46  
47  import java.util.Iterator;
48  import java.util.List;
49  import java.util.Map;
50  
51  import org.apache.commons.lang.time.StopWatch;
52  
53  /**
54   * <a href="PermissionExporter.java.html"><b><i>View Source</i></b></a>
55   *
56   * @author Brian Wing Shun Chan
57   * @author Joel Kozikowski
58   * @author Charles May
59   * @author Raymond Augé
60   * @author Jorge Ferrer
61   * @author Bruno Farache
62   * @author Zsigmond Rab
63   * @author Douglas Wong
64   */
65  public class PermissionExporter {
66  
67      protected Element exportGroupPermissions(
68              long companyId, long groupId, String resourceName,
69              String resourcePrimKey, Element parentEl, String elName)
70          throws SystemException {
71  
72          Element el = parentEl.addElement(elName);
73  
74          List<Permission> permissions =
75              PermissionLocalServiceUtil.getGroupPermissions(
76                  groupId, companyId, resourceName,
77                  ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey);
78  
79          List<String> actions = ResourceActionsUtil.getActions(permissions);
80  
81          for (int i = 0; i < actions.size(); i++) {
82              String action = actions.get(i);
83  
84              Element actionKeyEl = el.addElement("action-key");
85  
86              actionKeyEl.addText(action);
87          }
88  
89          return el;
90      }
91  
92      protected void exportGroupRoles(
93              LayoutCache layoutCache, long companyId, long groupId,
94              String resourceName, String entityName, Element parentEl)
95          throws SystemException {
96  
97          List<Role> roles = layoutCache.getGroupRoles_1to4(groupId);
98  
99          Element groupEl = exportRoles(
100             companyId, resourceName, ResourceConstants.SCOPE_GROUP,
101             String.valueOf(groupId), parentEl, entityName + "-roles", roles);
102 
103         if (groupEl.elements().isEmpty()) {
104             parentEl.remove(groupEl);
105         }
106     }
107 
108     protected void exportInheritedPermissions(
109             LayoutCache layoutCache, long companyId, String resourceName,
110             String resourcePrimKey, Element parentEl, String entityName)
111         throws PortalException, SystemException {
112 
113         Element entityPermissionsEl = SAXReaderUtil.createElement(
114             entityName + "-permissions");
115 
116         Map<String, Long> entityMap = layoutCache.getEntityMap(
117             companyId, entityName);
118 
119         Iterator<Map.Entry<String, Long>> itr = entityMap.entrySet().iterator();
120 
121         while (itr.hasNext()) {
122             Map.Entry<String, Long> entry = itr.next();
123 
124             String name = entry.getKey().toString();
125 
126             long entityGroupId = entry.getValue();
127 
128             Element entityEl = exportGroupPermissions(
129                 companyId, entityGroupId, resourceName, resourcePrimKey,
130                 entityPermissionsEl, entityName + "-actions");
131 
132             if (entityEl.elements().isEmpty()) {
133                 entityPermissionsEl.remove(entityEl);
134             }
135             else {
136                 entityEl.addAttribute("name", name);
137             }
138         }
139 
140         if (!entityPermissionsEl.elements().isEmpty()) {
141             parentEl.add(entityPermissionsEl);
142         }
143     }
144 
145     protected void exportInheritedRoles(
146             LayoutCache layoutCache, long companyId, long groupId,
147             String resourceName, String entityName, Element parentEl)
148         throws PortalException, SystemException {
149 
150         Element entityRolesEl = SAXReaderUtil.createElement(
151             entityName + "-roles");
152 
153         Map<String, Long> entityMap = layoutCache.getEntityMap(
154             companyId, entityName);
155 
156         Iterator<Map.Entry<String, Long>> itr = entityMap.entrySet().iterator();
157 
158         while (itr.hasNext()) {
159             Map.Entry<String, Long> entry = itr.next();
160 
161             String name = entry.getKey().toString();
162 
163             long entityGroupId = entry.getValue();
164 
165             List<Role> entityRoles = layoutCache.getGroupRoles_1to4(
166                 entityGroupId);
167 
168             Element entityEl = exportRoles(
169                 companyId, resourceName, ResourceConstants.SCOPE_GROUP,
170                 String.valueOf(groupId), entityRolesEl, entityName,
171                 entityRoles);
172 
173             if (entityEl.elements().isEmpty()) {
174                 entityRolesEl.remove(entityEl);
175             }
176             else {
177                 entityEl.addAttribute("name", name);
178             }
179         }
180 
181         if (!entityRolesEl.elements().isEmpty()) {
182             parentEl.add(entityRolesEl);
183         }
184     }
185 
186     protected void exportLayoutPermissions(
187             PortletDataContext context, LayoutCache layoutCache, long companyId,
188             long groupId, Layout layout, Element layoutEl,
189             boolean exportUserPermissions)
190         throws PortalException, SystemException {
191 
192         String resourceName = Layout.class.getName();
193         String resourcePrimKey = String.valueOf(layout.getPlid());
194 
195         Element permissionsEl = layoutEl.addElement("permissions");
196 
197         if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
198             exportPermissions_5(
199                 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
200                 permissionsEl, false);
201         }
202         else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
203             exportPermissions_6(
204                 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
205                 permissionsEl, false);
206         }
207         else {
208             exportPermissions_1to4(
209                 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
210                 permissionsEl, exportUserPermissions);
211         }
212     }
213 
214     protected void exportLayoutRoles(
215             LayoutCache layoutCache, long companyId, long groupId,
216             Element rolesEl)
217         throws PortalException, SystemException {
218 
219         String resourceName = Layout.class.getName();
220 
221         exportGroupRoles(
222             layoutCache, companyId, groupId, resourceName, "community",
223             rolesEl);
224 
225         exportUserRoles(layoutCache, companyId, groupId, resourceName, rolesEl);
226 
227         exportInheritedRoles(
228             layoutCache, companyId, groupId, resourceName, "organization",
229             rolesEl);
230 
231         exportInheritedRoles(
232             layoutCache, companyId, groupId, resourceName, "user-group",
233             rolesEl);
234     }
235 
236     protected void exportPermissions_1to4(
237             LayoutCache layoutCache, long companyId, long groupId,
238             String resourceName, String resourcePrimKey, Element permissionsEl,
239             boolean exportUserPermissions)
240         throws PortalException, SystemException {
241 
242         Group guestGroup = GroupLocalServiceUtil.getGroup(
243             companyId, GroupConstants.GUEST);
244 
245         exportGroupPermissions(
246             companyId, groupId, resourceName, resourcePrimKey, permissionsEl,
247             "community-actions");
248 
249         if (groupId != guestGroup.getGroupId()) {
250             exportGroupPermissions(
251                 companyId, guestGroup.getGroupId(), resourceName,
252                 resourcePrimKey, permissionsEl, "guest-actions");
253         }
254 
255         if (exportUserPermissions) {
256             exportUserPermissions(
257                 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
258                 permissionsEl);
259         }
260 
261         exportInheritedPermissions(
262             layoutCache, companyId, resourceName, resourcePrimKey,
263             permissionsEl, "organization");
264 
265         exportInheritedPermissions(
266             layoutCache, companyId, resourceName, resourcePrimKey,
267             permissionsEl, "user-group");
268     }
269 
270     protected void exportPermissions_5(
271             LayoutCache layoutCache, long companyId, long groupId,
272             String resourceName, String resourcePrimKey, Element permissionsEl,
273             boolean portletActions)
274         throws PortalException, SystemException {
275 
276         Resource resource = layoutCache.getResource(
277             companyId, groupId, resourceName,
278             ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
279             portletActions);
280 
281         List<Role> roles = layoutCache.getGroupRoles_5(groupId, resourceName);
282 
283         for (Role role : roles) {
284             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
285                 continue;
286             }
287 
288             Element roleEl = permissionsEl.addElement("role");
289 
290             roleEl.addAttribute("name", role.getName());
291             roleEl.addAttribute("description", role.getDescription());
292             roleEl.addAttribute("type", String.valueOf(role.getType()));
293 
294             List<Permission> permissions =
295                 PermissionLocalServiceUtil.getRolePermissions(
296                     role.getRoleId(), resource.getResourceId());
297 
298             List<String> actions = ResourceActionsUtil.getActions(permissions);
299 
300             for (String action : actions) {
301                 Element actionKeyEl = roleEl.addElement("action-key");
302 
303                 actionKeyEl.addText(action);
304             }
305         }
306     }
307 
308     protected void exportPermissions_6(
309             LayoutCache layoutCache, long companyId, long groupId,
310             String resourceName, String resourcePrimKey, Element permissionsEl,
311             boolean portletActions)
312         throws PortalException, SystemException {
313 
314         List<Role> roles = layoutCache.getGroupRoles_5(groupId, resourceName);
315 
316         for (Role role : roles) {
317             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
318                 continue;
319             }
320 
321             Element roleEl = permissionsEl.addElement("role");
322 
323             roleEl.addAttribute("name", role.getName());
324             roleEl.addAttribute("description", role.getDescription());
325             roleEl.addAttribute("type", String.valueOf(role.getType()));
326 
327             List<String> actionIds = null;
328 
329             if (portletActions) {
330                 actionIds = ResourceActionsUtil.getPortletResourceActions(
331                     resourceName);
332             }
333             else {
334                 actionIds = ResourceActionsUtil.getModelResourceActions(
335                     resourceName);
336             }
337 
338             List<String> actions =
339                 ResourcePermissionLocalServiceUtil.
340                     getAvailableResourcePermissionActionIds(
341                         companyId, resourceName,
342                         ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
343                         role.getRoleId(), actionIds);
344 
345             for (String action : actions) {
346                 Element actionKeyEl = roleEl.addElement("action-key");
347 
348                 actionKeyEl.addText(action);
349             }
350         }
351     }
352 
353     protected void exportPortletDataPermissions(PortletDataContext context)
354         throws SystemException {
355 
356         try {
357             Document doc = SAXReaderUtil.createDocument();
358 
359             Element root = doc.addElement("portlet-data-permissions");
360 
361             Map<String, List<KeyValuePair>> permissionsMap =
362                 context.getPermissions();
363 
364             for (Map.Entry<String, List<KeyValuePair>> entry :
365                     permissionsMap.entrySet()) {
366 
367                 String[] permissionEntry = entry.getKey().split(
368                     StringPool.POUND);
369 
370                 Element portletDataEl = root.addElement("portlet-data");
371 
372                 portletDataEl.addAttribute("resource-name", permissionEntry[0]);
373                 portletDataEl.addAttribute("resource-pk", permissionEntry[1]);
374 
375                 List<KeyValuePair> permissions = entry.getValue();
376 
377                 for (KeyValuePair permission : permissions) {
378                     String roleName = permission.getKey();
379                     String actions = permission.getValue();
380 
381                     Element permissionsEl = portletDataEl.addElement(
382                         "permissions");
383 
384                     permissionsEl.addAttribute("role-name", roleName);
385                     permissionsEl.addAttribute("actions", actions);
386                 }
387             }
388 
389             context.addZipEntry(
390                 context.getRootPath() + "/portlet-data-permissions.xml",
391                 doc.formattedString());
392         }
393         catch (IOException ioe) {
394             throw new SystemException(ioe);
395         }
396     }
397 
398     protected void exportPortletPermissions(
399             PortletDataContext context, LayoutCache layoutCache,
400             String portletId, Layout layout, Element portletEl)
401         throws PortalException, SystemException {
402 
403         long companyId = context.getCompanyId();
404         long groupId = context.getGroupId();
405 
406         String resourceName = PortletConstants.getRootPortletId(portletId);
407         String resourcePrimKey = PortletPermissionUtil.getPrimaryKey(
408             layout.getPlid(), portletId);
409 
410         Element permissionsEl = portletEl.addElement("permissions");
411 
412         if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
413             exportPermissions_5(
414                 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
415                 permissionsEl, true);
416         }
417         else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
418             exportPermissions_6(
419                 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
420                 permissionsEl, true);
421         }
422         else {
423             boolean exportUserPermissions = MapUtil.getBoolean(
424                 context.getParameterMap(),
425                 PortletDataHandlerKeys.USER_PERMISSIONS);
426 
427             exportPermissions_1to4(
428                 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
429                 permissionsEl, exportUserPermissions);
430 
431             Element rolesEl = portletEl.addElement("roles");
432 
433             exportPortletRoles(
434                 layoutCache, companyId, groupId, portletId, rolesEl);
435         }
436     }
437 
438     protected void exportPortletRoles(
439             LayoutCache layoutCache, long companyId, long groupId,
440             String portletId, Element rolesEl)
441         throws PortalException, SystemException {
442 
443         String resourceName = PortletConstants.getRootPortletId(
444             portletId);
445 
446         Element portletEl = rolesEl.addElement("portlet");
447 
448         portletEl.addAttribute("portlet-id", portletId);
449 
450         exportGroupRoles(
451             layoutCache, companyId, groupId, resourceName, "community",
452             portletEl);
453 
454         exportUserRoles(
455             layoutCache, companyId, groupId, resourceName, portletEl);
456 
457         exportInheritedRoles(
458             layoutCache, companyId, groupId, resourceName, "organization",
459             portletEl);
460 
461         exportInheritedRoles(
462             layoutCache, companyId, groupId, resourceName, "user-group",
463             portletEl);
464 
465         if (portletEl.elements().isEmpty()) {
466             rolesEl.remove(portletEl);
467         }
468     }
469 
470     protected Element exportRoles(
471             long companyId, String resourceName, int scope,
472             String resourcePrimKey, Element parentEl, String elName,
473             List<Role> roles)
474         throws SystemException {
475 
476         Element el = parentEl.addElement(elName);
477 
478         Map<String, List<String>> resourceRoles =
479             RoleLocalServiceUtil.getResourceRoles(
480                 companyId, resourceName, scope, resourcePrimKey);
481 
482         Iterator<Map.Entry<String, List<String>>> itr =
483             resourceRoles.entrySet().iterator();
484 
485         while (itr.hasNext()) {
486             Map.Entry<String, List<String>> entry = itr.next();
487 
488             String roleName = entry.getKey().toString();
489 
490             if (hasRole(roles, roleName)) {
491                 Element roleEl = el.addElement("role");
492 
493                 roleEl.addAttribute("name", roleName);
494 
495                 List<String> actions = entry.getValue();
496 
497                 for (int i = 0; i < actions.size(); i++) {
498                     String action = actions.get(i);
499 
500                     Element actionKeyEl = roleEl.addElement("action-key");
501 
502                     actionKeyEl.addText(action);
503                     actionKeyEl.addAttribute("scope", String.valueOf(scope));
504                 }
505             }
506         }
507 
508         return el;
509     }
510 
511     protected void exportUserPermissions(
512             LayoutCache layoutCache, long companyId, long groupId,
513             String resourceName, String resourcePrimKey, Element parentEl)
514         throws SystemException {
515 
516         StopWatch stopWatch = null;
517 
518         if (_log.isDebugEnabled()) {
519             stopWatch = new StopWatch();
520 
521             stopWatch.start();
522         }
523 
524         Element userPermissionsEl = SAXReaderUtil.createElement(
525             "user-permissions");
526 
527         List<User> users = layoutCache.getGroupUsers(groupId);
528 
529         for (User user : users) {
530             String uuid = user.getUuid();
531 
532             Element userActionsEl = SAXReaderUtil.createElement("user-actions");
533 
534             List<Permission> permissions =
535                 PermissionLocalServiceUtil.getUserPermissions(
536                     user.getUserId(), companyId, resourceName,
537                     ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey);
538 
539             List<String> actions = ResourceActionsUtil.getActions(permissions);
540 
541             for (String action : actions) {
542                 Element actionKeyEl = userActionsEl.addElement("action-key");
543 
544                 actionKeyEl.addText(action);
545             }
546 
547             if (!userActionsEl.elements().isEmpty()) {
548                 userActionsEl.addAttribute("uuid", uuid);
549                 userPermissionsEl.add(userActionsEl);
550             }
551         }
552 
553         if (!userPermissionsEl.elements().isEmpty()) {
554             parentEl.add(userPermissionsEl);
555         }
556 
557         if (_log.isDebugEnabled()) {
558             _log.debug(
559                 "Export user permissions for {" + resourceName + ", " +
560                     resourcePrimKey + "} with " + users.size() +
561                         " users takes " + stopWatch.getTime() + " ms");
562         }
563     }
564 
565     protected void exportUserRoles(
566             LayoutCache layoutCache, long companyId, long groupId,
567             String resourceName, Element parentEl)
568         throws SystemException {
569 
570         Element userRolesEl = SAXReaderUtil.createElement("user-roles");
571 
572         List<User> users = layoutCache.getGroupUsers(groupId);
573 
574         for (User user : users) {
575             long userId = user.getUserId();
576             String uuid = user.getUuid();
577 
578             List<Role> userRoles = layoutCache.getUserRoles(userId);
579 
580             Element userEl = exportRoles(
581                 companyId, resourceName, ResourceConstants.SCOPE_GROUP,
582                 String.valueOf(groupId), userRolesEl, "user", userRoles);
583 
584             if (userEl.elements().isEmpty()) {
585                 userRolesEl.remove(userEl);
586             }
587             else {
588                 userEl.addAttribute("uuid", uuid);
589             }
590         }
591 
592         if (!userRolesEl.elements().isEmpty()) {
593             parentEl.add(userRolesEl);
594         }
595     }
596 
597     protected boolean hasRole(List<Role> roles, String roleName) {
598         if ((roles == null) || (roles.size() == 0)) {
599             return false;
600         }
601 
602         for (Role role : roles) {
603             if (role.getName().equals(roleName)) {
604                 return true;
605             }
606         }
607 
608         return false;
609     }
610 
611     private static Log _log = LogFactoryUtil.getLog(PermissionExporter.class);
612 
613 }