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.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.jsonwebservice.JSONWebService;
019    import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceMode;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.model.AuditedModel;
022    import com.liferay.portal.model.Group;
023    import com.liferay.portal.model.GroupedModel;
024    import com.liferay.portal.model.PermissionedModel;
025    import com.liferay.portal.model.PortletConstants;
026    import com.liferay.portal.model.ResourceConstants;
027    import com.liferay.portal.model.ResourcePermission;
028    import com.liferay.portal.model.Role;
029    import com.liferay.portal.model.Team;
030    import com.liferay.portal.security.auth.PrincipalException;
031    import com.liferay.portal.security.permission.ActionKeys;
032    import com.liferay.portal.security.permission.BaseModelPermissionChecker;
033    import com.liferay.portal.security.permission.PermissionChecker;
034    import com.liferay.portal.security.permission.ResourceActionsUtil;
035    import com.liferay.portal.service.base.PermissionServiceBaseImpl;
036    import com.liferay.portal.service.permission.PortletPermissionUtil;
037    import com.liferay.portal.service.permission.TeamPermissionUtil;
038    import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
039    import com.liferay.portlet.asset.model.AssetRendererFactory;
040    import com.liferay.registry.Filter;
041    import com.liferay.registry.Registry;
042    import com.liferay.registry.RegistryUtil;
043    import com.liferay.registry.ServiceReference;
044    import com.liferay.registry.ServiceTracker;
045    import com.liferay.registry.ServiceTrackerCustomizer;
046    
047    import java.util.List;
048    import java.util.Map;
049    import java.util.concurrent.ConcurrentHashMap;
050    
051    /**
052     * Provides the remote service for checking permissions.
053     *
054     * @author Brian Wing Shun Chan
055     * @author Raymond Aug??
056     */
057    public class PermissionServiceImpl extends PermissionServiceBaseImpl {
058    
059            @Override
060            public void afterPropertiesSet() {
061                    Registry registry = RegistryUtil.getRegistry();
062    
063                    Filter filter = registry.getFilter(
064                            "(&(model.class.name=*)(objectClass=" +
065                                    BaseModelPermissionChecker.class.getName() + "))");
066    
067                    _serviceTracker = registry.trackServices(
068                            filter, new BaseModelPermissionCheckerServiceTrackerCustomizer());
069    
070                    _serviceTracker.open();
071            }
072    
073            /**
074             * Checks to see if the group has permission to the service.
075             *
076             * @param groupId the primary key of the group
077             * @param name the service name
078             * @param primKey the primary key of the service
079             */
080            @JSONWebService(mode = JSONWebServiceMode.IGNORE)
081            @Override
082            public void checkPermission(long groupId, String name, long primKey)
083                    throws PortalException {
084    
085                    checkPermission(
086                            getPermissionChecker(), groupId, name, String.valueOf(primKey));
087            }
088    
089            /**
090             * Checks to see if the group has permission to the service.
091             *
092             * @param groupId the primary key of the group
093             * @param name the service name
094             * @param primKey the primary key of the service
095             */
096            @Override
097            public void checkPermission(long groupId, String name, String primKey)
098                    throws PortalException {
099    
100                    checkPermission(getPermissionChecker(), groupId, name, primKey);
101            }
102    
103            protected boolean checkBaseModelPermission(
104                            PermissionChecker permissionChecker, long groupId, String className,
105                            long classPK)
106                    throws PortalException {
107    
108                    String actionId = ActionKeys.PERMISSIONS;
109    
110                    if (className.equals(Team.class.getName())) {
111                            className = Group.class.getName();
112    
113                            Team team = teamLocalService.fetchTeam(classPK);
114    
115                            classPK = team.getGroupId();
116    
117                            actionId = ActionKeys.MANAGE_TEAMS;
118                    }
119    
120                    BaseModelPermissionChecker baseModelPermissionChecker =
121                            _baseModelPermissionCheckers.get(className);
122    
123                    if (baseModelPermissionChecker != null) {
124                            baseModelPermissionChecker.checkBaseModel(
125                                    permissionChecker, groupId, classPK, actionId);
126    
127                            return true;
128                    }
129    
130                    return false;
131            }
132    
133            protected void checkPermission(
134                            PermissionChecker permissionChecker, long groupId, String name,
135                            String primKey)
136                    throws PortalException {
137    
138                    if (checkBaseModelPermission(
139                                    permissionChecker, groupId, name,
140                                    GetterUtil.getLong(primKey))) {
141    
142                            return;
143                    }
144    
145                    if ((primKey != null) &&
146                            primKey.contains(PortletConstants.LAYOUT_SEPARATOR)) {
147    
148                            int pos = primKey.indexOf(PortletConstants.LAYOUT_SEPARATOR);
149    
150                            long plid = GetterUtil.getLong(primKey.substring(0, pos));
151    
152                            String portletId = primKey.substring(
153                                    pos + PortletConstants.LAYOUT_SEPARATOR.length());
154    
155                            PortletPermissionUtil.check(
156                                    permissionChecker, plid, portletId, ActionKeys.CONFIGURATION);
157                    }
158                    else if (!permissionChecker.hasPermission(
159                                            groupId, name, primKey, ActionKeys.PERMISSIONS)) {
160    
161                            AssetRendererFactory<?> assetRendererFactory =
162                                    AssetRendererFactoryRegistryUtil.
163                                            getAssetRendererFactoryByClassName(name);
164    
165                            if (assetRendererFactory != null) {
166                                    try {
167                                            if (assetRendererFactory.hasPermission(
168                                                            permissionChecker, GetterUtil.getLong(primKey),
169                                                            ActionKeys.PERMISSIONS)) {
170    
171                                                    return;
172                                            }
173                                    }
174                                    catch (Exception e) {
175                                    }
176                            }
177    
178                            long ownerId = 0;
179    
180                            if (resourceBlockLocalService.isSupported(name)) {
181                                    PermissionedModel permissionedModel =
182                                            resourceBlockLocalService.getPermissionedModel(
183                                                    name, GetterUtil.getLong(primKey));
184    
185                                    if (permissionedModel instanceof GroupedModel) {
186                                            GroupedModel groupedModel = (GroupedModel)permissionedModel;
187    
188                                            ownerId = groupedModel.getUserId();
189                                    }
190                                    else if (permissionedModel instanceof AuditedModel) {
191                                            AuditedModel auditedModel = (AuditedModel)permissionedModel;
192    
193                                            ownerId = auditedModel.getUserId();
194                                    }
195                            }
196                            else {
197                                    ResourcePermission resourcePermission =
198                                            resourcePermissionLocalService.getResourcePermission(
199                                                    permissionChecker.getCompanyId(), name,
200                                                    ResourceConstants.SCOPE_INDIVIDUAL, primKey,
201                                                    permissionChecker.getOwnerRoleId());
202    
203                                    ownerId = resourcePermission.getOwnerId();
204                            }
205    
206                            if (permissionChecker.hasOwnerPermission(
207                                            permissionChecker.getCompanyId(), name, primKey, ownerId,
208                                            ActionKeys.PERMISSIONS)) {
209    
210                                    return;
211                            }
212    
213                            Role role = null;
214    
215                            if (name.equals(Role.class.getName())) {
216                                    long roleId = GetterUtil.getLong(primKey);
217    
218                                    role = rolePersistence.findByPrimaryKey(roleId);
219                            }
220    
221                            if ((role != null) && role.isTeam()) {
222                                    Team team = teamPersistence.findByPrimaryKey(role.getClassPK());
223    
224                                    TeamPermissionUtil.check(
225                                            permissionChecker, team, ActionKeys.PERMISSIONS);
226                            }
227                            else {
228                                    List<String> resourceActions =
229                                            ResourceActionsUtil.getResourceActions(name);
230    
231                                    if (!resourceActions.contains(ActionKeys.DEFINE_PERMISSIONS) ||
232                                            !permissionChecker.hasPermission(
233                                                    groupId, name, primKey,
234                                                    ActionKeys.DEFINE_PERMISSIONS)) {
235    
236                                            throw new PrincipalException.MustHavePermission(
237                                                    permissionChecker, name, Long.valueOf(primKey),
238                                                    ActionKeys.DEFINE_PERMISSIONS);
239                                    }
240                            }
241                    }
242            }
243    
244            private final Map<String, BaseModelPermissionChecker>
245                    _baseModelPermissionCheckers = new ConcurrentHashMap<>();
246            private ServiceTracker
247                    <BaseModelPermissionChecker, BaseModelPermissionChecker>
248                            _serviceTracker;
249    
250            private class BaseModelPermissionCheckerServiceTrackerCustomizer
251                    implements
252                            ServiceTrackerCustomizer
253                                    <BaseModelPermissionChecker, BaseModelPermissionChecker> {
254    
255                    @Override
256                    public BaseModelPermissionChecker addingService(
257                            ServiceReference<BaseModelPermissionChecker> serviceReference) {
258    
259                            Registry registry = RegistryUtil.getRegistry();
260    
261                            BaseModelPermissionChecker baseModelPermissionChecker =
262                                    registry.getService(serviceReference);
263    
264                            String modelClassName = GetterUtil.getString(
265                                    serviceReference.getProperty("model.class.name"));
266    
267                            _baseModelPermissionCheckers.put(
268                                    modelClassName, baseModelPermissionChecker);
269    
270                            return baseModelPermissionChecker;
271                    }
272    
273                    @Override
274                    public void modifiedService(
275                            ServiceReference<BaseModelPermissionChecker> serviceReference,
276                            BaseModelPermissionChecker baseModelPermissionChecker) {
277                    }
278    
279                    @Override
280                    public void removedService(
281                            ServiceReference<BaseModelPermissionChecker> serviceReference,
282                            BaseModelPermissionChecker baseModelPermissionChecker) {
283    
284                            Registry registry = RegistryUtil.getRegistry();
285    
286                            registry.ungetService(serviceReference);
287    
288                            String modelClassName = GetterUtil.getString(
289                                    serviceReference.getProperty("model.class.name"));
290    
291                            _baseModelPermissionCheckers.remove(modelClassName);
292                    }
293    
294            }
295    
296    }