001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.ResourceActionsException;
018    import com.liferay.portal.kernel.bean.BeanPropertiesUtil;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.search.SearchEngineUtil;
024    import com.liferay.portal.kernel.util.ListUtil;
025    import com.liferay.portal.model.AuditedModel;
026    import com.liferay.portal.model.GroupedModel;
027    import com.liferay.portal.model.PermissionedModel;
028    import com.liferay.portal.model.Resource;
029    import com.liferay.portal.model.ResourceConstants;
030    import com.liferay.portal.model.ResourcePermission;
031    import com.liferay.portal.model.Role;
032    import com.liferay.portal.model.RoleConstants;
033    import com.liferay.portal.model.impl.ResourceImpl;
034    import com.liferay.portal.security.permission.PermissionCacheUtil;
035    import com.liferay.portal.security.permission.PermissionThreadLocal;
036    import com.liferay.portal.security.permission.ResourceActionsUtil;
037    import com.liferay.portal.service.ServiceContext;
038    import com.liferay.portal.service.base.ResourceLocalServiceBaseImpl;
039    import com.liferay.portal.util.ResourcePermissionsThreadLocal;
040    
041    import java.util.Arrays;
042    import java.util.Iterator;
043    import java.util.List;
044    
045    import org.apache.commons.lang.time.StopWatch;
046    
047    /**
048     * Provides the local service for accessing, adding, and updating resources.
049     *
050     * <p>
051     * Permissions in Liferay are defined for resource/action pairs. Some resources,
052     * known as portlet resources, define actions that the end-user can perform with
053     * respect to a portlet window. Other resources, known as model resources,
054     * define actions that the end-user can perform with respect to the
055     * service/persistence layer.
056     * </p>
057     *
058     * <p>
059     * On creating an entity instance, you should create resources for it. The
060     * following example demonstrates adding resources for an instance of a model
061     * entity named <code>SomeWidget</code>. The IDs of the actions permitted for
062     * the group and guests are passed in from the service context.
063     * </p>
064     *
065     * <p>
066     * <pre>
067     * <code>
068     * resourceLocalService.addModelResources(
069     *              SomeWidget.getCompanyId(), SomeWidget.getGroupId(), userId,
070     *              SomeWidget.class.getName(), SomeWidget.getPrimaryKey(),
071     *              serviceContext.getGroupPermissions, serviceContext.getGuestPermissions);
072     * </code>
073     * </pre>
074     * </p>
075     *
076     * <p>
077     * Just prior to deleting an entity instance, you should delete its resource at
078     * the individual scope. The following example demonstrates deleting a resource
079     * associated with the <code>SomeWidget</code> model entity at the scope
080     * individual scope.
081     * </p>
082     *
083     * <p>
084     * <pre>
085     * <code>
086     * resourceLocalService.deleteResource(
087     *              SomeWidget.getCompanyId(), SomeWidget.class.getName(),
088     *              ResourceConstants.SCOPE_INDIVIDUAL, SomeWidget.getPrimaryKey());
089     * </code>
090     * </pre>
091     * </p>
092     *
093     * @author Brian Wing Shun Chan
094     * @author Wilson S. Man
095     * @author Raymond Aug??
096     * @author Julio Camarero
097     * @author Connor McKay
098     */
099    public class ResourceLocalServiceImpl extends ResourceLocalServiceBaseImpl {
100    
101            /**
102             * Adds resources for the model, always creating a resource at the
103             * individual scope and only creating resources at the group, group
104             * template, and company scope if such resources don't already exist.
105             *
106             * <ol>
107             * <li>
108             * If the service context specifies that default group or default guest
109             * permissions are to be added, then only default permissions are added. See
110             * {@link com.liferay.portal.service.ServiceContext#setAddGroupPermissions(
111             * boolean)} and {@link
112             * com.liferay.portal.service.ServiceContext#setAddGuestPermissions(
113             * boolean)}.
114             * </li>
115             * <li>
116             * Else ...
117             * <ol>
118             * <li>
119             * If the service context specifies to derive default permissions, then
120             * default group and guest permissions are derived from the model and
121             * added. See {@link
122             * com.liferay.portal.service.ServiceContext#setDeriveDefaultPermissions(
123             * boolean)}.
124             * </li>
125             * <li>
126             * Lastly group and guest permissions from the service
127             * context are applied. See {@link
128             * com.liferay.portal.service.ServiceContext#setGroupPermissions(String[])}
129             * and {@link
130             * com.liferay.portal.service.ServiceContext#setGuestPermissions(String[])}.
131             * </li>
132             * </ol>
133             *
134             * </li>
135             * </ol>
136             *
137             * @param  auditedModel the model to associate with the resources
138             * @param  serviceContext the service context to apply. Can set whether to
139             *         add the model's default group and guest permissions, set whether
140             *         to derive default group and guest permissions from the model, set
141             *         group permissions to apply, and set guest permissions to apply.
142             * @throws PortalException if no portal actions could be found associated
143             *         with the model or if a portal exception occurred
144             * @throws SystemException if a system exception occurred
145             */
146            @Override
147            public void addModelResources(
148                            AuditedModel auditedModel, ServiceContext serviceContext)
149                    throws PortalException, SystemException {
150    
151                    if (serviceContext.isAddGroupPermissions() ||
152                            serviceContext.isAddGuestPermissions()) {
153    
154                            addResources(
155                                    auditedModel.getCompanyId(), getGroupId(auditedModel),
156                                    auditedModel.getUserId(), auditedModel.getModelClassName(),
157                                    String.valueOf(auditedModel.getPrimaryKeyObj()), false,
158                                    serviceContext.isAddGroupPermissions(),
159                                    serviceContext.isAddGuestPermissions(),
160                                    getPermissionedModel(auditedModel));
161                    }
162                    else {
163                            if (serviceContext.isDeriveDefaultPermissions()) {
164                                    serviceContext.deriveDefaultPermissions(
165                                            getGroupId(auditedModel), auditedModel.getModelClassName());
166                            }
167    
168                            addModelResources(
169                                    auditedModel.getCompanyId(), getGroupId(auditedModel),
170                                    auditedModel.getUserId(), auditedModel.getModelClassName(),
171                                    String.valueOf(auditedModel.getPrimaryKeyObj()),
172                                    serviceContext.getGroupPermissions(),
173                                    serviceContext.getGuestPermissions(),
174                                    getPermissionedModel(auditedModel));
175                    }
176            }
177    
178            /**
179             * Adds resources for the model with the name and primary key, always
180             * creating a resource at the individual scope and only creating resources
181             * at the group, group template, and company scope if such resources don't
182             * already exist.
183             *
184             * @param  companyId the primary key of the portal instance
185             * @param  groupId the primary key of the group
186             * @param  userId the primary key of the user adding the resources
187             * @param  name a name for the resource, typically the model's class name
188             * @param  primKey the primary key of the model instance, optionally
189             *         <code>0</code> if no instance exists
190             * @param  groupPermissions the group permissions to be applied
191             * @param  guestPermissions the guest permissions to be applied
192             * @throws PortalException if no portal actions could be found associated
193             *         with the model or if a portal exception occurred
194             * @throws SystemException if a system exception occurred
195             */
196            @Override
197            public void addModelResources(
198                            long companyId, long groupId, long userId, String name,
199                            long primKey, String[] groupPermissions, String[] guestPermissions)
200                    throws PortalException, SystemException {
201    
202                    addModelResources(
203                            companyId, groupId, userId, name, String.valueOf(primKey),
204                            groupPermissions, guestPermissions, null);
205            }
206    
207            /**
208             * Adds resources for the model with the name and primary key string, always
209             * creating a resource at the individual scope and only creating resources
210             * at the group, group template, and company scope if such resources don't
211             * already exist.
212             *
213             * @param  companyId the primary key of the portal instance
214             * @param  groupId the primary key of the group
215             * @param  userId the primary key of the user adding the resources
216             * @param  name a name for the resource, typically the model's class name
217             * @param  primKey the primary key string of the model instance, optionally
218             *         an empty string if no instance exists
219             * @param  groupPermissions the group permissions to be applied
220             * @param  guestPermissions the guest permissions to be applied
221             * @throws PortalException if no portal actions could be found associated
222             *         with the model or if a portal exception occurred
223             * @throws SystemException if a system exception occurred
224             */
225            @Override
226            public void addModelResources(
227                            long companyId, long groupId, long userId, String name,
228                            String primKey, String[] groupPermissions,
229                            String[] guestPermissions)
230                    throws PortalException, SystemException {
231    
232                    addModelResources(
233                            companyId, groupId, userId, name, primKey, groupPermissions,
234                            guestPermissions, null);
235            }
236    
237            /**
238             * Adds resources for the entity with the name and primary key, always
239             * creating a resource at the individual scope and only creating resources
240             * at the group, group template, and company scope if such resources don't
241             * already exist.
242             *
243             * @param  companyId the primary key of the portal instance
244             * @param  groupId the primary key of the group
245             * @param  userId the primary key of the user adding the resources
246             * @param  name a name for the resource, which should be a portlet ID if the
247             *         resource is a portlet or the resource's class name otherwise
248             * @param  primKey the primary key of the resource instance, optionally
249             *         <code>0</code> if no instance exists
250             * @param  portletActions whether to associate portlet actions with the
251             *         resource
252             * @param  addGroupPermissions whether to add group permissions
253             * @param  addGuestPermissions whether to add guest permissions
254             * @throws PortalException if no portal actions could be found associated
255             *         with the resource or if a portal exception occurred
256             * @throws SystemException if a system exception occurred
257             */
258            @Override
259            public void addResources(
260                            long companyId, long groupId, long userId, String name,
261                            long primKey, boolean portletActions, boolean addGroupPermissions,
262                            boolean addGuestPermissions)
263                    throws PortalException, SystemException {
264    
265                    addResources(
266                            companyId, groupId, userId, name, String.valueOf(primKey),
267                            portletActions, addGroupPermissions, addGuestPermissions, null);
268            }
269    
270            /**
271             * Adds resources for the entity with the name and primary key string,
272             * always creating a resource at the individual scope and only creating
273             * resources at the group, group template, and company scope if such
274             * resources don't already exist.
275             *
276             * @param  companyId the primary key of the portal instance
277             * @param  groupId the primary key of the group
278             * @param  userId the primary key of the user adding the resources
279             * @param  name a name for the resource, which should be a portlet ID if the
280             *         resource is a portlet or the resource's class name otherwise
281             * @param  primKey the primary key string of the resource instance,
282             *         optionally an empty string if no instance exists
283             * @param  portletActions whether to associate portlet actions with the
284             *         resource
285             * @param  addGroupPermissions whether to add group permissions
286             * @param  addGuestPermissions whether to add guest permissions
287             * @throws PortalException if no portal actions could be found associated
288             *         with the resource or if a portal exception occurred
289             * @throws SystemException if a system exception occurred
290             */
291            @Override
292            public void addResources(
293                            long companyId, long groupId, long userId, String name,
294                            String primKey, boolean portletActions, boolean addGroupPermissions,
295                            boolean addGuestPermissions)
296                    throws PortalException, SystemException {
297    
298                    addResources(
299                            companyId, groupId, userId, name, primKey, portletActions,
300                            addGroupPermissions, addGuestPermissions, null);
301            }
302    
303            /**
304             * Adds resources for the entity with the name. Use this method if the user
305             * is unknown or irrelevant and there is no current entity instance.
306             *
307             * @param  companyId the primary key of the portal instance
308             * @param  groupId the primary key of the group
309             * @param  name a name for the resource, which should be a portlet ID if the
310             *         resource is a portlet or the resource's class name otherwise
311             * @param  portletActions whether to associate portlet actions with the
312             *         resource
313             * @throws PortalException if no portal actions could be found associated
314             *         with the resource or if a portal exception occurred
315             * @throws SystemException if a system exception occurred
316             */
317            @Override
318            public void addResources(
319                            long companyId, long groupId, String name, boolean portletActions)
320                    throws PortalException, SystemException {
321    
322                    addResources(
323                            companyId, groupId, 0, name, null, portletActions, false, false);
324            }
325    
326            /**
327             * Deletes the resource associated with the model at the scope.
328             *
329             * @param  auditedModel the model associated with the resource
330             * @param  scope the scope of the resource. For more information see {@link
331             *         com.liferay.portal.model.ResourceConstants}.
332             * @throws PortalException if a portal exception occurred
333             * @throws SystemException if a system exception occurred
334             */
335            @Override
336            public void deleteResource(AuditedModel auditedModel, int scope)
337                    throws PortalException, SystemException {
338    
339                    deleteResource(
340                            auditedModel.getCompanyId(), auditedModel.getModelClassName(),
341                            scope, String.valueOf(auditedModel.getPrimaryKeyObj()),
342                            getPermissionedModel(auditedModel));
343            }
344    
345            /**
346             * Deletes the resource matching the primary key at the scope.
347             *
348             * @param  companyId the primary key of the portal instance
349             * @param  name the resource's name, which should be a portlet ID if the
350             *         resource is a portlet or the resource's class name otherwise
351             * @param  scope the scope of the resource. For more information see {@link
352             *         com.liferay.portal.model.ResourceConstants}.
353             * @param  primKey the primary key of the resource instance
354             * @throws PortalException if a portal exception occurred
355             * @throws SystemException if a system exception occurred
356             */
357            @Override
358            public void deleteResource(
359                            long companyId, String name, int scope, long primKey)
360                    throws PortalException, SystemException {
361    
362                    deleteResource(companyId, name, scope, String.valueOf(primKey), null);
363            }
364    
365            /**
366             * Deletes the resource matching the primary key at the scope.
367             *
368             * @param  companyId the primary key of the portal instance
369             * @param  name the resource's name, which should be a portlet ID if the
370             *         resource is a portlet or the resource's class name otherwise
371             * @param  scope the scope of the resource. For more information see {@link
372             *         com.liferay.portal.model.ResourceConstants}.
373             * @param  primKey the primary key string of the resource instance
374             * @throws PortalException if a portal exception occurred
375             * @throws SystemException if a system exception occurred
376             */
377            @Override
378            public void deleteResource(
379                            long companyId, String name, int scope, String primKey)
380                    throws PortalException, SystemException {
381    
382                    deleteResource(companyId, name, scope, primKey, null);
383            }
384    
385            /**
386             * Returns a new resource with the name and primary key at the scope.
387             *
388             * @param  companyId the primary key of the portal instance
389             * @param  name a name for the resource, which should be a portlet ID if the
390             *         resource is a portlet or the resource's class name otherwise
391             * @param  scope the scope of the resource. For more information see {@link
392             *         com.liferay.portal.model.ResourceConstants}.
393             * @param  primKey the primary key string of the resource
394             * @return the new resource
395             */
396            @Override
397            public Resource getResource(
398                    long companyId, String name, int scope, String primKey) {
399    
400                    Resource resource = new ResourceImpl();
401    
402                    resource.setCompanyId(companyId);
403                    resource.setName(name);
404                    resource.setScope(scope);
405                    resource.setPrimKey(primKey);
406    
407                    return resource;
408            }
409    
410            /**
411             * Returns <code>true</code> if the roles have permission to perform the
412             * action on the resources.
413             *
414             * @param  userId the primary key of the user performing the permission
415             *         check
416             * @param  resourceId the primary key of the resource, typically the scope
417             *         group ID representing the scope in which the permission check is
418             *         being performed
419             * @param  resources the resources for which permissions are to be checked
420             * @param  actionId the primary key of the action to be performed on the
421             *         resources
422             * @param  roleIds the primary keys of the roles
423             * @return <code>true</code> if the roles have permission to perform the
424             *         action on the resources;<code>false</code> otherwise
425             * @throws PortalException if any one of the roles with the primary keys
426             *         could not be found or if a resource action with the action ID
427             *         could not be found
428             * @throws SystemException if a system exception occurred
429             */
430            @Override
431            public boolean hasUserPermissions(
432                            long userId, long resourceId, List<Resource> resources,
433                            String actionId, long[] roleIds)
434                    throws PortalException, SystemException {
435    
436                    StopWatch stopWatch = new StopWatch();
437    
438                    stopWatch.start();
439    
440                    int block = 1;
441    
442                    boolean hasUserPermissions =
443                            resourcePermissionLocalService.hasResourcePermission(
444                                    resources, roleIds, actionId);
445    
446                    logHasUserPermissions(userId, resourceId, actionId, stopWatch, block++);
447    
448                    return hasUserPermissions;
449            }
450    
451            /**
452             * Updates the resources for the model, replacing their group and guest
453             * permissions with new ones from the service context.
454             *
455             * @param  auditedModel the model associated with the resources
456             * @param  serviceContext the service context to be applied. Can set group
457             *         and guest permissions.
458             * @throws PortalException if a portal exception occurred
459             * @throws SystemException if a system exception occurred
460             */
461            @Override
462            public void updateModelResources(
463                            AuditedModel auditedModel, ServiceContext serviceContext)
464                    throws PortalException, SystemException {
465    
466                    updateResources(
467                            auditedModel.getCompanyId(), getGroupId(auditedModel),
468                            auditedModel.getModelClassName(),
469                            String.valueOf(auditedModel.getPrimaryKeyObj()),
470                            serviceContext.getGroupPermissions(),
471                            serviceContext.getGuestPermissions(),
472                            getPermissionedModel(auditedModel));
473            }
474    
475            /**
476             * Updates resources matching the group, name, and primary key at the
477             * individual scope, setting new group and guest permissions.
478             *
479             * @param  companyId the primary key of the portal instance
480             * @param  groupId the primary key of the group
481             * @param  name the resource's name, which should be a portlet ID if the
482             *         resource is a portlet or the resource's class name otherwise
483             * @param  primKey the primary key of the resource instance
484             * @param  groupPermissions the group permissions to be applied
485             * @param  guestPermissions the guest permissions to be applied
486             * @throws PortalException if a portal exception occurred
487             * @throws SystemException if a system exception occurred
488             */
489            @Override
490            public void updateResources(
491                            long companyId, long groupId, String name, long primKey,
492                            String[] groupPermissions, String[] guestPermissions)
493                    throws PortalException, SystemException {
494    
495                    updateResources(
496                            companyId, groupId, name, String.valueOf(primKey), groupPermissions,
497                            guestPermissions, null);
498            }
499    
500            /**
501             * Updates resources matching the group, name, and primary key string at the
502             * individual scope, setting new group and guest permissions.
503             *
504             * @param  companyId the primary key of the portal instance
505             * @param  groupId the primary key of the group
506             * @param  name the resource's name, which should be a portlet ID if the
507             *         resource is a portlet or the resource's class name otherwise
508             * @param  primKey the primary key string of the resource instance
509             * @param  groupPermissions the group permissions to be applied
510             * @param  guestPermissions the guest permissions to be applied
511             * @throws PortalException if a portal exception occurred
512             * @throws SystemException if a system exception occurred
513             */
514            @Override
515            public void updateResources(
516                            long companyId, long groupId, String name, String primKey,
517                            String[] groupPermissions, String[] guestPermissions)
518                    throws PortalException, SystemException {
519    
520                    updateResources(
521                            companyId, groupId, name, primKey, groupPermissions,
522                            guestPermissions, null);
523            }
524    
525            /**
526             * Updates resources matching the name, primary key string and scope,
527             * replacing the primary key of their resource permissions with the new
528             * primary key.
529             *
530             * @param  companyId the primary key of the portal instance
531             * @param  name the resource's name, which should be a portlet ID if the
532             *         resource is a portlet or the resource's class name otherwise
533             * @param  scope the scope of the resource. For more information see {@link
534             *         com.liferay.portal.model.ResourceConstants}.
535             * @param  primKey the primary key string of the resource instance
536             * @param  newPrimKey the new primary key string of the resource
537             * @throws SystemException if a system exception occurred
538             */
539            @Override
540            public void updateResources(
541                            long companyId, String name, int scope, String primKey,
542                            String newPrimKey)
543                    throws SystemException {
544    
545                    if (resourceBlockLocalService.isSupported(name)) {
546    
547                            // Assuming that this method is used when the primary key of an
548                            // existing record is changed, then nothing needs to happen here, as
549                            // it should still have its resource block ID.
550    
551                    }
552                    else {
553                            updateResourcePermissions(
554                                    companyId, name, scope, primKey, newPrimKey);
555                    }
556            }
557    
558            protected void addGroupPermissions(
559                            long companyId, long groupId, long userId, String name,
560                            Resource resource, boolean portletActions,
561                            PermissionedModel permissionedModel)
562                    throws PortalException, SystemException {
563    
564                    List<String> actions = null;
565    
566                    if (portletActions) {
567                            actions = ResourceActionsUtil.getPortletResourceGroupDefaultActions(
568                                    name);
569                    }
570                    else {
571                            actions = ResourceActionsUtil.getModelResourceGroupDefaultActions(
572                                    name);
573                    }
574    
575                    String[] actionIds = actions.toArray(new String[actions.size()]);
576    
577                    if (resourceBlockLocalService.isSupported(name)) {
578                            addGroupPermissionsBlocks(
579                                    groupId, resource, actions, permissionedModel);
580                    }
581                    else {
582                            addGroupPermissions(groupId, resource, actionIds);
583                    }
584            }
585    
586            protected void addGroupPermissions(
587                            long groupId, Resource resource, String[] actionIds)
588                    throws PortalException, SystemException {
589    
590                    Role role = roleLocalService.getDefaultGroupRole(groupId);
591    
592                    resourcePermissionLocalService.setResourcePermissions(
593                            resource.getCompanyId(), resource.getName(), resource.getScope(),
594                            resource.getPrimKey(), role.getRoleId(), actionIds);
595            }
596    
597            protected void addGroupPermissionsBlocks(
598                            long groupId, Resource resource, List<String> actionIds,
599                            PermissionedModel permissionedModel)
600                    throws PortalException, SystemException {
601    
602                    if (permissionedModel == null) {
603                            throw new IllegalArgumentException("Permissioned model is null");
604                    }
605    
606                    // Scope is assumed to always be individual
607    
608                    Role role = roleLocalService.getDefaultGroupRole(groupId);
609    
610                    resourceBlockLocalService.setIndividualScopePermissions(
611                            resource.getCompanyId(), groupId, resource.getName(),
612                            permissionedModel, role.getRoleId(), actionIds);
613            }
614    
615            protected void addGuestPermissions(
616                            long companyId, long groupId, long userId, String name,
617                            Resource resource, boolean portletActions,
618                            PermissionedModel permissionedModel)
619                    throws PortalException, SystemException {
620    
621                    List<String> actions = null;
622    
623                    if (portletActions) {
624                            actions = ResourceActionsUtil.getPortletResourceGuestDefaultActions(
625                                    name);
626                    }
627                    else {
628                            actions = ResourceActionsUtil.getModelResourceGuestDefaultActions(
629                                    name);
630                    }
631    
632                    String[] actionIds = actions.toArray(new String[actions.size()]);
633    
634                    if (resourceBlockLocalService.isSupported(name)) {
635                            addGuestPermissionsBlocks(
636                                    companyId, groupId, resource, actions, permissionedModel);
637                    }
638                    else {
639                            addGuestPermissions(companyId, resource, actionIds);
640                    }
641            }
642    
643            protected void addGuestPermissions(
644                            long companyId, Resource resource, String[] actionIds)
645                    throws PortalException, SystemException {
646    
647                    Role guestRole = roleLocalService.getRole(
648                            companyId, RoleConstants.GUEST);
649    
650                    resourcePermissionLocalService.setResourcePermissions(
651                            resource.getCompanyId(), resource.getName(), resource.getScope(),
652                            resource.getPrimKey(), guestRole.getRoleId(), actionIds);
653            }
654    
655            protected void addGuestPermissionsBlocks(
656                            long companyId, long groupId, Resource resource,
657                            List<String> actionIds, PermissionedModel permissionedModel)
658                    throws PortalException, SystemException {
659    
660                    if (permissionedModel == null) {
661                            throw new IllegalArgumentException("Permissioned model is null");
662                    }
663    
664                    // Scope is assumed to always be individual
665    
666                    Role guestRole = roleLocalService.getRole(
667                            companyId, RoleConstants.GUEST);
668    
669                    resourceBlockLocalService.setIndividualScopePermissions(
670                            resource.getCompanyId(), groupId, resource.getName(),
671                            permissionedModel, guestRole.getRoleId(), actionIds);
672            }
673    
674            protected void addModelResources(
675                            long companyId, long groupId, long userId, Resource resource,
676                            String[] groupPermissions, String[] guestPermissions,
677                            PermissionedModel permissionedModel)
678                    throws PortalException, SystemException {
679    
680                    // Owner permissions
681    
682                    Role ownerRole = roleLocalService.getRole(
683                            companyId, RoleConstants.OWNER);
684    
685                    List<String> ownerActionIds =
686                            ResourceActionsUtil.getModelResourceActions(resource.getName());
687    
688                    ownerActionIds = ListUtil.copy(ownerActionIds);
689    
690                    filterOwnerActions(resource.getName(), ownerActionIds);
691    
692                    String[] ownerPermissions = ownerActionIds.toArray(
693                            new String[ownerActionIds.size()]);
694    
695                    // Group permissions
696    
697                    Role defaultGroupRole = null;
698    
699                    if (groupId > 0) {
700                            defaultGroupRole = roleLocalService.getDefaultGroupRole(groupId);
701    
702                            if (groupPermissions == null) {
703                                    groupPermissions = new String[0];
704                            }
705                    }
706    
707                    // Guest permissions
708    
709                    Role guestRole = roleLocalService.getRole(
710                            companyId, RoleConstants.GUEST);
711    
712                    if (guestPermissions == null) {
713                            guestPermissions = new String[0];
714                    }
715    
716                    if (resourceBlockLocalService.isSupported(resource.getName())) {
717                            if (permissionedModel == null) {
718                                    throw new IllegalArgumentException(
719                                            "Permissioned model is null");
720                            }
721    
722                            // Scope is assumed to always be individual
723    
724                            resourceBlockLocalService.setIndividualScopePermissions(
725                                    resource.getCompanyId(), groupId, resource.getName(),
726                                    permissionedModel, ownerRole.getRoleId(), ownerActionIds);
727    
728                            if (groupId > 0) {
729                                    resourceBlockLocalService.setIndividualScopePermissions(
730                                            resource.getCompanyId(), groupId, resource.getName(),
731                                            permissionedModel, defaultGroupRole.getRoleId(),
732                                            Arrays.asList(groupPermissions));
733                            }
734    
735                            resourceBlockLocalService.setIndividualScopePermissions(
736                                    resource.getCompanyId(), groupId, resource.getName(),
737                                    permissionedModel, guestRole.getRoleId(),
738                                    Arrays.asList(guestPermissions));
739                    }
740                    else {
741                            resourcePermissionLocalService.setOwnerResourcePermissions(
742                                    resource.getCompanyId(), resource.getName(),
743                                    resource.getScope(), resource.getPrimKey(),
744                                    ownerRole.getRoleId(), userId, ownerPermissions);
745    
746                            if (groupId > 0) {
747                                    resourcePermissionLocalService.setResourcePermissions(
748                                            resource.getCompanyId(), resource.getName(),
749                                            resource.getScope(), resource.getPrimKey(),
750                                            defaultGroupRole.getRoleId(), groupPermissions);
751                            }
752    
753                            resourcePermissionLocalService.setResourcePermissions(
754                                    resource.getCompanyId(), resource.getName(),
755                                    resource.getScope(), resource.getPrimKey(),
756                                    guestRole.getRoleId(), guestPermissions);
757                    }
758            }
759    
760            protected void addModelResources(
761                            long companyId, long groupId, long userId, String name,
762                            String primKey, String[] groupPermissions,
763                            String[] guestPermissions, PermissionedModel permissionedModel)
764                    throws PortalException, SystemException {
765    
766                    if (!PermissionThreadLocal.isAddResource()) {
767                            return;
768                    }
769    
770                    validate(name, false);
771    
772                    if (primKey == null) {
773                            return;
774                    }
775    
776                    // Individual
777    
778                    Resource resource = getResource(
779                            companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
780    
781                    // Permissions
782    
783                    boolean flushResourceBlockEnabled =
784                            PermissionThreadLocal.isFlushResourceBlockEnabled(
785                                    companyId, groupId, name);
786                    boolean flushResourcePermissionEnabled =
787                            PermissionThreadLocal.isFlushResourcePermissionEnabled(
788                                    name, primKey);
789    
790                    PermissionThreadLocal.setFlushResourceBlockEnabled(
791                            companyId, groupId, name, false);
792                    PermissionThreadLocal.setFlushResourcePermissionEnabled(
793                            name, primKey, false);
794    
795                    try {
796                            addModelResources(
797                                    companyId, groupId, userId, resource, groupPermissions,
798                                    guestPermissions, permissionedModel);
799                    }
800                    finally {
801                            PermissionThreadLocal.setFlushResourceBlockEnabled(
802                                    companyId, groupId, name, flushResourceBlockEnabled);
803                            PermissionThreadLocal.setFlushResourcePermissionEnabled(
804                                    name, primKey, flushResourcePermissionEnabled);
805    
806                            PermissionCacheUtil.clearResourceBlockCache(
807                                    companyId, groupId, name);
808                            PermissionCacheUtil.clearResourcePermissionCache(
809                                    ResourceConstants.SCOPE_INDIVIDUAL, name, primKey);
810    
811                            SearchEngineUtil.updatePermissionFields(name, primKey);
812                    }
813            }
814    
815            protected void addResources(
816                            long companyId, long groupId, long userId, Resource resource,
817                            boolean portletActions, PermissionedModel permissionedModel)
818                    throws PortalException, SystemException {
819    
820                    List<String> actionIds = null;
821    
822                    if (portletActions) {
823                            actionIds = ResourceActionsUtil.getPortletResourceActions(
824                                    resource.getName());
825                    }
826                    else {
827                            actionIds = ResourceActionsUtil.getModelResourceActions(
828                                    resource.getName());
829    
830                            actionIds = ListUtil.copy(actionIds);
831    
832                            filterOwnerActions(resource.getName(), actionIds);
833                    }
834    
835                    Role role = roleLocalService.getRole(companyId, RoleConstants.OWNER);
836    
837                    if (resourceBlockLocalService.isSupported(resource.getName())) {
838                            if (permissionedModel == null) {
839                                    throw new IllegalArgumentException(
840                                            "Permissioned model is null");
841                            }
842    
843                            // Scope is assumed to always be individual
844    
845                            resourceBlockLocalService.setIndividualScopePermissions(
846                                    resource.getCompanyId(), groupId, resource.getName(),
847                                    permissionedModel, role.getRoleId(), actionIds);
848                    }
849                    else {
850                            resourcePermissionLocalService.setOwnerResourcePermissions(
851                                    resource.getCompanyId(), resource.getName(),
852                                    resource.getScope(), resource.getPrimKey(), role.getRoleId(),
853                                    userId, actionIds.toArray(new String[actionIds.size()]));
854                    }
855            }
856    
857            protected void addResources(
858                            long companyId, long groupId, long userId, String name,
859                            String primKey, boolean portletActions, boolean addGroupPermissions,
860                            boolean addGuestPermissions, PermissionedModel permissionedModel)
861                    throws PortalException, SystemException {
862    
863                    if (!PermissionThreadLocal.isAddResource()) {
864                            return;
865                    }
866    
867                    validate(name, portletActions);
868    
869                    if (primKey == null) {
870                            return;
871                    }
872    
873                    // Individual
874    
875                    Resource resource = getResource(
876                            companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
877    
878                    // Permissions
879    
880                    boolean flushResourceBlockEnabled =
881                            PermissionThreadLocal.isFlushResourceBlockEnabled(
882                                    companyId, groupId, name);
883                    boolean flushResourcePermissionEnabled =
884                            PermissionThreadLocal.isFlushResourcePermissionEnabled(
885                                    name, primKey);
886    
887                    PermissionThreadLocal.setFlushResourceBlockEnabled(
888                            companyId, groupId, name, false);
889                    PermissionThreadLocal.setFlushResourcePermissionEnabled(
890                            name, primKey, false);
891    
892                    List<ResourcePermission> resourcePermissions =
893                            resourcePermissionPersistence.findByC_N_S_P(
894                                    companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
895    
896                    ResourcePermissionsThreadLocal.setResourcePermissions(
897                            resourcePermissions);
898    
899                    try {
900                            addResources(
901                                    companyId, groupId, userId, resource, portletActions,
902                                    permissionedModel);
903    
904                            // Group permissions
905    
906                            if ((groupId > 0) && addGroupPermissions) {
907                                    addGroupPermissions(
908                                            companyId, groupId, userId, name, resource, portletActions,
909                                            permissionedModel);
910                            }
911    
912                            // Guest permissions
913    
914                            if (addGuestPermissions) {
915    
916                                    // Don't add guest permissions when you've already added group
917                                    // permissions and the given group is the guest group.
918    
919                                    addGuestPermissions(
920                                            companyId, groupId, userId, name, resource, portletActions,
921                                            permissionedModel);
922                            }
923                    }
924                    finally {
925                            ResourcePermissionsThreadLocal.setResourcePermissions(null);
926    
927                            PermissionThreadLocal.setFlushResourceBlockEnabled(
928                                    companyId, groupId, name, flushResourceBlockEnabled);
929                            PermissionThreadLocal.setFlushResourcePermissionEnabled(
930                                    name, primKey, flushResourcePermissionEnabled);
931    
932                            PermissionCacheUtil.clearResourceBlockCache(
933                                    companyId, groupId, name);
934                            PermissionCacheUtil.clearResourcePermissionCache(
935                                    ResourceConstants.SCOPE_INDIVIDUAL, name, primKey);
936    
937                            SearchEngineUtil.updatePermissionFields(name, primKey);
938                    }
939            }
940    
941            protected void deleteResource(
942                            long companyId, String name, int scope, String primKey,
943                            PermissionedModel permissionedModel)
944                    throws PortalException, SystemException {
945    
946                    if (resourceBlockLocalService.isSupported(name)) {
947                            if (permissionedModel == null) {
948                                    throw new IllegalArgumentException(
949                                            "Permissioned model is null");
950                            }
951    
952                            resourceBlockLocalService.releasePermissionedModelResourceBlock(
953                                    permissionedModel);
954    
955                            return;
956                    }
957    
958                    resourcePermissionLocalService.deleteResourcePermissions(
959                            companyId, name, scope, primKey);
960            }
961    
962            protected void filterOwnerActions(String name, List<String> actionIds) {
963                    List<String> defaultOwnerActions =
964                            ResourceActionsUtil.getModelResourceOwnerDefaultActions(name);
965    
966                    if (defaultOwnerActions.isEmpty()) {
967                            return;
968                    }
969    
970                    Iterator<String> itr = actionIds.iterator();
971    
972                    while (itr.hasNext()) {
973                            String actionId = itr.next();
974    
975                            if (!defaultOwnerActions.contains(actionId)) {
976                                    itr.remove();
977                            }
978                    }
979            }
980    
981            protected long getGroupId(AuditedModel auditedModel) {
982                    long groupId = 0;
983    
984                    if (auditedModel instanceof GroupedModel) {
985                            GroupedModel groupedModel = (GroupedModel)auditedModel;
986    
987                            groupId = BeanPropertiesUtil.getLongSilent(
988                                    groupedModel, "resourceGroupId", groupedModel.getGroupId());
989                    }
990    
991                    return groupId;
992            }
993    
994            protected PermissionedModel getPermissionedModel(
995                    AuditedModel auditedModel) {
996    
997                    PermissionedModel permissionedModel = null;
998    
999                    if (auditedModel instanceof PermissionedModel) {
1000                            permissionedModel = (PermissionedModel)auditedModel;
1001                    }
1002    
1003                    return permissionedModel;
1004            }
1005    
1006            protected void logHasUserPermissions(
1007                    long userId, long resourceId, String actionId, StopWatch stopWatch,
1008                    int block) {
1009    
1010                    if (!_log.isDebugEnabled()) {
1011                            return;
1012                    }
1013    
1014                    _log.debug(
1015                            "Checking user permissions block " + block + " for " + userId +
1016                                    " " + resourceId + " " + actionId + " takes " +
1017                                            stopWatch.getTime() + " ms");
1018            }
1019    
1020            protected void updateResourceBlocks(
1021                            long companyId, long groupId, Resource resource,
1022                            String[] groupPermissions, String[] guestPermissions,
1023                            PermissionedModel permissionedModel)
1024                    throws PortalException, SystemException {
1025    
1026                    if (permissionedModel == null) {
1027                            throw new IllegalArgumentException("Permissioned model is null");
1028                    }
1029    
1030                    // Scope is assumed to always be individual
1031    
1032                    Role role = roleLocalService.getDefaultGroupRole(groupId);
1033    
1034                    resourceBlockLocalService.setIndividualScopePermissions(
1035                            companyId, groupId, resource.getName(), permissionedModel,
1036                            role.getRoleId(), Arrays.asList(groupPermissions));
1037    
1038                    role = roleLocalService.getRole(companyId, RoleConstants.GUEST);
1039    
1040                    resourceBlockLocalService.setIndividualScopePermissions(
1041                            companyId, groupId, resource.getName(), permissionedModel,
1042                            role.getRoleId(), Arrays.asList(guestPermissions));
1043            }
1044    
1045            protected void updateResourcePermissions(
1046                            long companyId, long groupId, Resource resource,
1047                            String[] groupPermissions, String[] guestPermissions)
1048                    throws PortalException, SystemException {
1049    
1050                    Role role = roleLocalService.getDefaultGroupRole(groupId);
1051    
1052                    resourcePermissionLocalService.setResourcePermissions(
1053                            resource.getCompanyId(), resource.getName(), resource.getScope(),
1054                            resource.getPrimKey(), role.getRoleId(), groupPermissions);
1055    
1056                    role = roleLocalService.getRole(companyId, RoleConstants.GUEST);
1057    
1058                    resourcePermissionLocalService.setResourcePermissions(
1059                            resource.getCompanyId(), resource.getName(), resource.getScope(),
1060                            resource.getPrimKey(), role.getRoleId(), guestPermissions);
1061            }
1062    
1063            protected void updateResourcePermissions(
1064                            long companyId, String name, int scope, String primKey,
1065                            String newPrimKey)
1066                    throws SystemException {
1067    
1068                    List<ResourcePermission> resourcePermissions =
1069                            resourcePermissionLocalService.getResourcePermissions(
1070                                    companyId, name, scope, primKey);
1071    
1072                    for (ResourcePermission resourcePermission : resourcePermissions) {
1073                            resourcePermission.setPrimKey(newPrimKey);
1074    
1075                            resourcePermissionPersistence.update(resourcePermission);
1076                    }
1077            }
1078    
1079            protected void updateResources(
1080                            long companyId, long groupId, String name, String primKey,
1081                            String[] groupPermissions, String[] guestPermissions,
1082                            PermissionedModel permissionedModel)
1083                    throws PortalException, SystemException {
1084    
1085                    Resource resource = getResource(
1086                            companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
1087    
1088                    if (groupPermissions == null) {
1089                            groupPermissions = new String[0];
1090                    }
1091    
1092                    if (guestPermissions == null) {
1093                            guestPermissions = new String[0];
1094                    }
1095    
1096                    if (resourceBlockLocalService.isSupported(name)) {
1097                            updateResourceBlocks(
1098                                    companyId, groupId, resource, groupPermissions,
1099                                    guestPermissions, permissionedModel);
1100                    }
1101                    else {
1102                            updateResourcePermissions(
1103                                    companyId, groupId, resource, groupPermissions,
1104                                    guestPermissions);
1105                    }
1106            }
1107    
1108            protected void validate(String name, boolean portletActions)
1109                    throws PortalException {
1110    
1111                    List<String> actions = null;
1112    
1113                    if (portletActions) {
1114                            actions = ResourceActionsUtil.getPortletResourceActions(name);
1115                    }
1116                    else {
1117                            actions = ResourceActionsUtil.getModelResourceActions(name);
1118                    }
1119    
1120                    if (actions.size() == 0) {
1121                            throw new ResourceActionsException(
1122                                    "There are no actions associated with the resource " + name);
1123                    }
1124            }
1125    
1126            private static Log _log = LogFactoryUtil.getLog(
1127                    ResourceLocalServiceImpl.class);
1128    
1129    }