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             * @throws PortalException if the group did not have permission to the
080             *         service, if a group with the primary key could not be found or if
081             *         the permission information was invalid
082             */
083            @JSONWebService(mode = JSONWebServiceMode.IGNORE)
084            @Override
085            public void checkPermission(long groupId, String name, long primKey)
086                    throws PortalException {
087    
088                    checkPermission(
089                            getPermissionChecker(), groupId, name, String.valueOf(primKey));
090            }
091    
092            /**
093             * Checks to see if the group has permission to the service.
094             *
095             * @param  groupId the primary key of the group
096             * @param  name the service name
097             * @param  primKey the primary key of the service
098             * @throws PortalException if the group did not have permission to the
099             *         service, if a group with the primary key could not be found or if
100             *         the permission information was invalid
101             */
102            @Override
103            public void checkPermission(long groupId, String name, String primKey)
104                    throws PortalException {
105    
106                    checkPermission(getPermissionChecker(), groupId, name, primKey);
107            }
108    
109            protected boolean checkBaseModelPermission(
110                            PermissionChecker permissionChecker, long groupId, String className,
111                            long classPK)
112                    throws PortalException {
113    
114                    String actionId = ActionKeys.PERMISSIONS;
115    
116                    if (className.equals(Team.class.getName())) {
117                            className = Group.class.getName();
118    
119                            Team team = teamLocalService.fetchTeam(classPK);
120    
121                            classPK = team.getGroupId();
122    
123                            actionId = ActionKeys.MANAGE_TEAMS;
124                    }
125    
126                    BaseModelPermissionChecker baseModelPermissionChecker =
127                            _baseModelPermissionCheckers.get(className);
128    
129                    if (baseModelPermissionChecker != null) {
130                            baseModelPermissionChecker.checkBaseModel(
131                                    permissionChecker, groupId, classPK, actionId);
132    
133                            return true;
134                    }
135    
136                    return false;
137            }
138    
139            protected void checkPermission(
140                            PermissionChecker permissionChecker, long groupId, String name,
141                            String primKey)
142                    throws PortalException {
143    
144                    if (checkBaseModelPermission(
145                                    permissionChecker, groupId, name,
146                                    GetterUtil.getLong(primKey))) {
147    
148                            return;
149                    }
150    
151                    if ((primKey != null) &&
152                            primKey.contains(PortletConstants.LAYOUT_SEPARATOR)) {
153    
154                            int pos = primKey.indexOf(PortletConstants.LAYOUT_SEPARATOR);
155    
156                            long plid = GetterUtil.getLong(primKey.substring(0, pos));
157    
158                            String portletId = primKey.substring(
159                                    pos + PortletConstants.LAYOUT_SEPARATOR.length());
160    
161                            PortletPermissionUtil.check(
162                                    permissionChecker, plid, portletId, ActionKeys.CONFIGURATION);
163                    }
164                    else if (!permissionChecker.hasPermission(
165                                            groupId, name, primKey, ActionKeys.PERMISSIONS)) {
166    
167                            AssetRendererFactory<?> assetRendererFactory =
168                                    AssetRendererFactoryRegistryUtil.
169                                            getAssetRendererFactoryByClassName(name);
170    
171                            if (assetRendererFactory != null) {
172                                    try {
173                                            if (assetRendererFactory.hasPermission(
174                                                            permissionChecker, GetterUtil.getLong(primKey),
175                                                            ActionKeys.PERMISSIONS)) {
176    
177                                                    return;
178                                            }
179                                    }
180                                    catch (Exception e) {
181                                    }
182                            }
183    
184                            long ownerId = 0;
185    
186                            if (resourceBlockLocalService.isSupported(name)) {
187                                    PermissionedModel permissionedModel =
188                                            resourceBlockLocalService.getPermissionedModel(
189                                                    name, GetterUtil.getLong(primKey));
190    
191                                    if (permissionedModel instanceof GroupedModel) {
192                                            GroupedModel groupedModel = (GroupedModel)permissionedModel;
193    
194                                            ownerId = groupedModel.getUserId();
195                                    }
196                                    else if (permissionedModel instanceof AuditedModel) {
197                                            AuditedModel auditedModel = (AuditedModel)permissionedModel;
198    
199                                            ownerId = auditedModel.getUserId();
200                                    }
201                            }
202                            else {
203                                    ResourcePermission resourcePermission =
204                                            resourcePermissionLocalService.getResourcePermission(
205                                                    permissionChecker.getCompanyId(), name,
206                                                    ResourceConstants.SCOPE_INDIVIDUAL, primKey,
207                                                    permissionChecker.getOwnerRoleId());
208    
209                                    ownerId = resourcePermission.getOwnerId();
210                            }
211    
212                            if (permissionChecker.hasOwnerPermission(
213                                            permissionChecker.getCompanyId(), name, primKey, ownerId,
214                                            ActionKeys.PERMISSIONS)) {
215    
216                                    return;
217                            }
218    
219                            Role role = null;
220    
221                            if (name.equals(Role.class.getName())) {
222                                    long roleId = GetterUtil.getLong(primKey);
223    
224                                    role = rolePersistence.findByPrimaryKey(roleId);
225                            }
226    
227                            if ((role != null) && role.isTeam()) {
228                                    Team team = teamPersistence.findByPrimaryKey(role.getClassPK());
229    
230                                    TeamPermissionUtil.check(
231                                            permissionChecker, team, ActionKeys.PERMISSIONS);
232                            }
233                            else {
234                                    List<String> resourceActions =
235                                            ResourceActionsUtil.getResourceActions(name);
236    
237                                    if (!resourceActions.contains(ActionKeys.DEFINE_PERMISSIONS) ||
238                                            !permissionChecker.hasPermission(
239                                                    groupId, name, primKey,
240                                                    ActionKeys.DEFINE_PERMISSIONS)) {
241    
242                                            throw new PrincipalException.MustHavePermission(
243                                                    permissionChecker, name, Long.valueOf(primKey),
244                                                    ActionKeys.DEFINE_PERMISSIONS);
245                                    }
246                            }
247                    }
248            }
249    
250            private final Map<String, BaseModelPermissionChecker>
251                    _baseModelPermissionCheckers = new ConcurrentHashMap<>();
252            private ServiceTracker
253                    <BaseModelPermissionChecker, BaseModelPermissionChecker>
254                            _serviceTracker;
255    
256            private class BaseModelPermissionCheckerServiceTrackerCustomizer
257                    implements
258                            ServiceTrackerCustomizer
259                                    <BaseModelPermissionChecker, BaseModelPermissionChecker> {
260    
261                    @Override
262                    public BaseModelPermissionChecker addingService(
263                            ServiceReference<BaseModelPermissionChecker> serviceReference) {
264    
265                            Registry registry = RegistryUtil.getRegistry();
266    
267                            BaseModelPermissionChecker baseModelPermissionChecker =
268                                    registry.getService(serviceReference);
269    
270                            String modelClassName = GetterUtil.getString(
271                                    serviceReference.getProperty("model.class.name"));
272    
273                            _baseModelPermissionCheckers.put(
274                                    modelClassName, baseModelPermissionChecker);
275    
276                            return baseModelPermissionChecker;
277                    }
278    
279                    @Override
280                    public void modifiedService(
281                            ServiceReference<BaseModelPermissionChecker> serviceReference,
282                            BaseModelPermissionChecker baseModelPermissionChecker) {
283                    }
284    
285                    @Override
286                    public void removedService(
287                            ServiceReference<BaseModelPermissionChecker> serviceReference,
288                            BaseModelPermissionChecker baseModelPermissionChecker) {
289    
290                            Registry registry = RegistryUtil.getRegistry();
291    
292                            registry.ungetService(serviceReference);
293    
294                            String modelClassName = GetterUtil.getString(
295                                    serviceReference.getProperty("model.class.name"));
296    
297                            _baseModelPermissionCheckers.remove(modelClassName);
298                    }
299    
300            }
301    
302    }