001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.lar;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.lar.PortletDataContext;
020    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.util.KeyValuePair;
024    import com.liferay.portal.kernel.util.MapUtil;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.xml.Document;
027    import com.liferay.portal.kernel.xml.Element;
028    import com.liferay.portal.kernel.xml.SAXReaderUtil;
029    import com.liferay.portal.model.Group;
030    import com.liferay.portal.model.GroupConstants;
031    import com.liferay.portal.model.Layout;
032    import com.liferay.portal.model.Permission;
033    import com.liferay.portal.model.PortletConstants;
034    import com.liferay.portal.model.Resource;
035    import com.liferay.portal.model.ResourceConstants;
036    import com.liferay.portal.model.Role;
037    import com.liferay.portal.model.RoleConstants;
038    import com.liferay.portal.model.User;
039    import com.liferay.portal.security.permission.ResourceActionsUtil;
040    import com.liferay.portal.service.GroupLocalServiceUtil;
041    import com.liferay.portal.service.PermissionLocalServiceUtil;
042    import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
043    import com.liferay.portal.service.RoleLocalServiceUtil;
044    import com.liferay.portal.service.permission.PortletPermissionUtil;
045    import com.liferay.portal.util.PropsValues;
046    
047    import java.io.IOException;
048    
049    import java.util.Iterator;
050    import java.util.List;
051    import java.util.Map;
052    
053    import org.apache.commons.lang.time.StopWatch;
054    
055    /**
056     * @author Brian Wing Shun Chan
057     * @author Joel Kozikowski
058     * @author Charles May
059     * @author Raymond Augé
060     * @author Jorge Ferrer
061     * @author Bruno Farache
062     * @author Zsigmond Rab
063     * @author Douglas Wong
064     */
065    public class PermissionExporter {
066    
067            protected Element exportGroupPermissions(
068                            long companyId, long groupId, String resourceName,
069                            String resourcePrimKey, Element parentEl, String elName)
070                    throws SystemException {
071    
072                    Element el = parentEl.addElement(elName);
073    
074                    List<Permission> permissions =
075                            PermissionLocalServiceUtil.getGroupPermissions(
076                                    groupId, companyId, resourceName,
077                                    ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey);
078    
079                    List<String> actions = ResourceActionsUtil.getActions(permissions);
080    
081                    for (int i = 0; i < actions.size(); i++) {
082                            String action = actions.get(i);
083    
084                            Element actionKeyEl = el.addElement("action-key");
085    
086                            actionKeyEl.addText(action);
087                    }
088    
089                    return el;
090            }
091    
092            protected void exportGroupRoles(
093                            LayoutCache layoutCache, long companyId, long groupId,
094                            String resourceName, String entityName, Element parentEl)
095                    throws SystemException {
096    
097                    List<Role> roles = layoutCache.getGroupRoles_1to4(groupId);
098    
099                    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    }