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