001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.util.HashUtil;
022    import com.liferay.portal.kernel.util.StringBundler;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.model.ResourceConstants;
026    import com.liferay.portal.model.Role;
027    import com.liferay.portal.util.PropsValues;
028    import com.liferay.portlet.exportimport.lar.ExportImportThreadLocal;
029    
030    import java.io.Serializable;
031    
032    /**
033     * @author Charles May
034     * @author Michael Young
035     * @author Shuyang Zhou
036     * @author Connor McKay
037     * @author L??szl?? Csontos
038     */
039    public class PermissionCacheUtil {
040    
041            public static final String PERMISSION_CACHE_NAME =
042                    PermissionCacheUtil.class.getName() + "_PERMISSION";
043    
044            public static final String PERMISSION_CHECKER_BAG_CACHE_NAME =
045                    PermissionCacheUtil.class.getName() + "_PERMISSION_CHECKER_BAG";
046    
047            public static final String RESOURCE_BLOCK_IDS_BAG_CACHE_NAME =
048                    PermissionCacheUtil.class.getName() + "_RESOURCE_BLOCK_IDS_BAG";
049    
050            public static final String USER_BAG_CACHE_NAME =
051                    PermissionCacheUtil.class.getName() + "_USER_BAG";
052    
053            public static final String USER_PRIMARY_KEY_ROLE_CACHE_NAME =
054                    PermissionCacheUtil.class.getName() + "_USER_PRIMARY_KEY_ROLE";
055    
056            public static final String USER_ROLE_CACHE_NAME =
057                    PermissionCacheUtil.class.getName() + "_USER_ROLE";
058    
059            public static void clearCache() {
060                    if (ExportImportThreadLocal.isImportInProcess()) {
061                            return;
062                    }
063    
064                    _userRolePortalCache.removeAll();
065                    _userGroupRoleIdsPortalCache.removeAll();
066                    _permissionPortalCache.removeAll();
067                    _resourceBlockIdsBagCache.removeAll();
068                    _userBagPortalCache.removeAll();
069                    _userPrimaryKeyRolePortalCache.removeAll();
070            }
071    
072            public static void clearCache(long... userIds) {
073                    if (ExportImportThreadLocal.isImportInProcess()) {
074                            return;
075                    }
076    
077                    for (long userId : userIds) {
078                            _userBagPortalCache.remove(userId);
079    
080                            _userGroupRoleIdsPortalCacheIndexer.removeKeys(userId);
081                            _userPrimaryKeyRolePortalCacheUserIdIndexer.removeKeys(userId);
082                            _userRolePortalCacheIndexer.removeKeys(userId);
083                    }
084    
085                    _permissionPortalCache.removeAll();
086                    _resourceBlockIdsBagCache.removeAll();
087            }
088    
089            public static void clearResourceBlockCache(
090                    long companyId, long groupId, String name) {
091    
092                    if (ExportImportThreadLocal.isImportInProcess() ||
093                            !PermissionThreadLocal.isFlushResourceBlockEnabled(
094                                    companyId, groupId, name)) {
095    
096                            return;
097                    }
098    
099                    _resourceBlockIdsBagCacheIndexer.removeKeys(
100                            ResourceBlockIdsBagKeyIndexEncoder.encode(
101                                    companyId, groupId, name));
102            }
103    
104            public static void clearResourceCache() {
105                    if (!ExportImportThreadLocal.isImportInProcess()) {
106                            _resourceBlockIdsBagCache.removeAll();
107                            _permissionPortalCache.removeAll();
108                    }
109            }
110    
111            public static void clearResourcePermissionCache(
112                    int scope, String name, String primKey) {
113    
114                    if (ExportImportThreadLocal.isImportInProcess() ||
115                            !PermissionThreadLocal.isFlushResourcePermissionEnabled(
116                                    name, primKey)) {
117    
118                            return;
119                    }
120    
121                    if (scope == ResourceConstants.SCOPE_INDIVIDUAL) {
122                            _permissionPortalCacheNamePrimKeyIndexer.removeKeys(
123                                    PermissionKeyNamePrimKeyIndexEncoder.encode(name, primKey));
124                    }
125                    else if (scope == ResourceConstants.SCOPE_GROUP) {
126                            _permissionPortalCacheGroupIdIndexer.removeKeys(
127                                    Long.valueOf(primKey));
128                    }
129                    else {
130                            _permissionPortalCache.removeAll();
131                    }
132            }
133    
134            public static Boolean getPermission(
135                    long userId, boolean signedIn, long groupId, String name,
136                    String primKey, String actionId) {
137    
138                    PermissionKey permissionKey = new PermissionKey(
139                            userId, signedIn, groupId, name, primKey, actionId);
140    
141                    return _permissionPortalCache.get(permissionKey);
142            }
143    
144            public static ResourceBlockIdsBag getResourceBlockIdsBag(
145                    long companyId, long groupId, long userId, String name) {
146    
147                    ResourceBlockIdsBagKey resourceBlockIdsBagKey =
148                            new ResourceBlockIdsBagKey(companyId, groupId, userId, name);
149    
150                    return _resourceBlockIdsBagCache.get(resourceBlockIdsBagKey);
151            }
152    
153            public static UserBag getUserBag(long userId) {
154                    return _userBagPortalCache.get(userId);
155            }
156    
157            public static long[] getUserGroupRoleIds(long userId, long groupId) {
158                    UserGroupRoleIdsKey userGroupRoleIdsKey = new UserGroupRoleIdsKey(
159                            userId, groupId);
160    
161                    return _userGroupRoleIdsPortalCache.get(userGroupRoleIdsKey);
162            }
163    
164            public static Boolean getUserPrimaryKeyRole(
165                    long userId, long primaryKey, String roleName) {
166    
167                    UserPrimaryKeyRoleKey userPrimaryKeyRoleKey = new UserPrimaryKeyRoleKey(
168                            userId, primaryKey, roleName);
169    
170                    return _userPrimaryKeyRolePortalCache.get(userPrimaryKeyRoleKey);
171            }
172    
173            public static Boolean getUserRole(long userId, Role role) {
174                    UserRoleKey userRoleKey = new UserRoleKey(userId, role.getRoleId());
175    
176                    Boolean userRole = _userRolePortalCache.get(userRoleKey);
177    
178                    if (userRole != null) {
179                            return userRole;
180                    }
181    
182                    UserBag userBag = getUserBag(userId);
183    
184                    if (userBag == null) {
185                            return null;
186                    }
187    
188                    userRole = userBag.hasRole(role);
189    
190                    _userRolePortalCache.put(userRoleKey, userRole);
191    
192                    return userRole;
193            }
194    
195            public static void putPermission(
196                    long userId, boolean signedIn, long groupId, String name,
197                    String primKey, String actionId, Boolean value) {
198    
199                    PermissionKey permissionKey = new PermissionKey(
200                            userId, signedIn, groupId, name, primKey, actionId);
201    
202                    _permissionPortalCache.put(permissionKey, value);
203            }
204    
205            public static void putResourceBlockIdsBag(
206                    long companyId, long groupId, long userId, String name,
207                    ResourceBlockIdsBag resourceBlockIdsBag) {
208    
209                    if (resourceBlockIdsBag == null) {
210                            return;
211                    }
212    
213                    ResourceBlockIdsBagKey resourceBlockIdsBagKey =
214                            new ResourceBlockIdsBagKey(companyId, groupId, userId, name);
215    
216                    _resourceBlockIdsBagCache.put(
217                            resourceBlockIdsBagKey, resourceBlockIdsBag);
218            }
219    
220            public static void putUserBag(long userId, UserBag userBag) {
221                    _userBagPortalCache.put(userId, userBag);
222            }
223    
224            public static void putUserGroupRoleIds(
225                    long userId, long groupId, long[] roleIds) {
226    
227                    if (roleIds == null) {
228                            return;
229                    }
230    
231                    UserGroupRoleIdsKey userGroupRoleIdsKey = new UserGroupRoleIdsKey(
232                            userId, groupId);
233    
234                    _userGroupRoleIdsPortalCache.put(userGroupRoleIdsKey, roleIds);
235            }
236    
237            public static void putUserPrimaryKeyRole(
238                    long userId, long primaryKey, String roleName, Boolean value) {
239    
240                    if (value == null) {
241                            return;
242                    }
243    
244                    UserPrimaryKeyRoleKey userPrimaryKeyRoleKey = new UserPrimaryKeyRoleKey(
245                            userId, primaryKey, roleName);
246    
247                    _userPrimaryKeyRolePortalCache.put(userPrimaryKeyRoleKey, value);
248            }
249    
250            public static void putUserRole(long userId, Role role, Boolean value) {
251                    if (value == null) {
252                            return;
253                    }
254    
255                    UserRoleKey userRoleKey = new UserRoleKey(userId, role.getRoleId());
256    
257                    _userRolePortalCache.put(userRoleKey, value);
258            }
259    
260            public static void removePermission(
261                    long userId, boolean signedIn, long groupId, String name,
262                    String primKey, String actionId) {
263    
264                    PermissionKey permissionKey = new PermissionKey(
265                            userId, signedIn, groupId, name, primKey, actionId);
266    
267                    _permissionPortalCache.remove(permissionKey);
268            }
269    
270            public static void removeResourceBlockIdsBag(
271                    long companyId, long groupId, long userId, String name) {
272    
273                    ResourceBlockIdsBagKey resourceBlockIdsBagKey =
274                            new ResourceBlockIdsBagKey(companyId, groupId, userId, name);
275    
276                    _resourceBlockIdsBagCache.remove(resourceBlockIdsBagKey);
277            }
278    
279            public static void removeUserBag(long userId) {
280                    _userBagPortalCache.remove(userId);
281            }
282    
283            public static void removeUserGroupRoleIds(long userId, long groupId) {
284                    UserGroupRoleIdsKey userGroupRoleIdsKey = new UserGroupRoleIdsKey(
285                            userId, groupId);
286    
287                    _userGroupRoleIdsPortalCache.remove(userGroupRoleIdsKey);
288            }
289    
290            public static void removeUserPrimaryKeyRole(
291                    long userId, long primaryKey, String roleName) {
292    
293                    UserPrimaryKeyRoleKey userPrimaryKeyRoleKey = new UserPrimaryKeyRoleKey(
294                            userId, primaryKey, roleName);
295    
296                    _userPrimaryKeyRolePortalCache.remove(userPrimaryKeyRoleKey);
297            }
298    
299            private static final PortalCache<PermissionKey, Boolean>
300                    _permissionPortalCache = MultiVMPoolUtil.getPortalCache(
301                            PERMISSION_CACHE_NAME,
302                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
303            private static final PortalCacheIndexer<Long, PermissionKey, Boolean>
304                    _permissionPortalCacheGroupIdIndexer = new PortalCacheIndexer<>(
305                            new PermissionKeyGroupIdIndexEncoder(), _permissionPortalCache);
306            private static final PortalCacheIndexer<String, PermissionKey, Boolean>
307                    _permissionPortalCacheNamePrimKeyIndexer = new PortalCacheIndexer<>(
308                            new PermissionKeyNamePrimKeyIndexEncoder(), _permissionPortalCache);
309            private static final
310                    PortalCache<ResourceBlockIdsBagKey, ResourceBlockIdsBag>
311                            _resourceBlockIdsBagCache = MultiVMPoolUtil.getPortalCache(
312                                    RESOURCE_BLOCK_IDS_BAG_CACHE_NAME,
313                                    PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
314            private static final PortalCacheIndexer
315                    <String, ResourceBlockIdsBagKey, ResourceBlockIdsBag>
316                            _resourceBlockIdsBagCacheIndexer = new PortalCacheIndexer<>(
317                                    new ResourceBlockIdsBagKeyIndexEncoder(),
318                                    _resourceBlockIdsBagCache);
319            private static final PortalCache<Long, UserBag> _userBagPortalCache =
320                    MultiVMPoolUtil.getPortalCache(
321                            USER_BAG_CACHE_NAME, PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
322            private static final PortalCache<UserGroupRoleIdsKey, long[]>
323                    _userGroupRoleIdsPortalCache = MultiVMPoolUtil.getPortalCache(
324                            PERMISSION_CHECKER_BAG_CACHE_NAME,
325                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
326            private static final PortalCacheIndexer<Long, UserGroupRoleIdsKey, long[]>
327                    _userGroupRoleIdsPortalCacheIndexer = new PortalCacheIndexer<>(
328                            new UserGroupRoleIdsKeyIndexEncoder(),
329                            _userGroupRoleIdsPortalCache);
330            private static final PortalCache<UserPrimaryKeyRoleKey, Boolean>
331                    _userPrimaryKeyRolePortalCache = MultiVMPoolUtil.getPortalCache(
332                            USER_PRIMARY_KEY_ROLE_CACHE_NAME,
333                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
334            private static final PortalCacheIndexer
335                    <Long, UserPrimaryKeyRoleKey, Boolean>
336                            _userPrimaryKeyRolePortalCacheUserIdIndexer =
337                                    new PortalCacheIndexer<>(
338                                            new UserGroupRoleKeyUserIdEncoder(),
339                                            _userPrimaryKeyRolePortalCache);
340            private static final PortalCache<UserRoleKey, Boolean>
341                    _userRolePortalCache = MultiVMPoolUtil.getPortalCache(
342                            USER_ROLE_CACHE_NAME,
343                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
344            private static final PortalCacheIndexer<Long, UserRoleKey, Boolean>
345                    _userRolePortalCacheIndexer = new PortalCacheIndexer<>(
346                            new UserRoleKeyIndexEncoder(), _userRolePortalCache);
347    
348            private static class PermissionKey implements Serializable {
349    
350                    @Override
351                    public boolean equals(Object obj) {
352                            PermissionKey permissionKey = (PermissionKey)obj;
353    
354                            if ((permissionKey._userId == _userId) &&
355                                    (permissionKey._signedIn == _signedIn) &&
356                                    (permissionKey._groupId == _groupId) &&
357                                    Validator.equals(permissionKey._name, _name) &&
358                                    Validator.equals(permissionKey._primKey, _primKey) &&
359                                    Validator.equals(permissionKey._actionId, _actionId)) {
360    
361                                    return true;
362                            }
363    
364                            return false;
365                    }
366    
367                    @Override
368                    public int hashCode() {
369                            int hashCode = HashUtil.hash(0, _userId);
370    
371                            hashCode = HashUtil.hash(hashCode, _signedIn);
372                            hashCode = HashUtil.hash(hashCode, _groupId);
373                            hashCode = HashUtil.hash(hashCode, _name);
374                            hashCode = HashUtil.hash(hashCode, _primKey);
375                            hashCode = HashUtil.hash(hashCode, _actionId);
376    
377                            return hashCode;
378                    }
379    
380                    private PermissionKey(
381                            long userId, boolean signedIn, long groupId, String name,
382                            String primKey, String actionId) {
383    
384                            _userId = userId;
385                            _signedIn = signedIn;
386                            _groupId = groupId;
387                            _name = name;
388                            _primKey = primKey;
389                            _actionId = actionId;
390                    }
391    
392                    private static final long serialVersionUID = 1L;
393    
394                    private final String _actionId;
395                    private final long _groupId;
396                    private final String _name;
397                    private final String _primKey;
398                    private final boolean _signedIn;
399                    private final long _userId;
400    
401            }
402    
403            private static class PermissionKeyGroupIdIndexEncoder
404                    implements IndexEncoder<Long, PermissionKey> {
405    
406                    @Override
407                    public Long encode(PermissionKey permissionKey) {
408                            return permissionKey._groupId;
409                    }
410    
411            }
412    
413            private static class PermissionKeyNamePrimKeyIndexEncoder
414                    implements IndexEncoder<String, PermissionKey> {
415    
416                    public static String encode(String name, String primKey) {
417                            return name.concat(StringPool.UNDERLINE).concat(primKey);
418                    }
419    
420                    @Override
421                    public String encode(PermissionKey permissionKey) {
422                            return encode(permissionKey._name, permissionKey._primKey);
423                    }
424    
425            }
426    
427            private static class ResourceBlockIdsBagKey implements Serializable {
428    
429                    @Override
430                    public boolean equals(Object obj) {
431                            ResourceBlockIdsBagKey resourceBlockIdsKey =
432                                    (ResourceBlockIdsBagKey)obj;
433    
434                            if ((resourceBlockIdsKey._companyId == _companyId) &&
435                                    (resourceBlockIdsKey._groupId == _groupId) &&
436                                    (resourceBlockIdsKey._userId == _userId) &&
437                                    Validator.equals(resourceBlockIdsKey._name, _name)) {
438    
439                                    return true;
440                            }
441    
442                            return false;
443                    }
444    
445                    @Override
446                    public int hashCode() {
447                            int hashCode = HashUtil.hash(0, _companyId);
448    
449                            hashCode = HashUtil.hash(hashCode, _groupId);
450                            hashCode = HashUtil.hash(hashCode, _userId);
451                            hashCode = HashUtil.hash(hashCode, _name);
452    
453                            return hashCode;
454                    }
455    
456                    private ResourceBlockIdsBagKey(
457                            long companyId, long groupId, long userId, String name) {
458    
459                            _companyId = companyId;
460                            _groupId = groupId;
461                            _userId = userId;
462                            _name = name;
463                    }
464    
465                    private static final long serialVersionUID = 1L;
466    
467                    private final long _companyId;
468                    private final long _groupId;
469                    private final String _name;
470                    private final long _userId;
471    
472            }
473    
474            private static class ResourceBlockIdsBagKeyIndexEncoder
475                    implements IndexEncoder<String, ResourceBlockIdsBagKey> {
476    
477                    public static String encode(long companyId, long groupId, String name) {
478                            StringBundler sb = new StringBundler(5);
479    
480                            sb.append(companyId);
481                            sb.append(StringPool.UNDERLINE);
482                            sb.append(groupId);
483                            sb.append(StringPool.UNDERLINE);
484                            sb.append(name);
485    
486                            return sb.toString();
487                    }
488    
489                    @Override
490                    public String encode(ResourceBlockIdsBagKey resourceBlockIdsBagKey) {
491                            return encode(
492                                    resourceBlockIdsBagKey._companyId,
493                                    resourceBlockIdsBagKey._groupId, resourceBlockIdsBagKey._name);
494                    }
495    
496            }
497    
498            private static class UserGroupRoleIdsKey implements Serializable {
499    
500                    @Override
501                    public boolean equals(Object obj) {
502                            UserGroupRoleIdsKey userGroupRoleIdsKey = (UserGroupRoleIdsKey)obj;
503    
504                            if ((userGroupRoleIdsKey._userId == _userId) &&
505                                    (userGroupRoleIdsKey._groupId == _groupId)) {
506    
507                                    return true;
508                            }
509    
510                            return false;
511                    }
512    
513                    @Override
514                    public int hashCode() {
515                            int hashCode = HashUtil.hash(0, _userId);
516    
517                            return HashUtil.hash(hashCode, _groupId);
518                    }
519    
520                    private UserGroupRoleIdsKey(long userId, long groupId) {
521                            _userId = userId;
522                            _groupId = groupId;
523                    }
524    
525                    private static final long serialVersionUID = 1L;
526    
527                    private final long _groupId;
528                    private final long _userId;
529    
530            }
531    
532            private static class UserGroupRoleIdsKeyIndexEncoder
533                    implements IndexEncoder<Long, UserGroupRoleIdsKey> {
534    
535                    @Override
536                    public Long encode(UserGroupRoleIdsKey userGroupRoleIdsKey) {
537                            return userGroupRoleIdsKey._userId;
538                    }
539    
540            }
541    
542            private static class UserGroupRoleKeyUserIdEncoder
543                    implements IndexEncoder<Long, UserPrimaryKeyRoleKey> {
544    
545                    @Override
546                    public Long encode(UserPrimaryKeyRoleKey key) {
547                            return key._userId;
548                    }
549    
550            }
551    
552            private static class UserPrimaryKeyRoleKey implements Serializable {
553    
554                    @Override
555                    public boolean equals(Object obj) {
556                            UserPrimaryKeyRoleKey UserPrimaryKeyRoleKey =
557                                    (UserPrimaryKeyRoleKey)obj;
558    
559                            if ((UserPrimaryKeyRoleKey._userId == _userId) &&
560                                    (UserPrimaryKeyRoleKey._primaryKey == _primaryKey) &&
561                                    Validator.equals(UserPrimaryKeyRoleKey._name, _name)) {
562    
563                                    return true;
564                            }
565    
566                            return false;
567                    }
568    
569                    @Override
570                    public int hashCode() {
571                            int hashCode = HashUtil.hash(0, _userId);
572    
573                            hashCode = HashUtil.hash(hashCode, _primaryKey);
574                            hashCode = HashUtil.hash(hashCode, _name);
575    
576                            return hashCode;
577                    }
578    
579                    private UserPrimaryKeyRoleKey(
580                            long userId, long primaryKey, String name) {
581    
582                            _userId = userId;
583                            _primaryKey = primaryKey;
584                            _name = name;
585                    }
586    
587                    private static final long serialVersionUID = 1L;
588    
589                    private final String _name;
590                    private final long _primaryKey;
591                    private final long _userId;
592    
593            }
594    
595            private static class UserRoleKey implements Serializable {
596    
597                    @Override
598                    public boolean equals(Object obj) {
599                            UserRoleKey userRoleKey = (UserRoleKey)obj;
600    
601                            if ((userRoleKey._userId == _userId) &&
602                                    (userRoleKey._roleId == _roleId)) {
603    
604                                    return true;
605                            }
606    
607                            return false;
608                    }
609    
610                    @Override
611                    public int hashCode() {
612                            int hashCode = HashUtil.hash(0, _userId);
613    
614                            return HashUtil.hash(hashCode, _roleId);
615                    }
616    
617                    private UserRoleKey(long userId, long roleId) {
618                            _userId = userId;
619                            _roleId = roleId;
620                    }
621    
622                    private static final long serialVersionUID = 1L;
623    
624                    private final long _roleId;
625                    private final long _userId;
626    
627            }
628    
629            private static class UserRoleKeyIndexEncoder
630                    implements IndexEncoder<Long, UserRoleKey> {
631    
632                    @Override
633                    public Long encode(UserRoleKey userRoleKey) {
634                            return userRoleKey._userId;
635                    }
636    
637            }
638    
639    }