1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.lar;
16  
17  import com.liferay.portal.PortalException;
18  import com.liferay.portal.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 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 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,
188             long companyId, 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(
226             layoutCache, companyId, groupId, resourceName, rolesEl);
227 
228         exportInheritedRoles(
229             layoutCache, companyId, groupId, resourceName, "organization",
230             rolesEl);
231 
232         exportInheritedRoles(
233             layoutCache, companyId, groupId, resourceName, "user-group",
234             rolesEl);
235     }
236 
237     protected void exportPermissions_1to4(
238             LayoutCache layoutCache, long companyId, long groupId,
239             String resourceName, String resourcePrimKey, Element permissionsEl,
240             boolean exportUserPermissions)
241         throws PortalException, SystemException {
242 
243         Group guestGroup = GroupLocalServiceUtil.getGroup(
244             companyId, GroupConstants.GUEST);
245 
246         exportGroupPermissions(
247             companyId, groupId, resourceName, resourcePrimKey, permissionsEl,
248             "community-actions");
249 
250         if (groupId != guestGroup.getGroupId()) {
251             exportGroupPermissions(
252                 companyId, guestGroup.getGroupId(), resourceName,
253                 resourcePrimKey, permissionsEl, "guest-actions");
254         }
255 
256         if (exportUserPermissions) {
257             exportUserPermissions(
258                 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
259                 permissionsEl);
260         }
261 
262         exportInheritedPermissions(
263             layoutCache, companyId, resourceName, resourcePrimKey,
264             permissionsEl, "organization");
265 
266         exportInheritedPermissions(
267             layoutCache, companyId, resourceName, resourcePrimKey,
268             permissionsEl, "user-group");
269     }
270 
271     protected void exportPermissions_5(
272             LayoutCache layoutCache, long companyId, long groupId,
273             String resourceName, String resourcePrimKey, Element permissionsEl,
274             boolean portletActions)
275         throws PortalException, SystemException {
276 
277         Resource resource = layoutCache.getResource(
278             companyId, groupId, resourceName,
279             ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
280             portletActions);
281 
282         List<Role> roles = layoutCache.getGroupRoles_5(groupId, resourceName);
283 
284         for (Role role : roles) {
285             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
286                 continue;
287             }
288 
289             Element roleEl = permissionsEl.addElement("role");
290 
291             roleEl.addAttribute("name", role.getName());
292             roleEl.addAttribute("description", role.getDescription());
293             roleEl.addAttribute("type", String.valueOf(role.getType()));
294 
295             List<Permission> permissions =
296                 PermissionLocalServiceUtil.getRolePermissions(
297                     role.getRoleId(), resource.getResourceId());
298 
299             List<String> actions = ResourceActionsUtil.getActions(permissions);
300 
301             for (String action : actions) {
302                 Element actionKeyEl = roleEl.addElement("action-key");
303 
304                 actionKeyEl.addText(action);
305             }
306         }
307     }
308 
309     protected void exportPermissions_6(
310             LayoutCache layoutCache, long companyId, long groupId,
311             String resourceName, String resourcePrimKey, Element permissionsEl,
312             boolean portletActions)
313         throws PortalException, SystemException {
314 
315         List<Role> roles = layoutCache.getGroupRoles_5(groupId, resourceName);
316 
317         for (Role role : roles) {
318             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
319                 continue;
320             }
321 
322             Element roleEl = permissionsEl.addElement("role");
323 
324             roleEl.addAttribute("name", role.getName());
325             roleEl.addAttribute("description", role.getDescription());
326             roleEl.addAttribute("type", String.valueOf(role.getType()));
327 
328             List<String> actionIds = null;
329 
330             if (portletActions) {
331                 actionIds = ResourceActionsUtil.getPortletResourceActions(
332                     resourceName);
333             }
334             else {
335                 actionIds = ResourceActionsUtil.getModelResourceActions(
336                     resourceName);
337             }
338 
339             List<String> actions =
340                 ResourcePermissionLocalServiceUtil.
341                     getAvailableResourcePermissionActionIds(
342                         companyId, resourceName,
343                         ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
344                         role.getRoleId(), actionIds);
345 
346             for (String action : actions) {
347                 Element actionKeyEl = roleEl.addElement("action-key");
348 
349                 actionKeyEl.addText(action);
350             }
351         }
352     }
353 
354     protected void exportPortletDataPermissions(PortletDataContext context)
355         throws SystemException {
356 
357         try {
358             Document doc = SAXReaderUtil.createDocument();
359 
360             Element root = doc.addElement("portlet-data-permissions");
361 
362             Map<String, List<KeyValuePair>> permissionsMap =
363                 context.getPermissions();
364 
365             for (Map.Entry<String, List<KeyValuePair>> entry :
366                     permissionsMap.entrySet()) {
367 
368                 String[] permissionEntry = entry.getKey().split(
369                     StringPool.POUND);
370 
371                 Element portletDataEl = root.addElement("portlet-data");
372 
373                 portletDataEl.addAttribute("resource-name", permissionEntry[0]);
374                 portletDataEl.addAttribute("resource-pk", permissionEntry[1]);
375 
376                 List<KeyValuePair> permissions = entry.getValue();
377 
378                 for (KeyValuePair permission : permissions) {
379                     String roleName = permission.getKey();
380                     String actions = permission.getValue();
381 
382                     Element permissionsEl = portletDataEl.addElement(
383                         "permissions");
384 
385                     permissionsEl.addAttribute("role-name", roleName);
386                     permissionsEl.addAttribute("actions", actions);
387                 }
388             }
389 
390             context.addZipEntry(
391                 context.getRootPath() + "/portlet-data-permissions.xml",
392                 doc.formattedString());
393         }
394         catch (IOException ioe) {
395             throw new SystemException(ioe);
396         }
397     }
398 
399     protected void exportPortletPermissions(
400             PortletDataContext context, LayoutCache layoutCache,
401             String portletId, Layout layout, Element portletEl)
402         throws PortalException, SystemException {
403 
404         long companyId = context.getCompanyId();
405         long groupId = context.getGroupId();
406 
407         String resourceName = PortletConstants.getRootPortletId(portletId);
408         String resourcePrimKey = PortletPermissionUtil.getPrimaryKey(
409             layout.getPlid(), portletId);
410 
411         Element permissionsEl = portletEl.addElement("permissions");
412 
413         if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
414             exportPermissions_5(
415                 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
416                 permissionsEl, true);
417         }
418         else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
419             exportPermissions_6(
420                 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
421                 permissionsEl, true);
422         }
423         else {
424             boolean exportUserPermissions = MapUtil.getBoolean(
425                 context.getParameterMap(),
426                 PortletDataHandlerKeys.USER_PERMISSIONS);
427 
428             exportPermissions_1to4(
429                 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
430                 permissionsEl, exportUserPermissions);
431 
432             Element rolesEl = portletEl.addElement("roles");
433 
434             exportPortletRoles(layoutCache, companyId, groupId, portletId,
435                 rolesEl);
436         }
437     }
438 
439     protected void exportPortletRoles(
440             LayoutCache layoutCache, long companyId, long groupId,
441             String portletId, Element rolesEl)
442         throws SystemException {
443 
444         String resourceName = PortletConstants.getRootPortletId(
445             portletId);
446 
447         Element portletEl = rolesEl.addElement("portlet");
448 
449         portletEl.addAttribute("portlet-id", portletId);
450 
451         exportGroupRoles(
452             layoutCache, companyId, groupId, resourceName, "community",
453             portletEl);
454 
455         exportUserRoles(
456             layoutCache, companyId, groupId, resourceName, portletEl);
457 
458         exportInheritedRoles(
459             layoutCache, companyId, groupId, resourceName, "organization",
460             portletEl);
461 
462         exportInheritedRoles(
463             layoutCache, companyId, groupId, resourceName, "user-group",
464             portletEl);
465 
466         if (portletEl.elements().isEmpty()) {
467             rolesEl.remove(portletEl);
468         }
469     }
470 
471     protected Element exportRoles(
472             long companyId, String resourceName, int scope,
473             String resourcePrimKey, Element parentEl, String elName,
474             List<Role> roles)
475         throws SystemException {
476 
477         Element el = parentEl.addElement(elName);
478 
479         Map<String, List<String>> resourceRoles =
480             RoleLocalServiceUtil.getResourceRoles(
481                 companyId, resourceName, scope, resourcePrimKey);
482 
483         Iterator<Map.Entry<String, List<String>>> itr =
484             resourceRoles.entrySet().iterator();
485 
486         while (itr.hasNext()) {
487             Map.Entry<String, List<String>> entry = itr.next();
488 
489             String roleName = entry.getKey().toString();
490 
491             if (hasRole(roles, roleName)) {
492                 Element roleEl = el.addElement("role");
493 
494                 roleEl.addAttribute("name", roleName);
495 
496                 List<String> actions = entry.getValue();
497 
498                 for (int i = 0; i < actions.size(); i++) {
499                     String action = actions.get(i);
500 
501                     Element actionKeyEl = roleEl.addElement("action-key");
502 
503                     actionKeyEl.addText(action);
504                     actionKeyEl.addAttribute("scope", String.valueOf(scope));
505                 }
506             }
507         }
508 
509         return el;
510     }
511 
512     protected void exportUserPermissions(
513             LayoutCache layoutCache, long companyId, long groupId,
514             String resourceName, String resourcePrimKey, Element parentEl)
515         throws SystemException {
516 
517         StopWatch stopWatch = null;
518 
519         if (_log.isDebugEnabled()) {
520             stopWatch = new StopWatch();
521 
522             stopWatch.start();
523         }
524 
525         Element userPermissionsEl = SAXReaderUtil.createElement(
526             "user-permissions");
527 
528         List<User> users = layoutCache.getGroupUsers(groupId);
529 
530         for (User user : users) {
531             String uuid = user.getUuid();
532 
533             Element userActionsEl = SAXReaderUtil.createElement("user-actions");
534 
535             List<Permission> permissions =
536                 PermissionLocalServiceUtil.getUserPermissions(
537                     user.getUserId(), companyId, resourceName,
538                     ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey);
539 
540             List<String> actions = ResourceActionsUtil.getActions(permissions);
541 
542             for (String action : actions) {
543                 Element actionKeyEl = userActionsEl.addElement("action-key");
544 
545                 actionKeyEl.addText(action);
546             }
547 
548             if (!userActionsEl.elements().isEmpty()) {
549                 userActionsEl.addAttribute("uuid", uuid);
550                 userPermissionsEl.add(userActionsEl);
551             }
552         }
553 
554         if (!userPermissionsEl.elements().isEmpty()) {
555             parentEl.add(userPermissionsEl);
556         }
557 
558         if (_log.isDebugEnabled()) {
559             _log.debug(
560                 "Export user permissions for {" + resourceName + ", " +
561                     resourcePrimKey + "} with " + users.size() +
562                         " users takes " + stopWatch.getTime() + " ms");
563         }
564     }
565 
566     protected void exportUserRoles(
567             LayoutCache layoutCache, long companyId, long groupId,
568             String resourceName, Element parentEl)
569         throws SystemException {
570 
571         Element userRolesEl = SAXReaderUtil.createElement("user-roles");
572 
573         List<User> users = layoutCache.getGroupUsers(groupId);
574 
575         for (User user : users) {
576             long userId = user.getUserId();
577             String uuid = user.getUuid();
578 
579             List<Role> userRoles = layoutCache.getUserRoles(userId);
580 
581             Element userEl = exportRoles(
582                 companyId, resourceName, ResourceConstants.SCOPE_GROUP,
583                 String.valueOf(groupId), userRolesEl, "user", userRoles);
584 
585             if (userEl.elements().isEmpty()) {
586                 userRolesEl.remove(userEl);
587             }
588             else {
589                 userEl.addAttribute("uuid", uuid);
590             }
591         }
592 
593         if (!userRolesEl.elements().isEmpty()) {
594             parentEl.add(userRolesEl);
595         }
596     }
597 
598     protected boolean hasRole(List<Role> roles, String roleName) {
599         if ((roles == null) || (roles.size() == 0)) {
600             return false;
601         }
602 
603         for (Role role : roles) {
604             if (role.getName().equals(roleName)) {
605                 return true;
606             }
607         }
608 
609         return false;
610     }
611 
612     private static Log _log = LogFactoryUtil.getLog(PermissionExporter.class);
613 
614 }