001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.service.permission;
016    
017    import com.liferay.portal.NoSuchResourceException;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.util.Validator;
021    import com.liferay.portal.model.Group;
022    import com.liferay.portal.model.Layout;
023    import com.liferay.portal.model.LayoutConstants;
024    import com.liferay.portal.model.Organization;
025    import com.liferay.portal.model.ResourceConstants;
026    import com.liferay.portal.model.ResourcePermission;
027    import com.liferay.portal.model.User;
028    import com.liferay.portal.security.auth.PrincipalException;
029    import com.liferay.portal.security.permission.ActionKeys;
030    import com.liferay.portal.security.permission.PermissionChecker;
031    import com.liferay.portal.service.GroupLocalServiceUtil;
032    import com.liferay.portal.service.LayoutLocalServiceUtil;
033    import com.liferay.portal.service.OrganizationLocalServiceUtil;
034    import com.liferay.portal.service.ResourceLocalServiceUtil;
035    import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
036    import com.liferay.portal.service.UserLocalServiceUtil;
037    import com.liferay.portal.util.PropsValues;
038    import com.liferay.portlet.sites.util.SitesUtil;
039    
040    import java.util.List;
041    
042    /**
043     * @author Charles May
044     * @author Brian Wing Shun Chan
045     * @author Raymond Augé
046     */
047    public class LayoutPermissionImpl implements LayoutPermission {
048    
049            public void check(
050                            PermissionChecker permissionChecker, Layout layout, String actionId)
051                    throws PortalException, SystemException {
052    
053                    if (!contains(permissionChecker, layout, actionId)) {
054                            throw new PrincipalException();
055                    }
056            }
057    
058            public void check(
059                            PermissionChecker permissionChecker, long groupId,
060                            boolean privateLayout, long layoutId, String actionId)
061                    throws PortalException, SystemException {
062    
063                    if (!contains(
064                                    permissionChecker, groupId, privateLayout, layoutId,
065                                    actionId)) {
066    
067                            throw new PrincipalException();
068                    }
069            }
070    
071            public void check(
072                            PermissionChecker permissionChecker, long plid, String actionId)
073                    throws PortalException, SystemException {
074    
075                    if (!contains(permissionChecker, plid, actionId)) {
076                            throw new PrincipalException();
077                    }
078            }
079    
080            public boolean contains(
081                            PermissionChecker permissionChecker, Layout layout,
082                            boolean checkResourcePermission, String actionId)
083                    throws PortalException, SystemException {
084    
085                    return contains(
086                            permissionChecker, layout, null, checkResourcePermission, actionId);
087            }
088    
089            public boolean contains(
090                            PermissionChecker permissionChecker, Layout layout, String actionId)
091                    throws PortalException, SystemException {
092    
093                    return contains(permissionChecker, layout, null, actionId);
094            }
095    
096            public boolean contains(
097                            PermissionChecker permissionChecker, Layout layout,
098                            String controlPanelCategory, boolean checkResourcePermission,
099                            String actionId)
100                    throws PortalException, SystemException {
101    
102                    return containsWithViewableGroup(
103                            permissionChecker, layout, controlPanelCategory,
104                            checkResourcePermission, actionId);
105            }
106    
107            public boolean contains(
108                            PermissionChecker permissionChecker, Layout layout,
109                            String controlPanelCategory, String actionId)
110                    throws PortalException, SystemException {
111    
112                    return contains(
113                            permissionChecker, layout, controlPanelCategory, false, actionId);
114            }
115    
116            public boolean contains(
117                            PermissionChecker permissionChecker, long groupId,
118                            boolean privateLayout, long layoutId, String actionId)
119                    throws PortalException, SystemException {
120    
121                    return contains(
122                            permissionChecker, groupId, privateLayout, layoutId, null,
123                            actionId);
124            }
125    
126            public boolean contains(
127                            PermissionChecker permissionChecker, long groupId,
128                            boolean privateLayout, long layoutId, String controlPanelCategory,
129                            String actionId)
130                    throws PortalException, SystemException {
131    
132                    Layout layout = LayoutLocalServiceUtil.getLayout(
133                            groupId, privateLayout, layoutId);
134    
135                    if (isAttemptToModifyLockedLayout(layout, actionId)) {
136                            return false;
137                    }
138    
139                    return contains(
140                            permissionChecker, layout, controlPanelCategory, actionId);
141            }
142    
143            public boolean contains(
144                            PermissionChecker permissionChecker, long plid, String actionId)
145                    throws PortalException, SystemException {
146    
147                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
148    
149                    return contains(permissionChecker, layout, actionId);
150            }
151    
152            protected boolean containsWithoutViewableGroup(
153                            PermissionChecker permissionChecker, Layout layout,
154                            String controlPanelCategory, boolean checkResourcePermission,
155                            String actionId)
156                    throws PortalException, SystemException {
157    
158                    if ((layout.isPrivateLayout() &&
159                             !PropsValues.LAYOUT_USER_PRIVATE_LAYOUTS_MODIFIABLE) ||
160                            (layout.isPublicLayout() &&
161                             !PropsValues.LAYOUT_USER_PUBLIC_LAYOUTS_MODIFIABLE)) {
162    
163                            if (actionId.equals(ActionKeys.UPDATE)) {
164                                    Group group = GroupLocalServiceUtil.getGroup(
165                                            layout.getGroupId());
166    
167                                    if (group.isUser()) {
168                                            return false;
169                                    }
170                            }
171                    }
172    
173                    Group group = layout.getGroup();
174    
175                    if (!group.isLayoutSetPrototype() &&
176                            isAttemptToModifyLockedLayout(layout, actionId)) {
177    
178                            return false;
179                    }
180    
181                    User user = UserLocalServiceUtil.getUserById(
182                            permissionChecker.getUserId());
183    
184                    if ((PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) &&
185                            !user.isDefaultUser() && !group.isUser()) {
186    
187                            // This is new way of doing an ownership check without having to
188                            // have a userId field on the model. When the instance model was
189                            // first created, we set the user's userId as the ownerId of the
190                            // individual scope ResourcePermission of the Owner Role.
191                            // Therefore, ownership can be determined by obtaining the Owner
192                            // role ResourcePermission for the current instance model and
193                            // testing it with the hasOwnerPermission call.
194    
195                            ResourcePermission resourcePermission =
196                                    ResourcePermissionLocalServiceUtil.getResourcePermission(
197                                            layout.getCompanyId(), Layout.class.getName(),
198                                            ResourceConstants.SCOPE_INDIVIDUAL,
199                                            String.valueOf(layout.getPlid()),
200                                            permissionChecker.getOwnerRoleId());
201    
202                            if (permissionChecker.hasOwnerPermission(
203                                            layout.getCompanyId(), Layout.class.getName(),
204                                            String.valueOf(layout.getPlid()),
205                                            resourcePermission.getOwnerId(), actionId)) {
206    
207                                    return true;
208                            }
209                    }
210    
211                    if (GroupPermissionUtil.contains(
212                                    permissionChecker, layout.getGroupId(),
213                                    ActionKeys.MANAGE_LAYOUTS)) {
214    
215                            return true;
216                    }
217                    else if (actionId.equals(ActionKeys.ADD_LAYOUT) &&
218                                     GroupPermissionUtil.contains(
219                                             permissionChecker, layout.getGroupId(),
220                                             ActionKeys.ADD_LAYOUT)) {
221    
222                            return true;
223                    }
224    
225                    if (PropsValues.PERMISSIONS_VIEW_DYNAMIC_INHERITANCE &&
226                            !actionId.equals(ActionKeys.VIEW)) {
227    
228                            // Check upward recursively to see if any pages above grant the
229                            // action
230    
231                            long parentLayoutId = layout.getParentLayoutId();
232    
233                            while (parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
234                                    Layout parentLayout = LayoutLocalServiceUtil.getLayout(
235                                            layout.getGroupId(), layout.isPrivateLayout(),
236                                            layout.getParentLayoutId());
237    
238                                    if (contains(
239                                                    permissionChecker, parentLayout, controlPanelCategory,
240                                                    actionId)) {
241    
242                                            return true;
243                                    }
244    
245                                    parentLayoutId = parentLayout.getParentLayoutId();
246                            }
247                    }
248    
249                    try {
250                            if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
251                                    if (ResourcePermissionLocalServiceUtil.
252                                                    getResourcePermissionsCount(
253                                                            layout.getCompanyId(), Layout.class.getName(),
254                                                            ResourceConstants.SCOPE_INDIVIDUAL,
255                                                            String.valueOf(layout.getPlid())) == 0) {
256    
257                                            throw new NoSuchResourceException();
258                                    }
259                            }
260                            else {
261                                    ResourceLocalServiceUtil.getResource(
262                                            layout.getCompanyId(), Layout.class.getName(),
263                                            ResourceConstants.SCOPE_INDIVIDUAL,
264                                            String.valueOf(layout.getPlid()));
265                            }
266                    }
267                    catch (NoSuchResourceException nsre) {
268                            boolean addGroupPermission = true;
269                            boolean addGuestPermission = true;
270    
271                            if (layout.isPrivateLayout()) {
272                                    addGuestPermission = false;
273                            }
274    
275                            ResourceLocalServiceUtil.addResources(
276                                    layout.getCompanyId(), layout.getGroupId(), 0,
277                                    Layout.class.getName(), layout.getPlid(), false,
278                                    addGroupPermission, addGuestPermission);
279                    }
280    
281                    return permissionChecker.hasPermission(
282                            layout.getGroupId(), Layout.class.getName(), layout.getPlid(),
283                            actionId);
284            }
285    
286            protected boolean containsWithViewableGroup(
287                            PermissionChecker permissionChecker, Layout layout,
288                            String controlPanelCategory, boolean checkResourcePermission,
289                            String actionId)
290                    throws PortalException, SystemException {
291    
292                    if (actionId.equals(ActionKeys.VIEW)) {
293                            return isViewableGroup(
294                                    permissionChecker, layout, controlPanelCategory,
295                                    checkResourcePermission);
296                    }
297    
298                    return containsWithoutViewableGroup(
299                            permissionChecker, layout, controlPanelCategory,
300                            checkResourcePermission, actionId);
301            }
302    
303            protected boolean isAttemptToModifyLockedLayout(
304                    Layout layout, String actionId) {
305    
306                    if (SitesUtil.isLayoutLocked(layout) &&
307                            (ActionKeys.CUSTOMIZE.equals(actionId) ||
308                             ActionKeys.UPDATE.equals(actionId))) {
309    
310                            return true;
311                    }
312    
313                    return false;
314            }
315    
316            protected boolean isViewableGroup(
317                            PermissionChecker permissionChecker, Layout layout,
318                            String controlPanelCategory, boolean checkResourcePermission)
319                    throws PortalException, SystemException {
320    
321                    Group group = GroupLocalServiceUtil.getGroup(layout.getGroupId());
322    
323                    // Inactive sites are not viewable
324    
325                    if (!group.isActive()) {
326                            return false;
327                    }
328                    else if (group.isStagingGroup()) {
329                            Group liveGroup = group.getLiveGroup();
330    
331                            if (!liveGroup.isActive()) {
332                                    return false;
333                            }
334                    }
335    
336                    // User private layouts are only viewable by the user and anyone who can
337                    // update the user. The user must also be active.
338    
339                    if (group.isUser()) {
340                            long groupUserId = group.getClassPK();
341    
342                            if (groupUserId == permissionChecker.getUserId()) {
343                                    return true;
344                            }
345                            else {
346                                    User groupUser = UserLocalServiceUtil.getUserById(groupUserId);
347    
348                                    if (!groupUser.isActive()) {
349                                            return false;
350                                    }
351    
352                                    if (layout.isPrivateLayout()) {
353                                            if (UserPermissionUtil.contains(
354                                                            permissionChecker, groupUserId,
355                                                            groupUser.getOrganizationIds(),
356                                                            ActionKeys.MANAGE_LAYOUTS) ||
357                                                    UserPermissionUtil.contains(
358                                                            permissionChecker, groupUserId,
359                                                            groupUser.getOrganizationIds(),
360                                                            ActionKeys.UPDATE)) {
361    
362                                                    return true;
363                                            }
364                                            else {
365                                                    return false;
366                                            }
367                                    }
368                            }
369                    }
370    
371                    // If the current group is staging, only users with editorial rights
372                    // can access it
373    
374                    if (group.isStagingGroup()) {
375                            if (GroupPermissionUtil.contains(
376                                            permissionChecker, group.getGroupId(),
377                                            ActionKeys.VIEW_STAGING)) {
378    
379                                    return true;
380                            }
381    
382                            return false;
383                    }
384    
385                    if (containsWithoutViewableGroup(
386                                    permissionChecker, layout, controlPanelCategory,
387                                    checkResourcePermission, ActionKeys.VIEW)) {
388    
389                            return true;
390                    }
391    
392                    // Control panel layouts are only viewable by authenticated users
393    
394                    if (group.isControlPanel()) {
395                            if (PortalPermissionUtil.contains(
396                                            permissionChecker, ActionKeys.VIEW_CONTROL_PANEL)) {
397    
398                                    return true;
399                            }
400                            else {
401                                    if (Validator.isNotNull(controlPanelCategory)) {
402                                            return true;
403                                    }
404                                    else {
405                                            return false;
406                                    }
407                            }
408                    }
409    
410                    // Site layouts are only viewable by users who are members of the site
411                    // or by users who can update the site
412    
413                    if (group.isSite()) {
414                            if (GroupPermissionUtil.contains(
415                                            permissionChecker, group.getGroupId(),
416                                            ActionKeys.MANAGE_LAYOUTS) ||
417                                     GroupPermissionUtil.contains(
418                                            permissionChecker, group.getGroupId(),
419                                            ActionKeys.UPDATE)) {
420    
421                                    return true;
422                            }
423                    }
424    
425                    // Organization site layouts are also viewable by users who belong to
426                    // the organization or by users who can update organization
427    
428                    if (group.isCompany()) {
429                            return false;
430                    }
431                    else if (group.isLayoutPrototype()) {
432                            if (LayoutPrototypePermissionUtil.contains(
433                                            permissionChecker, group.getClassPK(), ActionKeys.VIEW)) {
434    
435                                    return true;
436                            }
437                            else {
438                                    return false;
439                            }
440                    }
441                    else if (group.isLayoutSetPrototype()) {
442                            if (LayoutSetPrototypePermissionUtil.contains(
443                                            permissionChecker, group.getClassPK(), ActionKeys.VIEW)) {
444    
445                                    return true;
446                            }
447                            else {
448                                    return false;
449                            }
450                    }
451                    else if (group.isOrganization()) {
452                            long organizationId = group.getOrganizationId();
453    
454                            if (OrganizationLocalServiceUtil.hasUserOrganization(
455                                            permissionChecker.getUserId(), organizationId, false, true,
456                                            false)) {
457    
458                                    return true;
459                            }
460                            else if (OrganizationPermissionUtil.contains(
461                                                    permissionChecker, organizationId, ActionKeys.UPDATE)) {
462    
463                                    return true;
464                            }
465    
466                            if (!PropsValues.ORGANIZATIONS_MEMBERSHIP_STRICT) {
467                                    List<Organization> userOrgs =
468                                            OrganizationLocalServiceUtil.getUserOrganizations(
469                                                    permissionChecker.getUserId(), true);
470    
471                                    for (Organization organization : userOrgs) {
472                                            for (Organization ancestorOrganization :
473                                                            organization.getAncestors()) {
474    
475                                                    if (organizationId ==
476                                                                    ancestorOrganization.getOrganizationId()) {
477    
478                                                            return true;
479                                                    }
480                                            }
481                                    }
482                            }
483                    }
484    
485                    return false;
486            }
487    
488    }