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.IndexedCacheKey;
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.Role;
026    import com.liferay.portal.util.PropsValues;
027    import com.liferay.portlet.exportimport.lar.ExportImportThreadLocal;
028    
029    /**
030     * @author Charles May
031     * @author Michael Young
032     * @author Shuyang Zhou
033     * @author Connor McKay
034     * @author L??szl?? Csontos
035     */
036    public class PermissionCacheUtil {
037    
038            public static final String PERMISSION_CACHE_NAME =
039                    PermissionCacheUtil.class.getName() + "_PERMISSION";
040    
041            public static final String PERMISSION_CHECKER_BAG_CACHE_NAME =
042                    PermissionCacheUtil.class.getName() + "_PERMISSION_CHECKER_BAG";
043    
044            public static final String RESOURCE_BLOCK_IDS_BAG_CACHE_NAME =
045                    PermissionCacheUtil.class.getName() + "_RESOURCE_BLOCK_IDS_BAG";
046    
047            public static final String USER_PERMISSION_CHECKER_BAG_CACHE_NAME =
048                    PermissionCacheUtil.class.getName() + "_USER_PERMISSION_CHECKER_BAG";
049    
050            public static final String USER_ROLE_CACHE_NAME =
051                    PermissionCacheUtil.class.getName() + "_USER_ROLE";
052    
053            public static void clearCache() {
054                    if (ExportImportThreadLocal.isImportInProcess()) {
055                            return;
056                    }
057    
058                    _userRolePortalCache.removeAll();
059                    _permissionCheckerBagPortalCache.removeAll();
060                    _permissionPortalCache.removeAll();
061                    _resourceBlockIdsBagCache.removeAll();
062                    _userPermissionCheckerBagPortalCache.removeAll();
063            }
064    
065            public static void clearCache(long... userIds) {
066                    if (ExportImportThreadLocal.isImportInProcess()) {
067                            return;
068                    }
069    
070                    for (long userId : userIds) {
071                            _userPermissionCheckerBagPortalCache.remove(userId);
072    
073                            _userRolePortalCacheIndexer.removeIndexedCacheKeys(userId);
074                            _permissionCheckerBagPortalCacheIndexer.removeIndexedCacheKeys(
075                                    userId);
076                    }
077    
078                    _permissionPortalCache.removeAll();
079                    _resourceBlockIdsBagCache.removeAll();
080            }
081    
082            public static void clearResourceBlockCache(
083                    long companyId, long groupId, String name) {
084    
085                    if (ExportImportThreadLocal.isImportInProcess() ||
086                            !PermissionThreadLocal.isFlushResourceBlockEnabled(
087                                    companyId, groupId, name)) {
088    
089                            return;
090                    }
091    
092                    _resourceBlockIdsBagCacheIndexer.removeIndexedCacheKeys(
093                            ResourceBlockIdsBagKey.getIndex(companyId, groupId, name));
094            }
095    
096            public static void clearResourceCache() {
097                    if (!ExportImportThreadLocal.isImportInProcess()) {
098                            _resourceBlockIdsBagCache.removeAll();
099                            _permissionPortalCache.removeAll();
100                    }
101            }
102    
103            public static void clearResourcePermissionCache(
104                    String name, String primKey) {
105    
106                    if (ExportImportThreadLocal.isImportInProcess() ||
107                            !PermissionThreadLocal.isFlushResourcePermissionEnabled(
108                                    name, primKey)) {
109    
110                            return;
111                    }
112    
113                    _permissionPortalCacheIndexer.removeIndexedCacheKeys(
114                            PermissionKey.getIndex(name, primKey));
115            }
116    
117            public static PermissionCheckerBag getBag(long userId, long groupId) {
118                    BagKey bagKey = new BagKey(userId, groupId);
119    
120                    return _permissionCheckerBagPortalCache.get(bagKey);
121            }
122    
123            public static Boolean getPermission(
124                    long userId, boolean signedIn, long groupId, String name,
125                    String primKey, String actionId) {
126    
127                    PermissionKey permissionKey = new PermissionKey(
128                            userId, signedIn, groupId, name, primKey, actionId);
129    
130                    return _permissionPortalCache.get(permissionKey);
131            }
132    
133            public static ResourceBlockIdsBag getResourceBlockIdsBag(
134                    long companyId, long groupId, long userId, String name) {
135    
136                    ResourceBlockIdsBagKey resourceBlockIdsBagKey =
137                            new ResourceBlockIdsBagKey(companyId, groupId, userId, name);
138    
139                    return _resourceBlockIdsBagCache.get(resourceBlockIdsBagKey);
140            }
141    
142            public static UserPermissionCheckerBag getUserBag(long userId) {
143                    return _userPermissionCheckerBagPortalCache.get(userId);
144            }
145    
146            public static Boolean getUserRole(long userId, Role role) {
147                    UserRoleKey userRoleKey = new UserRoleKey(userId, role.getRoleId());
148    
149                    Boolean userRole = _userRolePortalCache.get(userRoleKey);
150    
151                    if (userRole != null) {
152                            return userRole;
153                    }
154    
155                    UserPermissionCheckerBag userPermissionCheckerBag = getUserBag(userId);
156    
157                    if (userPermissionCheckerBag == null) {
158                            return null;
159                    }
160    
161                    userRole = userPermissionCheckerBag.hasRole(role);
162    
163                    _userRolePortalCache.put(userRoleKey, userRole);
164    
165                    return userRole;
166            }
167    
168            public static void putBag(
169                    long userId, long groupId, PermissionCheckerBag bag) {
170    
171                    if (bag == null) {
172                            return;
173                    }
174    
175                    BagKey bagKey = new BagKey(userId, groupId);
176    
177                    _permissionCheckerBagPortalCache.put(bagKey, bag);
178            }
179    
180            public static void putPermission(
181                    long userId, boolean signedIn, long groupId, String name,
182                    String primKey, String actionId, Boolean value) {
183    
184                    PermissionKey permissionKey = new PermissionKey(
185                            userId, signedIn, groupId, name, primKey, actionId);
186    
187                    _permissionPortalCache.put(permissionKey, value);
188            }
189    
190            public static void putResourceBlockIdsBag(
191                    long companyId, long groupId, long userId, String name,
192                    ResourceBlockIdsBag resourceBlockIdsBag) {
193    
194                    if (resourceBlockIdsBag == null) {
195                            return;
196                    }
197    
198                    ResourceBlockIdsBagKey resourceBlockIdsBagKey =
199                            new ResourceBlockIdsBagKey(companyId, groupId, userId, name);
200    
201                    _resourceBlockIdsBagCache.put(
202                            resourceBlockIdsBagKey, resourceBlockIdsBag);
203            }
204    
205            public static void putUserBag(
206                    long userId, UserPermissionCheckerBag userPermissionCheckerBag) {
207    
208                    _userPermissionCheckerBagPortalCache.put(
209                            userId, userPermissionCheckerBag);
210            }
211    
212            public static void putUserRole(long userId, Role role, Boolean value) {
213                    if (value == null) {
214                            return;
215                    }
216    
217                    UserRoleKey userRoleKey = new UserRoleKey(userId, role.getRoleId());
218    
219                    _userRolePortalCache.put(userRoleKey, value);
220            }
221    
222            private static final PortalCache<BagKey, PermissionCheckerBag>
223                    _permissionCheckerBagPortalCache = MultiVMPoolUtil.getCache(
224                            PERMISSION_CHECKER_BAG_CACHE_NAME,
225                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
226            private static final PortalCacheIndexer<Long, BagKey, PermissionCheckerBag>
227                    _permissionCheckerBagPortalCacheIndexer = new PortalCacheIndexer<>(
228                            _permissionCheckerBagPortalCache);
229            private static final PortalCache<PermissionKey, Boolean>
230                    _permissionPortalCache = MultiVMPoolUtil.getCache(
231                            PERMISSION_CACHE_NAME,
232                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
233            private static final PortalCacheIndexer<String, PermissionKey, Boolean>
234                    _permissionPortalCacheIndexer = new PortalCacheIndexer<>(
235                            _permissionPortalCache);
236            private static final
237                    PortalCache<ResourceBlockIdsBagKey, ResourceBlockIdsBag>
238                            _resourceBlockIdsBagCache = MultiVMPoolUtil.getCache(
239                                    RESOURCE_BLOCK_IDS_BAG_CACHE_NAME,
240                                    PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
241            private static final PortalCacheIndexer
242                    <String, ResourceBlockIdsBagKey, ResourceBlockIdsBag>
243                            _resourceBlockIdsBagCacheIndexer = new PortalCacheIndexer<>(
244                                    _resourceBlockIdsBagCache);
245            private static final PortalCache<Long, UserPermissionCheckerBag>
246                    _userPermissionCheckerBagPortalCache = MultiVMPoolUtil.getCache(
247                            USER_PERMISSION_CHECKER_BAG_CACHE_NAME,
248                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
249            private static final PortalCache<UserRoleKey, Boolean>
250                    _userRolePortalCache = MultiVMPoolUtil.getCache(
251                            USER_ROLE_CACHE_NAME,
252                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
253            private static final PortalCacheIndexer<Long, UserRoleKey, Boolean>
254                    _userRolePortalCacheIndexer = new PortalCacheIndexer<>(
255                            _userRolePortalCache);
256    
257            private static class BagKey implements IndexedCacheKey<Long> {
258    
259                    @Override
260                    public boolean equals(Object obj) {
261                            BagKey bagKey = (BagKey)obj;
262    
263                            if ((bagKey._userId == _userId) && (bagKey._groupId == _groupId)) {
264                                    return true;
265                            }
266    
267                            return false;
268                    }
269    
270                    @Override
271                    public Long getIndex() {
272                            return _userId;
273                    }
274    
275                    @Override
276                    public int hashCode() {
277                            int hashCode = HashUtil.hash(0, _userId);
278    
279                            return HashUtil.hash(hashCode, _groupId);
280                    }
281    
282                    private BagKey(long userId, long groupId) {
283                            _userId = userId;
284                            _groupId = groupId;
285                    }
286    
287                    private static final long serialVersionUID = 1L;
288    
289                    private final long _groupId;
290                    private final long _userId;
291    
292            }
293    
294            private static class PermissionKey implements IndexedCacheKey<String> {
295    
296                    public static String getIndex(String name, String primKey) {
297                            return name.concat(StringPool.UNDERLINE).concat(primKey);
298                    }
299    
300                    @Override
301                    public boolean equals(Object obj) {
302                            PermissionKey permissionKey = (PermissionKey)obj;
303    
304                            if ((permissionKey._userId == _userId) &&
305                                    (permissionKey._signedIn == _signedIn) &&
306                                    (permissionKey._groupId == _groupId) &&
307                                    Validator.equals(permissionKey._name, _name) &&
308                                    Validator.equals(permissionKey._primKey, _primKey) &&
309                                    Validator.equals(permissionKey._actionId, _actionId)) {
310    
311                                    return true;
312                            }
313    
314                            return false;
315                    }
316    
317                    @Override
318                    public String getIndex() {
319                            return getIndex(_name, _primKey);
320                    }
321    
322                    @Override
323                    public int hashCode() {
324                            int hashCode = HashUtil.hash(0, _userId);
325    
326                            hashCode = HashUtil.hash(hashCode, _signedIn);
327                            hashCode = HashUtil.hash(hashCode, _groupId);
328                            hashCode = HashUtil.hash(hashCode, _name);
329                            hashCode = HashUtil.hash(hashCode, _primKey);
330                            hashCode = HashUtil.hash(hashCode, _actionId);
331    
332                            return hashCode;
333                    }
334    
335                    private PermissionKey(
336                            long userId, boolean signedIn, long groupId, String name,
337                            String primKey, String actionId) {
338    
339                            _userId = userId;
340                            _signedIn = signedIn;
341                            _groupId = groupId;
342                            _name = name;
343                            _primKey = primKey;
344                            _actionId = actionId;
345                    }
346    
347                    private static final long serialVersionUID = 1L;
348    
349                    private final String _actionId;
350                    private final long _groupId;
351                    private final String _name;
352                    private final String _primKey;
353                    private final boolean _signedIn;
354                    private final long _userId;
355    
356            }
357    
358            private static class ResourceBlockIdsBagKey
359                    implements IndexedCacheKey<String> {
360    
361                    public static String getIndex(
362                            long companyId, long groupId, String name) {
363    
364                            StringBundler sb = new StringBundler(5);
365    
366                            sb.append(companyId);
367                            sb.append(StringPool.UNDERLINE);
368                            sb.append(groupId);
369                            sb.append(StringPool.UNDERLINE);
370                            sb.append(name);
371    
372                            return sb.toString();
373                    }
374    
375                    @Override
376                    public boolean equals(Object obj) {
377                            ResourceBlockIdsBagKey resourceBlockIdsKey =
378                                    (ResourceBlockIdsBagKey)obj;
379    
380                            if ((resourceBlockIdsKey._companyId == _companyId) &&
381                                    (resourceBlockIdsKey._groupId == _groupId) &&
382                                    (resourceBlockIdsKey._userId == _userId) &&
383                                    Validator.equals(resourceBlockIdsKey._name, _name)) {
384    
385                                    return true;
386                            }
387    
388                            return false;
389                    }
390    
391                    @Override
392                    public String getIndex() {
393                            return getIndex(_companyId, _groupId, _name);
394                    }
395    
396                    @Override
397                    public int hashCode() {
398                            int hashCode = HashUtil.hash(0, _companyId);
399    
400                            hashCode = HashUtil.hash(hashCode, _groupId);
401                            hashCode = HashUtil.hash(hashCode, _userId);
402                            hashCode = HashUtil.hash(hashCode, _name);
403    
404                            return hashCode;
405                    }
406    
407                    private ResourceBlockIdsBagKey(
408                            long companyId, long groupId, long userId, String name) {
409    
410                            _companyId = companyId;
411                            _groupId = groupId;
412                            _userId = userId;
413                            _name = name;
414                    }
415    
416                    private static final long serialVersionUID = 1L;
417    
418                    private final long _companyId;
419                    private final long _groupId;
420                    private final String _name;
421                    private final long _userId;
422    
423            }
424    
425            private static class UserRoleKey implements IndexedCacheKey<Long> {
426    
427                    @Override
428                    public boolean equals(Object obj) {
429                            UserRoleKey userRoleKey = (UserRoleKey)obj;
430    
431                            if ((userRoleKey._userId == _userId) &&
432                                    (userRoleKey._roleId == _roleId)) {
433    
434                                    return true;
435                            }
436    
437                            return false;
438                    }
439    
440                    @Override
441                    public Long getIndex() {
442                            return _userId;
443                    }
444    
445                    @Override
446                    public int hashCode() {
447                            int hashCode = HashUtil.hash(0, _userId);
448    
449                            return HashUtil.hash(hashCode, _roleId);
450                    }
451    
452                    private UserRoleKey(long userId, long roleId) {
453                            _userId = userId;
454                            _roleId = roleId;
455                    }
456    
457                    private static final long serialVersionUID = 1L;
458    
459                    private final long _roleId;
460                    private final long _userId;
461    
462            }
463    
464    }