001
014
015 package com.liferay.portal.security.permission;
016
017 import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
018 import com.liferay.portal.kernel.cache.PortalCache;
019 import com.liferay.portal.kernel.cache.index.IndexEncoder;
020 import com.liferay.portal.kernel.cache.index.PortalCacheIndexer;
021 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
022 import com.liferay.portal.kernel.util.AutoResetThreadLocal;
023 import com.liferay.portal.kernel.util.HashUtil;
024 import com.liferay.portal.kernel.util.StringBundler;
025 import com.liferay.portal.kernel.util.StringPool;
026 import com.liferay.portal.kernel.util.Validator;
027 import com.liferay.portal.model.ResourceConstants;
028 import com.liferay.portal.model.Role;
029 import com.liferay.portal.util.PropsValues;
030
031 import java.io.Serializable;
032
033 import java.util.Map;
034
035 import org.apache.commons.collections.map.LRUMap;
036
037
044 public class PermissionCacheUtil {
045
046 public static final String PERMISSION_CACHE_NAME =
047 PermissionCacheUtil.class.getName() + "_PERMISSION";
048
049 public static final String PERMISSION_CHECKER_BAG_CACHE_NAME =
050 PermissionCacheUtil.class.getName() + "_PERMISSION_CHECKER_BAG";
051
052 public static final String RESOURCE_BLOCK_IDS_BAG_CACHE_NAME =
053 PermissionCacheUtil.class.getName() + "_RESOURCE_BLOCK_IDS_BAG";
054
055 public static final String USER_PERMISSION_CHECKER_BAG_CACHE_NAME =
056 PermissionCacheUtil.class.getName() + "_USER_PERMISSION_CHECKER_BAG";
057
058 public static final String USER_ROLE_CACHE_NAME =
059 PermissionCacheUtil.class.getName() + "_USER_ROLE";
060
061 public static void clearCache() {
062 if (ExportImportThreadLocal.isImportInProcess()) {
063 return;
064 }
065
066 clearLocalCache();
067
068 _permissionCheckerBagPortalCache.removeAll();
069 _permissionPortalCache.removeAll();
070 _resourceBlockIdsBagCache.removeAll();
071 _userPermissionCheckerBagPortalCache.removeAll();
072 _userRolePortalCache.removeAll();
073 }
074
075 public static void clearLocalCache() {
076 if (_localCacheAvailable) {
077 Map<Serializable, Object> localCache = _localCache.get();
078
079 localCache.clear();
080 }
081 }
082
083 public static void clearCache(long... userIds) {
084 if (ExportImportThreadLocal.isImportInProcess()) {
085 return;
086 }
087
088 clearLocalCache();
089
090 for (long userId : userIds) {
091 _userPermissionCheckerBagPortalCache.remove(userId);
092
093 _permissionCheckerBagPortalCacheIndexer.removeKeys(userId);
094 _userRolePortalCacheIndexer.removeKeys(userId);
095 }
096
097 _permissionPortalCache.removeAll();
098 _resourceBlockIdsBagCache.removeAll();
099 }
100
101 public static void clearResourceBlockCache(
102 long companyId, long groupId, String name) {
103
104 if (ExportImportThreadLocal.isImportInProcess() ||
105 !PermissionThreadLocal.isFlushResourceBlockEnabled(
106 companyId, groupId, name)) {
107
108 return;
109 }
110
111 clearLocalCache();
112
113 _resourceBlockIdsBagCacheIndexer.removeKeys(
114 ResourceBlockIdsBagKeyIndexEncoder.encode(
115 companyId, groupId, name));
116 }
117
118 public static void clearResourceCache() {
119 if (!ExportImportThreadLocal.isImportInProcess()) {
120 clearLocalCache();
121
122 _resourceBlockIdsBagCache.removeAll();
123 _permissionPortalCache.removeAll();
124 }
125 }
126
127 public static void clearResourcePermissionCache(
128 int scope, String name, String primKey) {
129
130 if (ExportImportThreadLocal.isImportInProcess() ||
131 !PermissionThreadLocal.isFlushResourcePermissionEnabled(
132 name, primKey)) {
133
134 return;
135 }
136
137 clearLocalCache();
138
139 if (scope == ResourceConstants.SCOPE_INDIVIDUAL) {
140 _permissionPortalCacheNamePrimKeyIndexer.removeKeys(
141 PermissionKeyNamePrimKeyIndexEncoder.encode(name, primKey));
142 }
143 else if (scope == ResourceConstants.SCOPE_GROUP) {
144 _permissionPortalCacheGroupIdIndexer.removeKeys(
145 Long.valueOf(primKey));
146 }
147 else {
148 _permissionPortalCache.removeAll();
149 }
150 }
151
152 public static PermissionCheckerBag getBag(long userId, long groupId) {
153 BagKey bagKey = new BagKey(userId, groupId);
154
155 return get(bagKey, _permissionCheckerBagPortalCache);
156 }
157
158 public static Boolean getPermission(
159 long userId, boolean signedIn, long groupId, String name,
160 String primKey, String actionId) {
161
162 PermissionKey permissionKey = new PermissionKey(
163 userId, signedIn, groupId, name, primKey, actionId);
164
165 return get(permissionKey, _permissionPortalCache);
166 }
167
168 public static ResourceBlockIdsBag getResourceBlockIdsBag(
169 long companyId, long groupId, long userId, String name) {
170
171 ResourceBlockIdsBagKey resourceBlockIdsBagKey =
172 new ResourceBlockIdsBagKey(companyId, groupId, userId, name);
173
174 return get(resourceBlockIdsBagKey, _resourceBlockIdsBagCache);
175 }
176
177 public static UserPermissionCheckerBag getUserBag(long userId) {
178 return get(userId, _userPermissionCheckerBagPortalCache);
179 }
180
181 public static Boolean getUserRole(long userId, Role role) {
182 UserRoleKey userRoleKey = new UserRoleKey(userId, role.getRoleId());
183
184 Boolean userRole = _userRolePortalCache.get(userRoleKey);
185
186 if (userRole != null) {
187 return userRole;
188 }
189
190 return null;
191 }
192
193 public static void putBag(
194 long userId, long groupId, PermissionCheckerBag bag) {
195
196 if (bag == null) {
197 return;
198 }
199
200 BagKey bagKey = new BagKey(userId, groupId);
201
202 put(bagKey, bag, _permissionCheckerBagPortalCache);
203 }
204
205 public static void putPermission(
206 long userId, boolean signedIn, long groupId, String name,
207 String primKey, String actionId, Boolean value) {
208
209 PermissionKey permissionKey = new PermissionKey(
210 userId, signedIn, groupId, name, primKey, actionId);
211
212 put(permissionKey, value, _permissionPortalCache);
213 }
214
215 public static void putResourceBlockIdsBag(
216 long companyId, long groupId, long userId, String name,
217 ResourceBlockIdsBag resourceBlockIdsBag) {
218
219 if (resourceBlockIdsBag == null) {
220 return;
221 }
222
223 ResourceBlockIdsBagKey resourceBlockIdsBagKey =
224 new ResourceBlockIdsBagKey(companyId, groupId, userId, name);
225
226 put(
227 resourceBlockIdsBagKey, resourceBlockIdsBag,
228 _resourceBlockIdsBagCache);
229 }
230
231 public static void putUserBag(
232 long userId, UserPermissionCheckerBag userPermissionCheckerBag) {
233
234 put(
235 userId, userPermissionCheckerBag,
236 _userPermissionCheckerBagPortalCache);
237 }
238
239 protected static
240 <K extends Serializable, V, C extends PortalCache<K, V>> V get(
241 K key, C portalCache) {
242
243 V value = null;
244
245 if (_localCacheAvailable) {
246 Map<K, V> localCache = _localCache.get();
247
248 value = localCache.get(key);
249 }
250
251 if (value == null) {
252 value = portalCache.get(key);
253 }
254
255 return value;
256 }
257
258 protected static
259 <K extends Serializable, V, C extends PortalCache<K, V>> void put(
260 K key, V value, C portalCache) {
261
262 if (_localCacheAvailable) {
263 Map<K, V> localCache = _localCache.get();
264
265 localCache.put(key, value);
266 }
267
268 portalCache.put(key, value);
269 }
270
271 public static void putUserRole(long userId, Role role, Boolean value) {
272 if (value == null) {
273 return;
274 }
275
276 UserRoleKey userRoleKey = new UserRoleKey(userId, role.getRoleId());
277
278 _userRolePortalCache.put(userRoleKey, value);
279 }
280
281 private static ThreadLocal<LRUMap> _localCache;
282 private static boolean _localCacheAvailable;
283 private static final PortalCache<BagKey, PermissionCheckerBag>
284 _permissionCheckerBagPortalCache = MultiVMPoolUtil.getCache(
285 PERMISSION_CHECKER_BAG_CACHE_NAME,
286 PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
287 private static final PortalCacheIndexer<Long, BagKey, PermissionCheckerBag>
288 _permissionCheckerBagPortalCacheIndexer =
289 new PortalCacheIndexer<Long, BagKey, PermissionCheckerBag>(
290 new BagKeyIndexEncoder(), _permissionCheckerBagPortalCache);
291 private static final PortalCache<PermissionKey, Boolean>
292 _permissionPortalCache = MultiVMPoolUtil.getCache(
293 PERMISSION_CACHE_NAME,
294 PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
295 private static final PortalCacheIndexer<Long, PermissionKey, Boolean>
296 _permissionPortalCacheGroupIdIndexer =
297 new PortalCacheIndexer<Long, PermissionKey, Boolean>(
298 new PermissionKeyGroupIdIndexEncoder(), _permissionPortalCache);
299 private static final PortalCacheIndexer<String, PermissionKey, Boolean>
300 _permissionPortalCacheNamePrimKeyIndexer =
301 new PortalCacheIndexer<String, PermissionKey, Boolean>(
302 new PermissionKeyNamePrimKeyIndexEncoder(),
303 _permissionPortalCache);
304 private static final
305 PortalCache<ResourceBlockIdsBagKey, ResourceBlockIdsBag>
306 _resourceBlockIdsBagCache = MultiVMPoolUtil.getCache(
307 RESOURCE_BLOCK_IDS_BAG_CACHE_NAME,
308 PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
309 private static final PortalCacheIndexer
310 <String, ResourceBlockIdsBagKey, ResourceBlockIdsBag>
311 _resourceBlockIdsBagCacheIndexer = new PortalCacheIndexer
312 <String, ResourceBlockIdsBagKey, ResourceBlockIdsBag>(
313 new ResourceBlockIdsBagKeyIndexEncoder(),
314 _resourceBlockIdsBagCache);
315 private static final PortalCache<Long, UserPermissionCheckerBag>
316 _userPermissionCheckerBagPortalCache = MultiVMPoolUtil.getCache(
317 USER_PERMISSION_CHECKER_BAG_CACHE_NAME,
318 PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
319 private static final PortalCache<UserRoleKey, Boolean>
320 _userRolePortalCache = MultiVMPoolUtil.getCache(
321 USER_ROLE_CACHE_NAME,
322 PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
323 private static final PortalCacheIndexer<Long, UserRoleKey, Boolean>
324 _userRolePortalCacheIndexer =
325 new PortalCacheIndexer<Long, UserRoleKey, Boolean>(
326 new UserRoleKeyIndexEncoder(), _userRolePortalCache);
327
328 private static class BagKey implements Serializable {
329
330 @Override
331 public boolean equals(Object obj) {
332 BagKey bagKey = (BagKey)obj;
333
334 if ((bagKey._userId == _userId) && (bagKey._groupId == _groupId)) {
335 return true;
336 }
337
338 return false;
339 }
340
341 @Override
342 public int hashCode() {
343 int hashCode = HashUtil.hash(0, _userId);
344
345 return HashUtil.hash(hashCode, _groupId);
346 }
347
348 private BagKey(long userId, long groupId) {
349 _userId = userId;
350 _groupId = groupId;
351 }
352
353 private static final long serialVersionUID = 1L;
354
355 private final long _groupId;
356 private final long _userId;
357
358 }
359
360 private static class BagKeyIndexEncoder
361 implements IndexEncoder<Long, BagKey> {
362
363 @Override
364 public Long encode(BagKey bagKey) {
365 return bagKey._userId;
366 }
367
368 }
369
370 private static class PermissionKey implements Serializable {
371
372 @Override
373 public boolean equals(Object obj) {
374 PermissionKey permissionKey = (PermissionKey)obj;
375
376 if ((permissionKey._userId == _userId) &&
377 (permissionKey._signedIn == _signedIn) &&
378 (permissionKey._groupId == _groupId) &&
379 Validator.equals(permissionKey._name, _name) &&
380 Validator.equals(permissionKey._primKey, _primKey) &&
381 Validator.equals(permissionKey._actionId, _actionId)) {
382
383 return true;
384 }
385
386 return false;
387 }
388
389 @Override
390 public int hashCode() {
391 int hashCode = HashUtil.hash(0, _userId);
392
393 hashCode = HashUtil.hash(hashCode, _signedIn);
394 hashCode = HashUtil.hash(hashCode, _groupId);
395 hashCode = HashUtil.hash(hashCode, _name);
396 hashCode = HashUtil.hash(hashCode, _primKey);
397 hashCode = HashUtil.hash(hashCode, _actionId);
398
399 return hashCode;
400 }
401
402 private PermissionKey(
403 long userId, boolean signedIn, long groupId, String name,
404 String primKey, String actionId) {
405
406 _userId = userId;
407 _signedIn = signedIn;
408 _groupId = groupId;
409 _name = name;
410 _primKey = primKey;
411 _actionId = actionId;
412 }
413
414 private static final long serialVersionUID = 1L;
415
416 private final String _actionId;
417 private final long _groupId;
418 private final String _name;
419 private final String _primKey;
420 private final boolean _signedIn;
421 private final long _userId;
422
423 }
424
425 private static class PermissionKeyGroupIdIndexEncoder
426 implements IndexEncoder<Long, PermissionKey> {
427
428 @Override
429 public Long encode(PermissionKey permissionKey) {
430 return permissionKey._groupId;
431 }
432
433 }
434
435 private static class PermissionKeyNamePrimKeyIndexEncoder
436 implements IndexEncoder<String, PermissionKey> {
437
438 public static String encode(String name, String primKey) {
439 return name.concat(StringPool.UNDERLINE).concat(primKey);
440 }
441
442 @Override
443 public String encode(PermissionKey permissionKey) {
444 return encode(permissionKey._name, permissionKey._primKey);
445 }
446
447 }
448
449 private static class ResourceBlockIdsBagKey implements Serializable {
450
451 @Override
452 public boolean equals(Object obj) {
453 ResourceBlockIdsBagKey resourceBlockIdsKey =
454 (ResourceBlockIdsBagKey)obj;
455
456 if ((resourceBlockIdsKey._companyId == _companyId) &&
457 (resourceBlockIdsKey._groupId == _groupId) &&
458 (resourceBlockIdsKey._userId == _userId) &&
459 Validator.equals(resourceBlockIdsKey._name, _name)) {
460
461 return true;
462 }
463
464 return false;
465 }
466
467 @Override
468 public int hashCode() {
469 int hashCode = HashUtil.hash(0, _companyId);
470
471 hashCode = HashUtil.hash(hashCode, _groupId);
472 hashCode = HashUtil.hash(hashCode, _userId);
473 hashCode = HashUtil.hash(hashCode, _name);
474
475 return hashCode;
476 }
477
478 private ResourceBlockIdsBagKey(
479 long companyId, long groupId, long userId, String name) {
480
481 _companyId = companyId;
482 _groupId = groupId;
483 _userId = userId;
484 _name = name;
485 }
486
487 private static final long serialVersionUID = 1L;
488
489 private final long _companyId;
490 private final long _groupId;
491 private final String _name;
492 private final long _userId;
493
494 }
495
496 private static class ResourceBlockIdsBagKeyIndexEncoder
497 implements IndexEncoder<String, ResourceBlockIdsBagKey> {
498
499 public static String encode(long companyId, long groupId, String name) {
500 StringBundler sb = new StringBundler(5);
501
502 sb.append(companyId);
503 sb.append(StringPool.UNDERLINE);
504 sb.append(groupId);
505 sb.append(StringPool.UNDERLINE);
506 sb.append(name);
507
508 return sb.toString();
509 }
510
511 @Override
512 public String encode(ResourceBlockIdsBagKey resourceBlockIdsBagKey) {
513 return encode(
514 resourceBlockIdsBagKey._companyId,
515 resourceBlockIdsBagKey._groupId, resourceBlockIdsBagKey._name);
516 }
517
518 }
519
520 private static class UserRoleKey implements Serializable {
521
522 @Override
523 public boolean equals(Object obj) {
524 UserRoleKey userRoleKey = (UserRoleKey)obj;
525
526 if ((userRoleKey._userId == _userId) &&
527 (userRoleKey._roleId == _roleId)) {
528
529 return true;
530 }
531
532 return false;
533 }
534
535 @Override
536 public int hashCode() {
537 int hashCode = HashUtil.hash(0, _userId);
538
539 return HashUtil.hash(hashCode, _roleId);
540 }
541
542 private UserRoleKey(long userId, long roleId) {
543 _userId = userId;
544 _roleId = roleId;
545 }
546
547 private static final long serialVersionUID = 1L;
548
549 private final long _roleId;
550 private final long _userId;
551
552 }
553
554 private static class UserRoleKeyIndexEncoder
555 implements IndexEncoder<Long, UserRoleKey> {
556
557 @Override
558 public Long encode(UserRoleKey userRoleKey) {
559 return userRoleKey._userId;
560 }
561
562 }
563
564 static {
565 if (PropsValues.PERMISSIONS_THREAD_LOCAL_CACHE_MAX_SIZE > 0) {
566 _localCache = new AutoResetThreadLocal<LRUMap>(
567 PermissionCacheUtil.class + "._localCache",
568 new LRUMap(
569 PropsValues.PERMISSIONS_THREAD_LOCAL_CACHE_MAX_SIZE));
570 _localCacheAvailable = true;
571 }
572 }
573
574 }