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