001
014
015 package com.liferay.portal.security.permission;
016
017 import com.liferay.portal.kernel.util.ArrayUtil;
018 import com.liferay.portal.kernel.util.StringBundler;
019 import com.liferay.portal.kernel.util.StringPool;
020 import com.liferay.portal.kernel.util.StringUtil;
021 import com.liferay.portal.kernel.util.Validator;
022 import com.liferay.portal.model.ResourceConstants;
023 import com.liferay.portal.service.ResourceBlockLocalServiceUtil;
024 import com.liferay.portal.service.ResourceTypePermissionLocalServiceUtil;
025 import com.liferay.portal.util.PropsValues;
026 import com.liferay.util.dao.orm.CustomSQLUtil;
027
028 import java.util.HashSet;
029 import java.util.Set;
030
031
035 public class InlineSQLHelperImpl implements InlineSQLHelper {
036
037 public static final String FILTER_BY_RESOURCE_BLOCK_ID =
038 InlineSQLHelper.class.getName() + ".filterByResourceBlockId";
039
040 public static final String FILTER_BY_RESOURCE_BLOCK_ID_OWNER =
041 InlineSQLHelper.class.getName() + ".filterByResourceBlockIdOwner";
042
043 public static final String JOIN_RESOURCE_PERMISSION =
044 InlineSQLHelper.class.getName() + ".joinResourcePermission";
045
046 public boolean isEnabled() {
047 return isEnabled(0);
048 }
049
050 public boolean isEnabled(long groupId) {
051 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM != 6) {
052 return false;
053 }
054
055 if (!PropsValues.PERMISSIONS_INLINE_SQL_CHECK_ENABLED) {
056 return false;
057 }
058
059 PermissionChecker permissionChecker =
060 PermissionThreadLocal.getPermissionChecker();
061
062 if (permissionChecker == null) {
063 return false;
064 }
065
066 if (groupId > 0) {
067 if (permissionChecker.isGroupAdmin(groupId) ||
068 permissionChecker.isGroupOwner(groupId)) {
069
070 return false;
071 }
072 }
073 else {
074 if (permissionChecker.isCompanyAdmin()) {
075 return false;
076 }
077 }
078
079 return true;
080 }
081
082 public boolean isEnabled(long[] groupIds) {
083 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM != 6) {
084 return false;
085 }
086
087 if (!PropsValues.PERMISSIONS_INLINE_SQL_CHECK_ENABLED) {
088 return false;
089 }
090
091 for (long groupId : groupIds) {
092 if (isEnabled(groupId)) {
093 return true;
094 }
095 }
096
097 return false;
098 }
099
100 public String replacePermissionCheck(
101 String sql, String className, String classPKField) {
102
103 return replacePermissionCheck(
104 sql, className, classPKField, null, new long[] {0}, null);
105 }
106
107 public String replacePermissionCheck(
108 String sql, String className, String classPKField, long groupId) {
109
110 return replacePermissionCheck(
111 sql, className, classPKField, null, new long[] {groupId}, null);
112 }
113
114 public String replacePermissionCheck(
115 String sql, String className, String classPKField, long groupId,
116 String bridgeJoin) {
117
118 return replacePermissionCheck(
119 sql, className, classPKField, null, new long[] {groupId},
120 bridgeJoin);
121 }
122
123 public String replacePermissionCheck(
124 String sql, String className, String classPKField, long[] groupIds) {
125
126 return replacePermissionCheck(
127 sql, className, classPKField, null, groupIds, null);
128 }
129
130 public String replacePermissionCheck(
131 String sql, String className, String classPKField, long[] groupIds,
132 String bridgeJoin) {
133
134 return replacePermissionCheck(
135 sql, className, classPKField, null, groupIds, bridgeJoin);
136 }
137
138 public String replacePermissionCheck(
139 String sql, String className, String classPKField, String userIdField) {
140
141 return replacePermissionCheck(
142 sql, className, classPKField, userIdField, new long[] {0}, null);
143 }
144
145 public String replacePermissionCheck(
146 String sql, String className, String classPKField, String userIdField,
147 long groupId) {
148
149 return replacePermissionCheck(
150 sql, className, classPKField, userIdField, new long[] {groupId},
151 null);
152 }
153
154 public String replacePermissionCheck(
155 String sql, String className, String classPKField, String userIdField,
156 long groupId, String bridgeJoin) {
157
158 return replacePermissionCheck(
159 sql, className, classPKField, userIdField, new long[] {groupId},
160 bridgeJoin);
161 }
162
163 public String replacePermissionCheck(
164 String sql, String className, String classPKField, String userIdField,
165 long[] groupIds) {
166
167 return replacePermissionCheck(
168 sql, className, classPKField, userIdField, groupIds, null);
169 }
170
171 public String replacePermissionCheck(
172 String sql, String className, String classPKField, String userIdField,
173 long[] groupIds, String bridgeJoin) {
174
175 if (!isEnabled(groupIds)) {
176 return sql;
177 }
178
179 if (Validator.isNull(className)) {
180 throw new IllegalArgumentException("className is null");
181 }
182
183 if (Validator.isNull(sql)) {
184 return sql;
185 }
186
187 if (ResourceBlockLocalServiceUtil.isSupported(className)) {
188 return replacePermissionCheckBlocks(
189 sql, className, classPKField, userIdField, groupIds,
190 bridgeJoin);
191 }
192 else {
193 return replacePermissionCheckJoin(
194 sql, className, classPKField, userIdField, groupIds,
195 bridgeJoin);
196 }
197 }
198
199 public String replacePermissionCheck(
200 String sql, String className, String classPKField, String userIdField,
201 String bridgeJoin) {
202
203 return replacePermissionCheck(
204 sql, className, classPKField, userIdField, 0, bridgeJoin);
205 }
206
207 protected Set<Long> getOwnerResourceBlockIds(
208 long companyId, long[] groupIds, String className) {
209
210 Set<Long> resourceBlockIds = new HashSet<Long>();
211
212 PermissionChecker permissionChecker =
213 PermissionThreadLocal.getPermissionChecker();
214
215 for (long groupId : groupIds) {
216 resourceBlockIds.addAll(
217 permissionChecker.getOwnerResourceBlockIds(
218 companyId, groupId, className, ActionKeys.VIEW));
219 }
220
221 return resourceBlockIds;
222 }
223
224 protected Set<Long> getResourceBlockIds(
225 long companyId, long[] groupIds, String className) {
226
227 Set<Long> resourceBlockIds = new HashSet<Long>();
228
229 PermissionChecker permissionChecker =
230 PermissionThreadLocal.getPermissionChecker();
231
232 for (long groupId : groupIds) {
233 resourceBlockIds.addAll(
234 permissionChecker.getResourceBlockIds(
235 companyId, groupId, permissionChecker.getUserId(), className,
236 ActionKeys.VIEW));
237 }
238
239 return resourceBlockIds;
240 }
241
242 protected long[] getRoleIds(long groupId) {
243 long[] roleIds = PermissionChecker.DEFAULT_ROLE_IDS;
244
245 PermissionChecker permissionChecker =
246 PermissionThreadLocal.getPermissionChecker();
247
248 if (permissionChecker != null) {
249 roleIds = permissionChecker.getRoleIds(
250 permissionChecker.getUserId(), groupId);
251 }
252
253 return roleIds;
254 }
255
256 protected long[] getRoleIds(long[] groupIds) {
257 long[] roleIds = PermissionChecker.DEFAULT_ROLE_IDS;
258
259 for (long groupId : groupIds) {
260 for (long roleId : getRoleIds(groupId)) {
261 if (!ArrayUtil.contains(roleIds, roleId)) {
262 roleIds = ArrayUtil.append(roleIds, roleId);
263 }
264 }
265 }
266
267 return roleIds;
268 }
269
270 protected long getUserId() {
271 long userId = 0;
272
273 PermissionChecker permissionChecker =
274 PermissionThreadLocal.getPermissionChecker();
275
276 if (permissionChecker != null) {
277 userId = permissionChecker.getUserId();
278 }
279
280 return userId;
281 }
282
283 protected String replacePermissionCheckBlocks(
284 String sql, String className, String classPKField, String userIdField,
285 long[] groupIds, String bridgeJoin) {
286
287 PermissionChecker permissionChecker =
288 PermissionThreadLocal.getPermissionChecker();
289
290 long checkGroupId = 0;
291
292 if (groupIds.length == 1) {
293 checkGroupId = groupIds[0];
294 }
295
296 long companyId = permissionChecker.getCompanyId();
297
298 long[] roleIds = permissionChecker.getRoleIds(
299 getUserId(), checkGroupId);
300
301 try {
302 for (long roleId : roleIds) {
303 if (ResourceTypePermissionLocalServiceUtil.
304 hasCompanyScopePermission(
305 companyId, className, roleId, ActionKeys.VIEW)) {
306
307 return sql;
308 }
309 }
310 }
311 catch (Exception e) {
312 }
313
314 Set<Long> userResourceBlockIds = getResourceBlockIds(
315 companyId, groupIds, className);
316
317 String permissionWhere = StringPool.BLANK;
318
319 if (Validator.isNotNull(bridgeJoin)) {
320 permissionWhere = bridgeJoin;
321 }
322
323 Set<Long> ownerResourceBlockIds = getOwnerResourceBlockIds(
324 companyId, groupIds, className);
325
326
327
328
329 ownerResourceBlockIds.removeAll(userResourceBlockIds);
330
331
332
333
334 if (userResourceBlockIds.size() == 0) {
335 userResourceBlockIds.add(_NO_RESOURCE_BLOCKS_ID);
336 }
337
338 if (Validator.isNotNull(userIdField) &&
339 ownerResourceBlockIds.size() > 0) {
340
341 permissionWhere = permissionWhere.concat(
342 CustomSQLUtil.get(FILTER_BY_RESOURCE_BLOCK_ID_OWNER));
343
344 permissionWhere = StringUtil.replace(
345 permissionWhere,
346 new String[] {
347 "[$OWNER_RESOURCE_BLOCK_IDS$]",
348 "[$USER_ID$]",
349 "[$USER_ID_FIELD$]",
350 "[$USER_RESOURCE_BLOCK_IDS$]"
351 },
352 new String[] {
353 StringUtil.merge(ownerResourceBlockIds),
354 String.valueOf(permissionChecker.getUserId()),
355 userIdField,
356 StringUtil.merge(userResourceBlockIds)
357 });
358 }
359 else {
360 permissionWhere = permissionWhere.concat(
361 CustomSQLUtil.get(FILTER_BY_RESOURCE_BLOCK_ID));
362
363 permissionWhere = StringUtil.replace(
364 permissionWhere, "[$USER_RESOURCE_BLOCK_IDS$]",
365 StringUtil.merge(userResourceBlockIds));
366 }
367
368 int pos = sql.indexOf(_WHERE_CLAUSE);
369
370 if (pos != -1) {
371 StringBundler sb = new StringBundler(4);
372
373 sb.append(sql.substring(0, pos));
374 sb.append(permissionWhere);
375 sb.append(" AND ");
376 sb.append(sql.substring(pos + 7));
377
378 return sb.toString();
379 }
380
381 pos = sql.indexOf(_GROUP_BY_CLAUSE);
382
383 if (pos != -1) {
384 return sql.substring(0, pos + 1).concat(permissionWhere).concat(
385 sql.substring(pos + 1));
386 }
387
388 pos = sql.indexOf(_ORDER_BY_CLAUSE);
389
390 if (pos != -1) {
391 return sql.substring(0, pos + 1).concat(permissionWhere).concat(
392 sql.substring(pos + 1));
393 }
394
395 return sql.concat(StringPool.SPACE).concat(permissionWhere);
396 }
397
398 protected String replacePermissionCheckJoin(
399 String sql, String className, String classPKField, String userIdField,
400 long[] groupIds, String bridgeJoin) {
401
402 if (Validator.isNull(classPKField)) {
403 throw new IllegalArgumentException("classPKField is null");
404 }
405
406 PermissionChecker permissionChecker =
407 PermissionThreadLocal.getPermissionChecker();
408
409 long checkGroupId = 0;
410
411 if (groupIds.length == 1) {
412 checkGroupId = groupIds[0];
413 }
414
415 if (permissionChecker.hasPermission(
416 checkGroupId, className, 0, ActionKeys.VIEW)) {
417
418 return sql;
419 }
420
421 String permissionJoin = StringPool.BLANK;
422
423 if (Validator.isNotNull(bridgeJoin)) {
424 permissionJoin = bridgeJoin;
425 }
426
427 permissionJoin += CustomSQLUtil.get(JOIN_RESOURCE_PERMISSION);
428
429 StringBundler sb = new StringBundler();
430
431 sb.append("(InlineSQLResourcePermission.scope = ");
432 sb.append(ResourceConstants.SCOPE_INDIVIDUAL);
433 sb.append(" AND ");
434 sb.append("InlineSQLResourcePermission.primKey = CAST_TEXT(");
435 sb.append(classPKField);
436 sb.append(") AND (");
437
438 long userId = getUserId();
439
440 for (int j = 0; j < groupIds.length; j++) {
441 long groupId = groupIds[j];
442
443 if (!permissionChecker.hasPermission(
444 groupId, className, 0, ActionKeys.VIEW)) {
445
446 if (j > 0) {
447 sb.append(" OR ");
448 }
449
450 sb.append("(");
451
452 long[] roleIds = getRoleIds(groupId);
453
454 if (roleIds.length == 0) {
455 roleIds = _NO_ROLE_IDS;
456 }
457
458 for (int i = 0; i < roleIds.length; i++) {
459 if (i > 0) {
460 sb.append(" OR ");
461 }
462
463 sb.append("InlineSQLResourcePermission.roleId = ");
464 sb.append(roleIds[i]);
465 }
466
467 if (permissionChecker.isSignedIn()) {
468 sb.append(" OR ");
469
470 if (Validator.isNotNull(userIdField)) {
471 sb.append("(");
472 sb.append(userIdField);
473 sb.append(" = ");
474 sb.append(userId);
475 sb.append(")");
476 }
477 else {
478 sb.append("(InlineSQLResourcePermission.ownerId = ");
479 sb.append(userId);
480 sb.append(")");
481 }
482 }
483
484 sb.append(") AND ");
485 }
486
487 sb.append("(");
488 sb.append(classPKField.substring(0, classPKField.lastIndexOf('.')));
489 sb.append(".groupId = ");
490 sb.append(groupId);
491 sb.append(")");
492 }
493
494 sb.append("))");
495
496 permissionJoin = StringUtil.replace(
497 permissionJoin,
498 new String[] {
499 "[$CLASS_NAME$]",
500 "[$COMPANY_ID$]",
501 "[$PRIM_KEYS$]"
502 },
503 new String[] {
504 className,
505 String.valueOf(permissionChecker.getCompanyId()),
506 sb.toString()
507 });
508
509 int pos = sql.indexOf(_WHERE_CLAUSE);
510
511 if (pos != -1) {
512 return sql.substring(0, pos + 1).concat(permissionJoin).concat(
513 sql.substring(pos + 1));
514 }
515
516 pos = sql.indexOf(_GROUP_BY_CLAUSE);
517
518 if (pos != -1) {
519 return sql.substring(0, pos + 1).concat(permissionJoin).concat(
520 sql.substring(pos + 1));
521 }
522
523 pos = sql.indexOf(_ORDER_BY_CLAUSE);
524
525 if (pos != -1) {
526 return sql.substring(0, pos + 1).concat(permissionJoin).concat(
527 sql.substring(pos + 1));
528 }
529
530 return sql.concat(StringPool.SPACE).concat(permissionJoin);
531 }
532
533 private static final String _GROUP_BY_CLAUSE = " GROUP BY ";
534
535 private static final long _NO_RESOURCE_BLOCKS_ID = -1;
536
537 private static final long[] _NO_ROLE_IDS = {0};
538
539 private static final String _ORDER_BY_CLAUSE = " ORDER BY ";
540
541 private static final String _WHERE_CLAUSE = " WHERE ";
542
543 }