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