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.log.Log;
21  import com.liferay.portal.kernel.log.LogFactoryUtil;
22  import com.liferay.portal.kernel.util.GetterUtil;
23  import com.liferay.portal.kernel.util.KeyValuePair;
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.Portlet;
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.User;
36  import com.liferay.portal.service.GroupLocalServiceUtil;
37  import com.liferay.portal.service.PermissionLocalServiceUtil;
38  import com.liferay.portal.service.PortletLocalServiceUtil;
39  import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
40  import com.liferay.portal.service.RoleLocalServiceUtil;
41  import com.liferay.portal.service.permission.PortletPermissionUtil;
42  import com.liferay.portal.util.PropsValues;
43  
44  import java.util.ArrayList;
45  import java.util.Iterator;
46  import java.util.List;
47  
48  /**
49   * <a href="PermissionImporter.java.html"><b><i>View Source</i></b></a>
50   *
51   * @author Brian Wing Shun Chan
52   * @author Joel Kozikowski
53   * @author Charles May
54   * @author Raymond Augé
55   * @author Jorge Ferrer
56   * @author Bruno Farache
57   * @author Wesley Gong
58   * @author Zsigmond Rab
59   * @author Douglas Wong
60   */
61  public class PermissionImporter {
62  
63      protected List<String> getActions(Element el) {
64          List<String> actions = new ArrayList<String>();
65  
66          Iterator<Element> itr = el.elements("action-key").iterator();
67  
68          while (itr.hasNext()) {
69              Element actionEl = itr.next();
70  
71              actions.add(actionEl.getText());
72          }
73  
74          return actions;
75      }
76  
77      protected void importGroupPermissions(
78              LayoutCache layoutCache, long companyId, long groupId,
79              String resourceName, String resourcePrimKey, Element parentEl,
80              String elName, boolean portletActions)
81          throws PortalException, SystemException {
82  
83          Element actionEl = parentEl.element(elName);
84  
85          if (actionEl == null) {
86              return;
87          }
88  
89          List<String> actions = getActions(actionEl);
90  
91          Resource resource = layoutCache.getResource(
92              companyId, groupId, resourceName,
93              ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
94              portletActions);
95  
96          PermissionLocalServiceUtil.setGroupPermissions(
97              groupId, actions.toArray(new String[actions.size()]),
98              resource.getResourceId());
99      }
100 
101     protected void importGroupRoles(
102             LayoutCache layoutCache, long companyId, long groupId,
103             String resourceName, String entityName,
104             Element parentEl)
105         throws PortalException, SystemException {
106 
107         Element entityRolesEl = parentEl.element(entityName + "-roles");
108 
109         if (entityRolesEl == null) {
110             return;
111         }
112 
113         importRolePermissions(
114             layoutCache, companyId, resourceName, ResourceConstants.SCOPE_GROUP,
115             String.valueOf(groupId), entityRolesEl, true);
116     }
117 
118     protected void importInheritedPermissions(
119             LayoutCache layoutCache, long companyId, String resourceName,
120             String resourcePrimKey, Element permissionsEl, String entityName,
121             boolean portletActions)
122         throws PortalException, SystemException {
123 
124         Element entityPermissionsEl = permissionsEl.element(
125             entityName + "-permissions");
126 
127         if (entityPermissionsEl == null) {
128             return;
129         }
130 
131         List<Element> actionsEls = entityPermissionsEl.elements(
132             entityName + "-actions");
133 
134         for (int i = 0; i < actionsEls.size(); i++) {
135             Element actionEl = actionsEls.get(i);
136 
137             String name = actionEl.attributeValue("name");
138 
139             long entityGroupId = layoutCache.getEntityGroupId(
140                 companyId, entityName, name);
141 
142             if (entityGroupId == 0) {
143                 _log.warn(
144                     "Ignore inherited permissions for entity " + entityName +
145                         " with name " + name);
146             }
147             else {
148                 Element parentEl = SAXReaderUtil.createElement("parent");
149 
150                 parentEl.add(actionEl.createCopy());
151 
152                 importGroupPermissions(
153                     layoutCache, companyId, entityGroupId, resourceName,
154                     resourcePrimKey, parentEl, entityName + "-actions",
155                     portletActions);
156             }
157         }
158     }
159 
160     protected void importInheritedRoles(
161             LayoutCache layoutCache, long companyId, long groupId,
162             String resourceName, String entityName, Element parentEl)
163         throws PortalException, SystemException {
164 
165         Element entityRolesEl = parentEl.element(entityName + "-roles");
166 
167         if (entityRolesEl == null) {
168             return;
169         }
170 
171         List<Element> entityEls = entityRolesEl.elements(entityName);
172 
173         for (int i = 0; i < entityEls.size(); i++) {
174             Element entityEl = entityEls.get(i);
175 
176             String name = entityEl.attributeValue("name");
177 
178             long entityGroupId = layoutCache.getEntityGroupId(
179                 companyId, entityName, name);
180 
181             if (entityGroupId == 0) {
182                 _log.warn(
183                     "Ignore inherited roles for entity " + entityName +
184                         " with name " + name);
185             }
186             else {
187                 importRolePermissions(
188                     layoutCache, companyId, resourceName,
189                     ResourceConstants.SCOPE_GROUP, String.valueOf(groupId),
190                     entityEl, false);
191             }
192         }
193     }
194 
195     protected void importLayoutPermissions(
196             LayoutCache layoutCache, long companyId, long groupId, long userId,
197             Layout layout, Element layoutEl, Element parentEl,
198             boolean importUserPermissions)
199         throws PortalException, SystemException {
200 
201         Element permissionsEl = layoutEl.element("permissions");
202 
203         if (permissionsEl != null) {
204             String resourceName = Layout.class.getName();
205             String resourcePrimKey = String.valueOf(layout.getPlid());
206 
207             if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
208                 importPermissions_5(
209                     layoutCache, companyId, groupId, userId, resourceName,
210                     resourcePrimKey, permissionsEl, false);
211             }
212             else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
213                 importPermissions_6(
214                     layoutCache, companyId, groupId, userId, resourceName,
215                     resourcePrimKey, permissionsEl, false);
216             }
217             else {
218                 Group guestGroup = GroupLocalServiceUtil.getGroup(
219                     companyId, GroupConstants.GUEST);
220 
221                 importLayoutPermissions_1to4(
222                     layoutCache, companyId, groupId, guestGroup, layout,
223                     resourceName, resourcePrimKey, permissionsEl,
224                     importUserPermissions);
225             }
226         }
227 
228         Element rolesEl = parentEl.element("roles");
229 
230         if ((PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM < 5) &&
231             (rolesEl != null)) {
232 
233             importLayoutRoles(layoutCache, companyId, groupId, rolesEl);
234         }
235     }
236 
237     protected void importLayoutPermissions_1to4(
238             LayoutCache layoutCache, long companyId, long groupId,
239             Group guestGroup, Layout layout, String resourceName,
240             String resourcePrimKey, Element permissionsEl,
241             boolean importUserPermissions)
242         throws PortalException, SystemException {
243 
244         importGroupPermissions(
245             layoutCache, companyId, groupId, resourceName, resourcePrimKey,
246             permissionsEl, "community-actions", false);
247 
248         if (groupId != guestGroup.getGroupId()) {
249             importGroupPermissions(
250                 layoutCache, companyId, guestGroup.getGroupId(), resourceName,
251                 resourcePrimKey, permissionsEl, "guest-actions", false);
252         }
253 
254         if (importUserPermissions) {
255             importUserPermissions(
256                 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
257                 permissionsEl, false);
258         }
259 
260         importInheritedPermissions(
261             layoutCache, companyId, resourceName, resourcePrimKey,
262             permissionsEl, "organization", false);
263 
264         importInheritedPermissions(
265             layoutCache, companyId, resourceName, resourcePrimKey,
266             permissionsEl, "user-group", false);
267     }
268 
269     protected void importLayoutRoles(
270             LayoutCache layoutCache, long companyId, long groupId,
271             Element rolesEl)
272         throws PortalException, SystemException {
273 
274         String resourceName = Layout.class.getName();
275 
276         importGroupRoles(
277             layoutCache, companyId, groupId, resourceName, "community",
278             rolesEl);
279 
280         importUserRoles(layoutCache, companyId, groupId, resourceName, rolesEl);
281 
282         importInheritedRoles(
283             layoutCache, companyId, groupId, resourceName, "organization",
284             rolesEl);
285 
286         importInheritedRoles(
287             layoutCache, companyId, groupId, resourceName, "user-group",
288             rolesEl);
289     }
290 
291     protected void importPermissions_5(
292             LayoutCache layoutCache, long companyId, long groupId, long userId,
293             String resourceName, String resourcePrimKey, Element permissionsEl,
294             boolean portletActions)
295         throws PortalException, SystemException {
296 
297         Resource resource = layoutCache.getResource(
298             companyId, groupId, resourceName,
299             ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
300             portletActions);
301 
302         List<Element> roleEls = permissionsEl.elements("role");
303 
304         for (Element roleEl : roleEls) {
305             String name = roleEl.attributeValue("name");
306 
307             Role role = layoutCache.getRole(companyId, name);
308 
309             if (role == null) {
310                 String description = roleEl.attributeValue("description");
311                 int type = Integer.valueOf(roleEl.attributeValue("type"));
312 
313                 role = RoleLocalServiceUtil.addRole(
314                     userId, companyId, name, null, description, type);
315             }
316 
317             List<String> actions = getActions(roleEl);
318 
319             PermissionLocalServiceUtil.setRolePermissions(
320                 role.getRoleId(), actions.toArray(new String[actions.size()]),
321                 resource.getResourceId());
322         }
323     }
324 
325     protected void importPermissions_6(
326             LayoutCache layoutCache, long companyId, long groupId, long userId,
327             String resourceName, String resourcePrimKey, Element permissionsEl,
328             boolean portletActions)
329         throws PortalException, SystemException {
330 
331         List<Element> roleEls = permissionsEl.elements("role");
332 
333         for (Element roleEl : roleEls) {
334             String name = roleEl.attributeValue("name");
335 
336             Role role = layoutCache.getRole(companyId, name);
337 
338             if (role == null) {
339                 String description = roleEl.attributeValue("description");
340                 int type = Integer.valueOf(roleEl.attributeValue("type"));
341 
342                 role = RoleLocalServiceUtil.addRole(
343                     userId, companyId, name, null, description, type);
344             }
345 
346             List<String> actions = getActions(roleEl);
347 
348             ResourcePermissionLocalServiceUtil.setResourcePermissions(
349                 companyId, resourceName, ResourceConstants.SCOPE_INDIVIDUAL,
350                 resourcePrimKey, role.getRoleId(),
351                 actions.toArray(new String[actions.size()]));
352         }
353     }
354 
355     protected void importPortletPermissions(
356             LayoutCache layoutCache, long companyId, long groupId, long userId,
357             Layout layout, Element portletEl, String portletId,
358             boolean importUserPermissions)
359         throws PortalException, SystemException {
360 
361         Element permissionsEl = portletEl.element("permissions");
362 
363         if (permissionsEl != null) {
364             String resourceName = PortletConstants.getRootPortletId(portletId);
365 
366             String resourcePrimKey = PortletPermissionUtil.getPrimaryKey(
367                 layout.getPlid(), portletId);
368 
369             if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
370                 importPermissions_5(
371                     layoutCache, companyId, groupId, userId, resourceName,
372                     resourcePrimKey, permissionsEl, true);
373             }
374             else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
375                 importPermissions_6(
376                     layoutCache, companyId, groupId, userId, resourceName,
377                     resourcePrimKey, permissionsEl, true);
378             }
379             else {
380                 Group guestGroup = GroupLocalServiceUtil.getGroup(
381                     companyId, GroupConstants.GUEST);
382 
383                 importPortletPermissions_1to4(
384                     layoutCache, companyId, groupId, guestGroup, layout,
385                     permissionsEl, importUserPermissions);
386             }
387         }
388 
389         Element rolesEl = portletEl.element("roles");
390 
391         if ((PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM < 5) &&
392             (rolesEl != null)) {
393 
394             importPortletRoles(layoutCache, companyId, groupId, portletEl);
395             importPortletRoles(
396                 layoutCache, companyId, groupId, portletId, rolesEl);
397         }
398     }
399 
400     protected void importPortletPermissions_1to4(
401             LayoutCache layoutCache, long companyId, long groupId,
402             Group guestGroup, Layout layout, Element permissionsEl,
403             boolean importUserPermissions)
404         throws PortalException, SystemException {
405 
406         Iterator<Element> itr = permissionsEl.elements("portlet").iterator();
407 
408         while (itr.hasNext()) {
409             Element portletEl = itr.next();
410 
411             String portletId = portletEl.attributeValue("portlet-id");
412 
413             String resourceName = PortletConstants.getRootPortletId(portletId);
414             String resourcePrimKey = PortletPermissionUtil.getPrimaryKey(
415                 layout.getPlid(), portletId);
416 
417             Portlet portlet = PortletLocalServiceUtil.getPortletById(
418                 companyId, resourceName);
419 
420             if (portlet == null) {
421                 if (_log.isDebugEnabled()) {
422                     _log.debug(
423                         "Do not import portlet permissions for " + portletId +
424                             " because the portlet does not exist");
425                 }
426             }
427             else {
428                 importGroupPermissions(
429                     layoutCache, companyId, groupId, resourceName,
430                     resourcePrimKey, portletEl, "community-actions", true);
431 
432                 if (groupId != guestGroup.getGroupId()) {
433                     importGroupPermissions(
434                         layoutCache, companyId, guestGroup.getGroupId(),
435                         resourceName, resourcePrimKey, portletEl,
436                         "guest-actions", true);
437                 }
438 
439                 if (importUserPermissions) {
440                     importUserPermissions(
441                         layoutCache, companyId, groupId, resourceName,
442                         resourcePrimKey, portletEl, true);
443                 }
444 
445                 importInheritedPermissions(
446                     layoutCache, companyId, resourceName, resourcePrimKey,
447                     portletEl, "organization", true);
448 
449                 importInheritedPermissions(
450                     layoutCache, companyId, resourceName, resourcePrimKey,
451                     portletEl, "user-group", true);
452             }
453         }
454     }
455 
456     protected void importPortletRoles(
457             LayoutCache layoutCache, long companyId, long groupId,
458             String portletId, Element rolesEl)
459         throws PortalException, SystemException {
460 
461         String resourceName = PortletConstants.getRootPortletId(portletId);
462 
463         Portlet portlet = PortletLocalServiceUtil.getPortletById(
464             companyId, resourceName);
465 
466         if (portlet == null) {
467             if (_log.isDebugEnabled()) {
468                 _log.debug(
469                     "Do not import portlet roles for " + portletId +
470                         " because the portlet does not exist");
471             }
472         }
473         else {
474             importGroupRoles(
475                 layoutCache, companyId, groupId, resourceName, "community",
476                 rolesEl);
477 
478             importUserRoles(
479                 layoutCache, companyId, groupId, resourceName, rolesEl);
480 
481             importInheritedRoles(
482                 layoutCache, companyId, groupId, resourceName,
483                 "organization", rolesEl);
484 
485             importInheritedRoles(
486                 layoutCache, companyId, groupId, resourceName, "user-group",
487                 rolesEl);
488         }
489     }
490 
491     protected void importPortletRoles(
492             LayoutCache layoutCache, long companyId, long groupId,
493             Element rolesEl)
494         throws PortalException, SystemException {
495 
496         Iterator<Element> itr = rolesEl.elements("portlet").iterator();
497 
498         while (itr.hasNext()) {
499             Element portletEl = itr.next();
500 
501             String portletId = portletEl.attributeValue("portlet-id");
502 
503             String resourceName = PortletConstants.getRootPortletId(portletId);
504 
505             Portlet portlet = PortletLocalServiceUtil.getPortletById(
506                 companyId, resourceName);
507 
508             if (portlet == null) {
509                 if (_log.isDebugEnabled()) {
510                     _log.debug(
511                         "Do not import portlet roles for " + portletId +
512                             " because the portlet does not exist");
513                 }
514             }
515             else {
516                 importGroupRoles(
517                     layoutCache, companyId, groupId, resourceName, "community",
518                     portletEl);
519 
520                 importUserRoles(
521                     layoutCache, companyId, groupId, resourceName, portletEl);
522 
523                 importInheritedRoles(
524                     layoutCache, companyId, groupId, resourceName,
525                     "organization", portletEl);
526 
527                 importInheritedRoles(
528                     layoutCache, companyId, groupId, resourceName, "user-group",
529                     portletEl);
530             }
531         }
532     }
533 
534     protected void importRolePermissions(
535             LayoutCache layoutCache, long companyId, String resourceName,
536             int scope, String resourcePrimKey, Element parentEl,
537             boolean communityRole)
538         throws PortalException, SystemException {
539 
540         List<Element> roleEls = parentEl.elements("role");
541 
542         for (int i = 0; i < roleEls.size(); i++) {
543             Element roleEl = roleEls.get(i);
544 
545             String roleName = roleEl.attributeValue("name");
546 
547             Role role = layoutCache.getRole(companyId, roleName);
548 
549             if (role == null) {
550                 _log.warn(
551                     "Ignoring permissions for role with name " + roleName);
552             }
553             else {
554                 List<String> actions = getActions(roleEl);
555 
556                 PermissionLocalServiceUtil.setRolePermissions(
557                     role.getRoleId(), companyId, resourceName, scope,
558                     resourcePrimKey,
559                     actions.toArray(new String[actions.size()]));
560 
561                 if (communityRole) {
562                     long[] groupIds = {GetterUtil.getLong(resourcePrimKey)};
563 
564                     GroupLocalServiceUtil.addRoleGroups(
565                         role.getRoleId(), groupIds);
566                 }
567             }
568         }
569     }
570 
571     protected void importUserPermissions(
572             LayoutCache layoutCache, long companyId, long groupId,
573             String resourceName, String resourcePrimKey, Element parentEl,
574             boolean portletActions)
575         throws PortalException, SystemException {
576 
577         Element userPermissionsEl = parentEl.element("user-permissions");
578 
579         if (userPermissionsEl == null) {
580             return;
581         }
582 
583         List<Element> userActionsEls = userPermissionsEl.elements(
584             "user-actions");
585 
586         for (int i = 0; i < userActionsEls.size(); i++) {
587             Element userActionsEl = userActionsEls.get(i);
588 
589             String uuid = userActionsEl.attributeValue("uuid");
590 
591             User user = layoutCache.getUser(companyId, groupId, uuid);
592 
593             if (user == null) {
594                 if (_log.isWarnEnabled()) {
595                     _log.warn(
596                         "Ignoring permissions for user with uuid " + uuid);
597                 }
598             }
599             else {
600                 List<String> actions = getActions(userActionsEl);
601 
602                 Resource resource = layoutCache.getResource(
603                     companyId, groupId, resourceName,
604                     ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
605                     portletActions);
606 
607                 PermissionLocalServiceUtil.setUserPermissions(
608                     user.getUserId(),
609                     actions.toArray(new String[actions.size()]),
610                     resource.getResourceId());
611             }
612         }
613     }
614 
615     protected void importUserRoles(
616             LayoutCache layoutCache, long companyId, long groupId,
617             String resourceName, Element parentEl)
618         throws PortalException, SystemException {
619 
620         Element userRolesEl = parentEl.element("user-roles");
621 
622         if (userRolesEl == null) {
623             return;
624         }
625 
626         List<Element> userEls = userRolesEl.elements("user");
627 
628         for (int i = 0; i < userEls.size(); i++) {
629             Element userEl = userEls.get(i);
630 
631             String uuid = userEl.attributeValue("uuid");
632 
633             User user = layoutCache.getUser(companyId, groupId, uuid);
634 
635             if (user == null) {
636                 if (_log.isWarnEnabled()) {
637                     _log.warn("Ignoring roles for user with uuid " + uuid);
638                 }
639             }
640             else {
641                 importRolePermissions(
642                     layoutCache, companyId, resourceName,
643                     ResourceConstants.SCOPE_GROUP, String.valueOf(groupId),
644                     userEl, false);
645             }
646         }
647     }
648 
649     protected void readPortletDataPermissions(PortletDataContext context)
650         throws SystemException {
651 
652         try {
653             String xml = context.getZipEntryAsString(
654                 context.getSourceRootPath() + "/portlet-data-permissions.xml");
655 
656             if (xml == null) {
657                 return;
658             }
659 
660             Document doc = SAXReaderUtil.read(xml);
661 
662             Element root = doc.getRootElement();
663 
664             List<Element> portletDataEls = root.elements("portlet-data");
665 
666             for (Element portletDataEl : portletDataEls) {
667                 String resourceName = portletDataEl.attributeValue(
668                     "resource-name");
669                 long resourcePK = GetterUtil.getLong(
670                     portletDataEl.attributeValue("resource-pk"));
671 
672                 List<KeyValuePair> permissions = new ArrayList<KeyValuePair>();
673 
674                 List<Element> permissionsEls = portletDataEl.elements(
675                     "permissions");
676 
677                 for (Element permissionsEl : permissionsEls) {
678                     String roleName = permissionsEl.attributeValue("role-name");
679                     String actions = permissionsEl.attributeValue("actions");
680 
681                     KeyValuePair permission = new KeyValuePair(
682                         roleName, actions);
683 
684                     permissions.add(permission);
685                 }
686 
687                 context.addPermissions(resourceName, resourcePK, permissions);
688             }
689         }
690         catch (Exception e) {
691             throw new SystemException(e);
692         }
693     }
694 
695     private static Log _log = LogFactoryUtil.getLog(PermissionImporter.class);
696 
697 }