001    /**
002     * Copyright (c) 2000-2013 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.kernel.dao.db.DB;
018    import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
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.EntityCacheUtil;
022    import com.liferay.portal.kernel.dao.orm.FinderCacheUtil;
023    import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.kernel.util.GetterUtil;
027    import com.liferay.portal.kernel.util.StringBundler;
028    import com.liferay.portal.kernel.util.StringPool;
029    import com.liferay.portal.kernel.util.StringUtil;
030    import com.liferay.portal.model.Group;
031    import com.liferay.portal.model.Layout;
032    import com.liferay.portal.model.LayoutConstants;
033    import com.liferay.portal.model.Organization;
034    import com.liferay.portal.model.PortletConstants;
035    import com.liferay.portal.model.ResourceConstants;
036    import com.liferay.portal.model.ResourcePermission;
037    import com.liferay.portal.model.Role;
038    import com.liferay.portal.model.RoleConstants;
039    import com.liferay.portal.model.User;
040    import com.liferay.portal.model.UserGroup;
041    import com.liferay.portal.security.permission.ActionKeys;
042    import com.liferay.portal.security.permission.PermissionCacheUtil;
043    import com.liferay.portal.security.permission.ResourceActionsUtil;
044    import com.liferay.portal.service.LayoutLocalServiceUtil;
045    import com.liferay.portal.service.ResourceActionLocalServiceUtil;
046    import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
047    import com.liferay.portal.service.RoleLocalServiceUtil;
048    import com.liferay.portal.service.impl.ResourcePermissionLocalServiceImpl;
049    import com.liferay.portal.util.PortalInstances;
050    import com.liferay.portal.util.PortalUtil;
051    
052    import java.sql.SQLException;
053    
054    import java.util.ArrayList;
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 extends VerifyProcess {
064    
065            protected void checkPermissions() throws Exception {
066                    List<String> modelNames = ResourceActionsUtil.getModelNames();
067    
068                    for (String modelName : modelNames) {
069                            List<String> actionIds =
070                                    ResourceActionsUtil.getModelResourceActions(modelName);
071    
072                                    ResourceActionLocalServiceUtil.checkResourceActions(
073                                            modelName, actionIds, true);
074                    }
075    
076                    List<String> portletNames = ResourceActionsUtil.getPortletNames();
077    
078                    for (String portletName : portletNames) {
079                            List<String> actionIds =
080                                    ResourceActionsUtil.getPortletResourceActions(portletName);
081    
082                            ResourceActionLocalServiceUtil.checkResourceActions(
083                                    portletName, actionIds, true);
084                    }
085            }
086    
087            protected void deleteDefaultPrivateLayoutPermissions() throws Exception {
088                    long[] companyIds = PortalInstances.getCompanyIdsBySQL();
089    
090                    for (long companyId : companyIds) {
091                            try {
092                                    deleteDefaultPrivateLayoutPermissions_6(companyId);
093                            }
094                            catch (Exception e) {
095                                    if (_log.isDebugEnabled()) {
096                                            _log.debug(e, e);
097                                    }
098                            }
099                    }
100            }
101    
102            protected void deleteDefaultPrivateLayoutPermissions_6(long companyId)
103                    throws Exception {
104    
105                    Role role = RoleLocalServiceUtil.getRole(
106                            companyId, RoleConstants.GUEST);
107    
108                    List<ResourcePermission> resourcePermissions =
109                            ResourcePermissionLocalServiceUtil.getRoleResourcePermissions(
110                                    role.getRoleId());
111    
112                    for (ResourcePermission resourcePermission : resourcePermissions) {
113                            if (isPrivateLayout(
114                                            resourcePermission.getName(),
115                                            resourcePermission.getPrimKey())) {
116    
117                                    ResourcePermissionLocalServiceUtil.deleteResourcePermission(
118                                            resourcePermission.getResourcePermissionId());
119                            }
120                    }
121            }
122    
123            @Override
124            protected void doVerify() throws Exception {
125                    deleteDefaultPrivateLayoutPermissions();
126    
127                    checkPermissions();
128                    fixOrganizationRolePermissions();
129                    fixUserDefaultRolePermissions();
130            }
131    
132            protected void fixOrganizationRolePermissions() throws Exception {
133                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
134                            ResourcePermission.class);
135    
136                    dynamicQuery.add(
137                            RestrictionsFactoryUtil.eq("name", Organization.class.getName()));
138    
139                    List<ResourcePermission> resourcePermissions =
140                            ResourcePermissionLocalServiceUtil.dynamicQuery(dynamicQuery);
141    
142                    for (ResourcePermission resourcePermission : resourcePermissions) {
143                            ResourcePermission groupResourcePermission = null;
144    
145                            try {
146                                    groupResourcePermission =
147                                            ResourcePermissionLocalServiceUtil.getResourcePermission(
148                                                    resourcePermission.getCompanyId(),
149                                                    Group.class.getName(), resourcePermission.getScope(),
150                                                    resourcePermission.getPrimKey(),
151                                                    resourcePermission.getRoleId());
152                            }
153                            catch (Exception e) {
154                                    ResourcePermissionLocalServiceUtil.setResourcePermissions(
155                                            resourcePermission.getCompanyId(), Group.class.getName(),
156                                            resourcePermission.getScope(),
157                                            resourcePermission.getPrimKey(),
158                                            resourcePermission.getRoleId(),
159                                            ResourcePermissionLocalServiceImpl.EMPTY_ACTION_IDS);
160    
161                                    groupResourcePermission =
162                                            ResourcePermissionLocalServiceUtil.getResourcePermission(
163                                                    resourcePermission.getCompanyId(),
164                                                    Group.class.getName(), resourcePermission.getScope(),
165                                                    resourcePermission.getPrimKey(),
166                                                    resourcePermission.getRoleId());
167                            }
168    
169                            for (String actionId : _DEPRECATED_ORGANIZATION_ACTION_IDS) {
170                                    if (resourcePermission.hasActionId(actionId)) {
171                                            resourcePermission.removeResourceAction(actionId);
172    
173                                            groupResourcePermission.addResourceAction(actionId);
174                                    }
175                            }
176    
177                            try {
178                                    resourcePermission.resetOriginalValues();
179    
180                                    ResourcePermissionLocalServiceUtil.updateResourcePermission(
181                                            resourcePermission);
182    
183                                    groupResourcePermission.resetOriginalValues();
184    
185                                    ResourcePermissionLocalServiceUtil.updateResourcePermission(
186                                            groupResourcePermission);
187                            }
188                            catch (Exception e) {
189                                    _log.error(e, e);
190                            }
191                    }
192    
193                    PermissionCacheUtil.clearResourceCache();
194            }
195    
196            protected void fixUserDefaultRolePermissions() throws Exception {
197                    DB db = DBFactoryUtil.getDB();
198    
199                    String dbType = db.getType();
200    
201                    try {
202                            long userClassNameId = PortalUtil.getClassNameId(User.class);
203                            long userGroupClassNameId = PortalUtil.getClassNameId(
204                                    UserGroup.class);
205    
206                            long[] companyIds = PortalInstances.getCompanyIdsBySQL();
207    
208                            if (dbType.equals(DB.TYPE_MYSQL)) {
209                                    fixUserDefaultRolePermissionsMySQL(
210                                            userClassNameId, userGroupClassNameId, companyIds);
211    
212                                    return;
213                            }
214    
215                            if (dbType.equals(DB.TYPE_ORACLE)) {
216                                    fixUserDefaultRolePermissionsOracle(
217                                            userClassNameId, userGroupClassNameId, companyIds);
218    
219                                    return;
220                            }
221    
222                            for (long companyId : companyIds) {
223                                    Role powerUserRole = RoleLocalServiceUtil.getRole(
224                                            companyId, RoleConstants.POWER_USER);
225                                    Role userRole = RoleLocalServiceUtil.getRole(
226                                            companyId, RoleConstants.USER);
227    
228                                    StringBundler sb = new StringBundler(20);
229    
230                                    sb.append("update ResourcePermission set roleId = ");
231                                    sb.append(userRole.getRoleId());
232                                    sb.append(" where resourcePermissionId in (select ");
233                                    sb.append("resourcePermissionId from ResourcePermission ");
234                                    sb.append("inner join Layout on ResourcePermission.companyId ");
235                                    sb.append("= Layout.companyId and ResourcePermission.primKey ");
236                                    sb.append("like replace('[$PLID$]_LAYOUT_%', '[$PLID$]', ");
237                                    sb.append("cast_text(Layout.plid)) inner join Group_ on ");
238                                    sb.append("Layout.groupId = Group_.groupId where ");
239                                    sb.append("ResourcePermission.scope = ");
240                                    sb.append(ResourceConstants.SCOPE_INDIVIDUAL);
241                                    sb.append(" and ResourcePermission.roleId = ");
242                                    sb.append(powerUserRole.getRoleId());
243                                    sb.append(" and (Group_.classNameId = ");
244                                    sb.append(userClassNameId);
245                                    sb.append(" or Group_.classNameId = ");
246                                    sb.append(userGroupClassNameId);
247                                    sb.append(") and Layout.type_ = '");
248                                    sb.append(LayoutConstants.TYPE_PORTLET);
249                                    sb.append("')");
250    
251                                    runSQL(sb.toString());
252                            }
253                    }
254                    finally {
255                            EntityCacheUtil.clearCache();
256                            FinderCacheUtil.clearCache();
257                    }
258            }
259    
260            protected void fixUserDefaultRolePermissionsMySQL(
261                            long userClassNameId, long userGroupClassNameId, long[] companyIds)
262                    throws Exception {
263    
264                    for (long companyId : companyIds) {
265                            Role powerUserRole = RoleLocalServiceUtil.getRole(
266                                    companyId, RoleConstants.POWER_USER);
267                            Role userRole = RoleLocalServiceUtil.getRole(
268                                    companyId, RoleConstants.USER);
269    
270                            StringBundler sb = new StringBundler(19);
271    
272                            sb.append("update ResourcePermission inner join Layout on ");
273                            sb.append("ResourcePermission.companyId = Layout.companyId and ");
274                            sb.append("ResourcePermission.primKey like ");
275                            sb.append("replace('[$PLID$]_LAYOUT_%', '[$PLID$]', ");
276                            sb.append("cast_text(Layout.plid)) inner join Group_ on ");
277                            sb.append("Layout.groupId = Group_.groupId set ");
278                            sb.append("ResourcePermission.roleId = ");
279                            sb.append(userRole.getRoleId());
280                            sb.append(" where ResourcePermission.scope = ");
281                            sb.append(ResourceConstants.SCOPE_INDIVIDUAL);
282                            sb.append(" and ResourcePermission.roleId = ");
283                            sb.append(powerUserRole.getRoleId());
284                            sb.append(" and (Group_.classNameId = ");
285                            sb.append(userClassNameId);
286                            sb.append(" or Group_.classNameId = ");
287                            sb.append(userGroupClassNameId);
288                            sb.append(") and Layout.type_ = '");
289                            sb.append(LayoutConstants.TYPE_PORTLET);
290                            sb.append(StringPool.APOSTROPHE);
291    
292                            runSQL(sb.toString());
293                    }
294            }
295    
296            protected void fixUserDefaultRolePermissionsOracle(
297                            long userClassNameId, long userGroupClassNameId, long[] companyIds)
298                    throws Exception {
299    
300                    try {
301                            runSQL("alter table ResourcePermission drop column plid");
302                    }
303                    catch (SQLException sqle) {
304                            if (_log.isDebugEnabled()) {
305                                    _log.debug(sqle, sqle);
306                            }
307                    }
308    
309                    runSQL("alter table ResourcePermission add plid NUMBER null");
310    
311                    runSQL("create index tmp_res_plid on ResourcePermission(plid)");
312    
313                    StringBundler sb = new StringBundler(6);
314    
315                    sb.append("update ResourcePermission r1 set plid = (select ");
316                    sb.append("SUBSTR(ResourcePermission.primKey, 0, ");
317                    sb.append("INSTR(ResourcePermission.primKey, '_LAYOUT_') -1) from ");
318                    sb.append("ResourcePermission where r1.resourcePermissionId = ");
319                    sb.append("ResourcePermission.resourcePermissionId and ");
320                    sb.append("ResourcePermission.primKey like '%_LAYOUT_%')");
321    
322                    runSQL(sb.toString());
323    
324                    for (long companyId : companyIds) {
325                            Role powerUserRole = RoleLocalServiceUtil.getRole(
326                                    companyId, RoleConstants.POWER_USER);
327                            Role userRole = RoleLocalServiceUtil.getRole(
328                                    companyId, RoleConstants.USER);
329    
330                            sb = new StringBundler(19);
331    
332                            sb.append("update ResourcePermission r1 set roleId = ");
333                            sb.append(userRole.getRoleId());
334                            sb.append(" where exists (select ");
335                            sb.append("ResourcePermission.resourcePermissionId from ");
336                            sb.append("ResourcePermission inner join Layout on ");
337                            sb.append("ResourcePermission.plid = Layout.plid inner join ");
338                            sb.append("Group_ on Layout.groupId = Group_.groupId where ");
339                            sb.append("r1.resourcePermissionId = ResourcePermission.");
340                            sb.append("resourcePermissionId and ResourcePermission.scope = ");
341                            sb.append(ResourceConstants.SCOPE_INDIVIDUAL);
342                            sb.append(" and ResourcePermission.roleId = ");
343                            sb.append(powerUserRole.getRoleId());
344                            sb.append(" and (Group_.classNameId = ");
345                            sb.append(userClassNameId);
346                            sb.append(" or Group_.classNameId = ");
347                            sb.append(userGroupClassNameId);
348                            sb.append(") and Layout.type_ = '");
349                            sb.append(LayoutConstants.TYPE_PORTLET);
350                            sb.append("')");
351    
352                            runSQL(sb.toString());
353                    }
354    
355                    runSQL("alter table ResourcePermission drop column plid");
356            }
357    
358            protected boolean isPrivateLayout(String name, String primKey)
359                    throws Exception {
360    
361                    if (!name.equals(Layout.class.getName()) &&
362                            !primKey.contains(PortletConstants.LAYOUT_SEPARATOR)) {
363    
364                            return false;
365                    }
366    
367                    if (primKey.contains(PortletConstants.LAYOUT_SEPARATOR)) {
368                            primKey = StringUtil.extractFirst(
369                                    primKey, PortletConstants.LAYOUT_SEPARATOR);
370                    }
371    
372                    long plid = GetterUtil.getLong(primKey);
373    
374                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
375    
376                    if (layout.isPublicLayout() || layout.isTypeControlPanel()) {
377                            return false;
378                    }
379    
380                    return true;
381            }
382    
383            private static final List<String> _DEPRECATED_ORGANIZATION_ACTION_IDS =
384                    new ArrayList<String>();
385    
386            private static Log _log = LogFactoryUtil.getLog(VerifyPermission.class);
387    
388            static {
389                    _DEPRECATED_ORGANIZATION_ACTION_IDS.add(
390                            ActionKeys.MANAGE_ARCHIVED_SETUPS);
391                    _DEPRECATED_ORGANIZATION_ACTION_IDS.add(ActionKeys.MANAGE_LAYOUTS);
392                    _DEPRECATED_ORGANIZATION_ACTION_IDS.add(ActionKeys.MANAGE_STAGING);
393                    _DEPRECATED_ORGANIZATION_ACTION_IDS.add(ActionKeys.MANAGE_TEAMS);
394                    _DEPRECATED_ORGANIZATION_ACTION_IDS.add(ActionKeys.PUBLISH_STAGING);
395                    _DEPRECATED_ORGANIZATION_ACTION_IDS.add("APPROVE_PROPOSAL");
396                    _DEPRECATED_ORGANIZATION_ACTION_IDS.add("ASSIGN_REVIEWER");
397            }
398    
399    }