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