001    /**
002     * Copyright (c) 2000-2012 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.verify;
016    
017    import com.liferay.portal.NoSuchResourceException;
018    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
019    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
020    import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
021    import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.util.GetterUtil;
025    import com.liferay.portal.kernel.util.StringBundler;
026    import com.liferay.portal.model.Group;
027    import com.liferay.portal.model.Layout;
028    import com.liferay.portal.model.Organization;
029    import com.liferay.portal.model.Permission;
030    import com.liferay.portal.model.Resource;
031    import com.liferay.portal.model.ResourceCode;
032    import com.liferay.portal.model.ResourceConstants;
033    import com.liferay.portal.model.ResourcePermission;
034    import com.liferay.portal.model.Role;
035    import com.liferay.portal.model.RoleConstants;
036    import com.liferay.portal.security.permission.ActionKeys;
037    import com.liferay.portal.security.permission.PermissionCacheUtil;
038    import com.liferay.portal.security.permission.ResourceActionsUtil;
039    import com.liferay.portal.service.LayoutLocalServiceUtil;
040    import com.liferay.portal.service.PermissionLocalServiceUtil;
041    import com.liferay.portal.service.ResourceActionLocalServiceUtil;
042    import com.liferay.portal.service.ResourceCodeLocalServiceUtil;
043    import com.liferay.portal.service.ResourceLocalServiceUtil;
044    import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
045    import com.liferay.portal.service.RoleLocalServiceUtil;
046    import com.liferay.portal.service.UserLocalServiceUtil;
047    import com.liferay.portal.service.impl.ResourcePermissionLocalServiceImpl;
048    import com.liferay.portal.util.PortalInstances;
049    import com.liferay.portal.util.PropsValues;
050    
051    import java.sql.Connection;
052    import java.sql.PreparedStatement;
053    import java.sql.ResultSet;
054    
055    import java.util.List;
056    
057    /**
058     * @author Tobias Kaefer
059     * @author Douglas Wong
060     * @author Matthew Kong
061     * @author Raymond Augé
062     */
063    public class VerifyPermission
064            extends VerifyProcess implements ResourceConstants {
065    
066            protected void checkPermissions() throws Exception {
067                    List<String> modelNames = ResourceActionsUtil.getModelNames();
068    
069                    for (String modelName : modelNames) {
070                            List<String> actionIds =
071                                    ResourceActionsUtil.getModelResourceActions(modelName);
072    
073                            if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
074                                    PermissionLocalServiceUtil.checkPermissions(
075                                            modelName, actionIds);
076                            }
077                            else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
078                                    ResourceActionLocalServiceUtil.checkResourceActions(
079                                            modelName, actionIds, true);
080                            }
081                    }
082            }
083    
084            protected void deleteDefaultPrivateLayoutPermissions() throws Exception {
085                    long[] companyIds = PortalInstances.getCompanyIdsBySQL();
086    
087                    for (long companyId : companyIds) {
088                            try {
089                                    if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
090                                            deleteDefaultPrivateLayoutPermissions_5(companyId);
091                                    }
092                                    else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
093                                            deleteDefaultPrivateLayoutPermissions_6(companyId);
094                                    }
095                                    else {
096                                            deleteDefaultPrivateLayoutPermissions_1to4(companyId);
097                                    }
098                            }
099                            catch (Exception e) {
100                                    if (_log.isDebugEnabled()) {
101                                            _log.debug(e, e);
102                                    }
103                            }
104                    }
105            }
106    
107            protected void deleteDefaultPrivateLayoutPermissions_1to4(long companyId)
108                    throws Exception {
109    
110                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
111    
112                    List<Permission> permissions =
113                            PermissionLocalServiceUtil.getUserPermissions(defaultUserId);
114    
115                    for (Permission permission : permissions) {
116                            Resource resource = ResourceLocalServiceUtil.getResource(
117                                    permission.getResourceId());
118    
119                            ResourceCode resourceCode =
120                                    ResourceCodeLocalServiceUtil.getResourceCode(
121                                            resource.getCodeId());
122    
123                            if (isPrivateLayout(
124                                            resourceCode.getName(), resource.getPrimKey())) {
125    
126                                    String[] actionIds = new String[] {permission.getActionId()};
127    
128                                    PermissionLocalServiceUtil.unsetUserPermissions(
129                                            defaultUserId, actionIds, permission.getResourceId());
130                            }
131                    }
132            }
133    
134            protected void deleteDefaultPrivateLayoutPermissions_5(long companyId)
135                    throws Exception {
136    
137                    Role role = RoleLocalServiceUtil.getRole(
138                            companyId, RoleConstants.GUEST);
139    
140                    List<Permission> permissions =
141                            PermissionLocalServiceUtil.getRolePermissions(role.getRoleId());
142    
143                    for (Permission permission : permissions) {
144                            Resource resource = ResourceLocalServiceUtil.getResource(
145                                    permission.getResourceId());
146    
147                            ResourceCode resourceCode =
148                                    ResourceCodeLocalServiceUtil.getResourceCode(
149                                            resource.getCodeId());
150    
151                            if (isPrivateLayout(
152                                            resourceCode.getName(), resource.getPrimKey())) {
153    
154                                    PermissionLocalServiceUtil.unsetRolePermission(
155                                            role.getRoleId(), permission.getPermissionId());
156                            }
157                    }
158            }
159    
160            protected void deleteDefaultPrivateLayoutPermissions_6(long companyId)
161                    throws Exception {
162    
163                    Role role = RoleLocalServiceUtil.getRole(
164                            companyId, RoleConstants.GUEST);
165    
166                    List<ResourcePermission> resourcePermissions =
167                            ResourcePermissionLocalServiceUtil.getRoleResourcePermissions(
168                                    role.getRoleId());
169    
170                    for (ResourcePermission resourcePermission : resourcePermissions) {
171                            if (isPrivateLayout(
172                                            resourcePermission.getName(),
173                                            resourcePermission.getPrimKey())) {
174    
175                                    ResourcePermissionLocalServiceUtil.deleteResourcePermission(
176                                            resourcePermission.getResourcePermissionId());
177                            }
178                    }
179            }
180    
181            @Override
182            protected void doVerify() throws Exception {
183                    deleteDefaultPrivateLayoutPermissions();
184    
185                    if ((PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM != 5) &&
186                            (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM != 6)) {
187    
188                            return;
189                    }
190    
191                    checkPermissions();
192                    fixLayoutRolePermissions();
193                    fixOrganizationRolePermissions();
194            }
195    
196            protected void fixLayoutRolePermissions() throws Exception {
197                    if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM != 6) {
198                            return;
199                    }
200    
201                    fixLayoutRolePermissions_6();
202    
203                    PermissionCacheUtil.clearCache();
204            }
205    
206            /**
207             * Fixes the case where layouts are missing the required owner role
208             * permissions. This can happen when upgrading from permission algorithms 1,
209             * 2, 3, and 4 to algorithm 6. This method will check for the presence of
210             * the owner role's resource permission for all layouts. The resource
211             * permission will be created if it does not exist. Both existing or newly
212             * created resource permission default action IDs for owner role are
213             * checked. If owner permissions for default action ID is missing, then the
214             * permission is given to the owner. See LPS-26191.
215             */
216            protected void fixLayoutRolePermissions_6() throws Exception {
217                    List<String> actions = ResourceActionsUtil.getModelResourceActions(
218                            Layout.class.getName());
219    
220                    String[] actionIds = actions.toArray(new String[actions.size()]);
221    
222                    Connection con = null;
223                    PreparedStatement ps = null;
224                    ResultSet rs = null;
225    
226                    try {
227                            con = DataAccess.getUpgradeOptimizedConnection();
228    
229                            StringBundler sb = new StringBundler(4);
230    
231                            sb.append("select Layout.companyId as companyId, Layout.plid as ");
232                            sb.append("primKey, Role_.roleId as ownerRoleId from Role_, ");
233                            sb.append("Layout where Role_.companyId = Layout.companyId and ");
234                            sb.append("Role_.name = ?");
235    
236                            ps = con.prepareStatement(sb.toString());
237    
238                            ps.setString(1, RoleConstants.OWNER);
239    
240                            rs = ps.executeQuery();
241    
242                            while (rs.next()) {
243                                    long companyId = rs.getLong("companyId");
244                                    String primKey = String.valueOf(rs.getLong("primKey"));
245                                    long ownerRoleId = rs.getLong("ownerRoleId");
246    
247                                    fixLayoutRolePermissions_6(
248                                            companyId, primKey, ownerRoleId, actionIds);
249                            }
250                    }
251                    finally {
252                            DataAccess.cleanUp(con, ps, rs);
253                    }
254            }
255    
256            protected void fixLayoutRolePermissions_6(
257                            long companyId, String primKey, long ownerRoleId,
258                            String[] actionIds)
259                    throws Exception {
260    
261                    Connection con = null;
262                    PreparedStatement ps = null;
263                    ResultSet rs = null;
264    
265                    try {
266                            con = DataAccess.getUpgradeOptimizedConnection();
267    
268                            StringBundler sb = new StringBundler(4);
269    
270                            sb.append("select count(*) from ResourcePermission where ");
271                            sb.append("ResourcePermission.companyId = ? and ");
272                            sb.append("ResourcePermission.primKey = ? and ");
273                            sb.append("ResourcePermission.roleId = ?");
274    
275                            ps = con.prepareStatement(sb.toString());
276    
277                            ps.setLong(1, companyId);
278                            ps.setString(2, primKey);
279                            ps.setLong(3, ownerRoleId);
280    
281                            rs = ps.executeQuery();
282    
283                            if (!rs.next()) {
284                                    return;
285                            }
286    
287                            int count = rs.getInt(1);
288    
289                            if (count > 0) {
290                                    return;
291                            }
292    
293                            ResourcePermissionLocalServiceUtil.setResourcePermissions(
294                                    companyId, Layout.class.getName(), SCOPE_INDIVIDUAL, primKey,
295                                    ownerRoleId, actionIds);
296    
297                            ResourcePermissionLocalServiceUtil.getResourcePermission(
298                                    companyId, Layout.class.getName(), SCOPE_INDIVIDUAL, primKey,
299                                    ownerRoleId);
300                    }
301                    finally {
302                            DataAccess.cleanUp(con, ps, rs);
303                    }
304            }
305    
306            protected void fixOrganizationRolePermissions() throws Exception {
307                    if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
308                            fixOrganizationRolePermissions_5();
309                    }
310                    else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
311                            fixOrganizationRolePermissions_6();
312                    }
313    
314                    PermissionCacheUtil.clearCache();
315            }
316    
317            protected void fixOrganizationRolePermissions_5() throws Exception {
318                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
319                            ResourceCode.class);
320    
321                    dynamicQuery.add(
322                            RestrictionsFactoryUtil.eq("name", Organization.class.getName()));
323    
324                    List<ResourceCode> resouceCodes =
325                            ResourceCodeLocalServiceUtil.dynamicQuery(dynamicQuery);
326    
327                    for (ResourceCode resourceCode : resouceCodes) {
328                            dynamicQuery = DynamicQueryFactoryUtil.forClass(Resource.class);
329    
330                            dynamicQuery.add(
331                                    RestrictionsFactoryUtil.eq("codeId", resourceCode.getCodeId()));
332    
333                            List<Resource> resources = ResourceLocalServiceUtil.dynamicQuery(
334                                    dynamicQuery);
335    
336                            for (Resource resource : resources) {
337                                    dynamicQuery = DynamicQueryFactoryUtil.forClass(
338                                            Permission.class);
339    
340                                    dynamicQuery.add(
341                                            RestrictionsFactoryUtil.eq(
342                                                    "resourceId", resource.getResourceId()));
343    
344                                    List<Permission> permissions =
345                                            PermissionLocalServiceUtil.dynamicQuery(dynamicQuery);
346    
347                                    processPermissions(resource, permissions);
348                            }
349                    }
350            }
351    
352            protected void fixOrganizationRolePermissions_6() throws Exception {
353                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
354                            ResourcePermission.class);
355    
356                    dynamicQuery.add(
357                            RestrictionsFactoryUtil.eq("name", Organization.class.getName()));
358    
359                    List<ResourcePermission> resourcePermissions =
360                            ResourcePermissionLocalServiceUtil.dynamicQuery(dynamicQuery);
361    
362                    for (ResourcePermission resourcePermission : resourcePermissions) {
363                            ResourcePermission groupResourcePermission = null;
364    
365                            try {
366                                    groupResourcePermission =
367                                            ResourcePermissionLocalServiceUtil.getResourcePermission(
368                                                    resourcePermission.getCompanyId(),
369                                                    Group.class.getName(), resourcePermission.getScope(),
370                                                    resourcePermission.getPrimKey(),
371                                                    resourcePermission.getRoleId());
372                            }
373                            catch (Exception e) {
374                                    ResourcePermissionLocalServiceUtil.setResourcePermissions(
375                                            resourcePermission.getCompanyId(), Group.class.getName(),
376                                            resourcePermission.getScope(),
377                                            resourcePermission.getPrimKey(),
378                                            resourcePermission.getRoleId(),
379                                            ResourcePermissionLocalServiceImpl.EMPTY_ACTION_IDS);
380    
381                                    groupResourcePermission =
382                                            ResourcePermissionLocalServiceUtil.getResourcePermission(
383                                                    resourcePermission.getCompanyId(),
384                                                    Group.class.getName(), resourcePermission.getScope(),
385                                                    resourcePermission.getPrimKey(),
386                                                    resourcePermission.getRoleId());
387                            }
388    
389                            long organizationActions = resourcePermission.getActionIds();
390                            long groupActions = groupResourcePermission.getActionIds();
391    
392                            for (Object[] actionIdToMask : _ORGANIZATION_ACTION_IDS_TO_MASKS) {
393                                    long organizationActionMask = (Long)actionIdToMask[1];
394                                    long groupActionMask = (Long)actionIdToMask[2];
395    
396                                    if ((organizationActions & organizationActionMask) ==
397                                                    organizationActionMask) {
398    
399                                            organizationActions =
400                                                    organizationActions & (~organizationActionMask);
401                                            groupActions = groupActions | groupActionMask;
402                                    }
403                            }
404    
405                            try {
406                                    resourcePermission.resetOriginalValues();
407    
408                                    resourcePermission.setActionIds(organizationActions);
409    
410                                    ResourcePermissionLocalServiceUtil.updateResourcePermission(
411                                            resourcePermission, false);
412    
413                                    groupResourcePermission.resetOriginalValues();
414                                    groupResourcePermission.setActionIds(groupActions);
415    
416                                    ResourcePermissionLocalServiceUtil.updateResourcePermission(
417                                            groupResourcePermission, false);
418                            }
419                            catch (Exception e) {
420                                    _log.error(e, e);
421                            }
422                    }
423            }
424    
425            protected boolean isPrivateLayout(String name, String primKey)
426                    throws Exception {
427    
428                    if (!name.equals(Layout.class.getName())) {
429                            return false;
430                    }
431    
432                    long plid = GetterUtil.getLong(primKey);
433    
434                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
435    
436                    if (layout.isPublicLayout() || layout.isTypeControlPanel()) {
437                            return false;
438                    }
439    
440                    return true;
441            }
442    
443            protected void processPermissions(
444                            Resource resource, List<Permission> permissions)
445                    throws Exception {
446    
447                    Resource groupResource = null;
448    
449                    try {
450                            groupResource = ResourceLocalServiceUtil.getResource(
451                                    resource.getCompanyId(), Group.class.getName(),
452                                    resource.getScope(), resource.getPrimKey());
453                    }
454                    catch (NoSuchResourceException nsre) {
455                            groupResource = ResourceLocalServiceUtil.addResource(
456                                    resource.getCompanyId(), Group.class.getName(),
457                                    resource.getScope(), resource.getPrimKey());
458                    }
459    
460                    for (Permission permission : permissions) {
461                            for (Object[] actionIdToMask : _ORGANIZATION_ACTION_IDS_TO_MASKS) {
462                                    String actionId = (String)actionIdToMask[0];
463                                    long mask = (Long)actionIdToMask[2];
464    
465                                    if (!actionId.equals(permission.getActionId())) {
466                                            continue;
467                                    }
468    
469                                    try {
470                                            if (mask != 0L) {
471                                                    permission.resetOriginalValues();
472    
473                                                    permission.setResourceId(groupResource.getResourceId());
474    
475                                                    PermissionLocalServiceUtil.updatePermission(
476                                                            permission, false);
477                                            }
478                                            else {
479                                                    PermissionLocalServiceUtil.deletePermission(
480                                                            permission.getPermissionId());
481                                            }
482                                    }
483                                    catch (Exception e) {
484                                            _log.error(e, e);
485                                    }
486    
487                                    break;
488                            }
489                    }
490            }
491    
492            private static final Object[][] _ORGANIZATION_ACTION_IDS_TO_MASKS =
493                    new Object[][] {
494                            new Object[] {"APPROVE_PROPOSAL", 2L, 0L},
495                            new Object[] {ActionKeys.ASSIGN_MEMBERS, 4L, 4L},
496                            new Object[] {"ASSIGN_REVIEWER", 8L, 0L},
497                            new Object[] {ActionKeys.MANAGE_ARCHIVED_SETUPS, 128L, 128L},
498                            new Object[] {ActionKeys.MANAGE_LAYOUTS, 256L, 256L},
499                            new Object[] {ActionKeys.MANAGE_STAGING, 512L, 512L},
500                            new Object[] {ActionKeys.MANAGE_TEAMS, 2048L, 1024L},
501                            new Object[] {ActionKeys.PUBLISH_STAGING, 16384L, 4096L}
502                    };
503    
504            private static Log _log = LogFactoryUtil.getLog(VerifyPermission.class);
505    
506    }