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