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