DocSpace-client/common/ASC.Core.Common/Caching/CachedUserService.cs

414 lines
14 KiB
C#
Raw Normal View History

2022-03-15 18:00:53 +00:00
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
2021-11-23 12:25:34 +00:00
2022-02-15 11:52:43 +00:00
namespace ASC.Core.Caching;
[Singletone]
public class UserServiceCache
2020-10-19 15:53:15 +00:00
{
2022-02-15 11:52:43 +00:00
public const string Users = "users";
public const string Refs = "refs";
2022-03-25 14:54:34 +00:00
private const string Groups = "groups";
2022-02-15 11:52:43 +00:00
2022-03-25 14:54:34 +00:00
internal readonly ICache Cache;
internal readonly CoreBaseSettings CoreBaseSettings;
internal readonly ICacheNotify<UserInfoCacheItem> CacheUserInfoItem;
internal readonly ICacheNotify<UserPhotoCacheItem> CacheUserPhotoItem;
internal readonly ICacheNotify<GroupCacheItem> CacheGroupCacheItem;
internal readonly ICacheNotify<UserGroupRefCacheItem> CacheUserGroupRefItem;
2022-03-17 16:57:02 +00:00
public UserServiceCache(ICacheNotify<GroupCacheItem> cacheGroupCacheItem)
{
2022-03-25 14:54:34 +00:00
CacheGroupCacheItem = cacheGroupCacheItem;
2022-03-17 16:57:02 +00:00
}
2022-02-15 11:52:43 +00:00
public UserServiceCache(
CoreBaseSettings coreBaseSettings,
ICacheNotify<UserInfoCacheItem> cacheUserInfoItem,
ICacheNotify<UserPhotoCacheItem> cacheUserPhotoItem,
ICacheNotify<GroupCacheItem> cacheGroupCacheItem,
ICacheNotify<UserGroupRefCacheItem> cacheUserGroupRefItem,
ICache cache)
{
2022-03-25 14:54:34 +00:00
Cache = cache;
CoreBaseSettings = coreBaseSettings;
CacheUserInfoItem = cacheUserInfoItem;
CacheUserPhotoItem = cacheUserPhotoItem;
CacheGroupCacheItem = cacheGroupCacheItem;
CacheUserGroupRefItem = cacheUserGroupRefItem;
2022-02-15 11:52:43 +00:00
2022-10-25 20:15:35 +00:00
cacheUserInfoItem.Subscribe((u) => InvalidateCache(u), CacheNotifyAction.Any);
2022-04-15 09:08:06 +00:00
cacheUserPhotoItem.Subscribe((p) => Cache.Remove(p.Key), CacheNotifyAction.Remove);
2022-08-31 18:06:26 +00:00
cacheGroupCacheItem.Subscribe((g) => InvalidateCache(g), CacheNotifyAction.Any);
2022-02-15 11:52:43 +00:00
2022-08-31 18:06:26 +00:00
cacheUserGroupRefItem.Subscribe((r) => UpdateUserGroupRefCache(r), CacheNotifyAction.Remove);
cacheUserGroupRefItem.Subscribe((r) => UpdateUserGroupRefCache(r), CacheNotifyAction.InsertOrUpdate);
2022-02-15 11:52:43 +00:00
}
2021-11-23 12:25:34 +00:00
2022-02-15 11:52:43 +00:00
private void InvalidateCache(UserInfoCacheItem userInfo)
{
if (userInfo != null)
2021-11-23 12:25:34 +00:00
{
2022-10-25 20:15:35 +00:00
var key = GetUserCacheKey(userInfo.Tenant);
2022-03-25 14:54:34 +00:00
Cache.Remove(key);
if (Guid.TryParse(userInfo.Id, out var userId))
{
var userKey = GetUserCacheKey(userInfo.Tenant, userId);
Cache.Remove(userKey);
}
2021-11-23 12:25:34 +00:00
}
2022-02-15 11:52:43 +00:00
}
2022-08-31 18:06:26 +00:00
private void InvalidateCache(GroupCacheItem groupCacheItem)
{
if (groupCacheItem != null)
{
var key = GetGroupCacheKey(groupCacheItem.Tenant, new Guid(groupCacheItem.Id));
Cache.Remove(key);
}
}
2021-11-23 12:25:34 +00:00
2022-08-31 18:06:26 +00:00
private void UpdateUserGroupRefCache(UserGroupRef r)
2022-02-15 11:52:43 +00:00
{
var key = GetRefCacheKey(r.Tenant);
2022-03-25 14:54:34 +00:00
var refs = Cache.Get<UserGroupRefStore>(key);
2022-08-31 18:06:26 +00:00
if (refs != null)
2021-11-23 12:25:34 +00:00
{
2022-02-15 11:52:43 +00:00
lock (refs)
2021-11-23 12:25:34 +00:00
{
2022-02-15 11:52:43 +00:00
refs[r.CreateKey()] = r;
2021-11-23 12:25:34 +00:00
}
}
2022-02-15 11:52:43 +00:00
}
2021-11-23 12:25:34 +00:00
2022-02-15 11:52:43 +00:00
public static string GetUserPhotoCacheKey(int tenant, Guid userId)
{
return tenant.ToString() + "userphoto" + userId.ToString();
}
2021-09-27 16:59:09 +00:00
2022-02-15 11:52:43 +00:00
public static string GetGroupCacheKey(int tenant)
{
2022-03-25 14:54:34 +00:00
return tenant.ToString() + Groups;
2022-02-15 11:52:43 +00:00
}
2021-09-28 17:29:25 +00:00
2022-02-15 11:52:43 +00:00
public static string GetGroupCacheKey(int tenant, Guid groupId)
{
2022-03-25 14:54:34 +00:00
return tenant.ToString() + Groups + groupId;
2022-02-15 11:52:43 +00:00
}
2021-09-28 17:29:25 +00:00
2022-02-15 11:52:43 +00:00
public static string GetRefCacheKey(int tenant)
{
return tenant.ToString() + Refs;
}
public static string GetRefCacheKey(int tenant, Guid groupId, UserGroupRefType refType)
{
return tenant.ToString() + groupId + (int)refType;
}
2021-09-28 17:29:25 +00:00
2022-02-15 11:52:43 +00:00
public static string GetUserCacheKey(int tenant)
{
return tenant.ToString() + Users;
2020-02-20 08:05:10 +00:00
}
2022-02-15 11:52:43 +00:00
public static string GetUserCacheKey(int tenant, Guid userId)
2020-02-20 08:05:10 +00:00
{
2022-02-15 11:52:43 +00:00
return tenant.ToString() + Users + userId;
}
}
2020-02-20 08:05:10 +00:00
2022-02-15 11:52:43 +00:00
[Scope]
public class CachedUserService : IUserService, ICachedService
{
2022-03-25 14:54:34 +00:00
internal IUserService Service { get; set; }
internal ICache Cache { get; set; }
internal CoreBaseSettings CoreBaseSettings { get; set; }
internal UserServiceCache UserServiceCache { get; set; }
internal ICacheNotify<UserInfoCacheItem> CacheUserInfoItem { get; set; }
internal ICacheNotify<UserPhotoCacheItem> CacheUserPhotoItem { get; set; }
internal ICacheNotify<GroupCacheItem> CacheGroupCacheItem { get; set; }
internal ICacheNotify<UserGroupRefCacheItem> CacheUserGroupRefItem { get; set; }
2022-03-17 15:07:17 +00:00
private readonly TimeSpan _cacheExpiration;
private readonly TimeSpan _photoExpiration;
2022-03-17 16:57:02 +00:00
public CachedUserService(ICacheNotify<GroupCacheItem> cacheGroupCacheItem)
{
2022-03-25 14:54:34 +00:00
CacheGroupCacheItem = cacheGroupCacheItem;
2022-03-17 16:57:02 +00:00
}
2022-02-15 11:52:43 +00:00
public CachedUserService()
2021-11-23 12:25:34 +00:00
{
2022-02-15 11:52:43 +00:00
_cacheExpiration = TimeSpan.FromMinutes(20);
_photoExpiration = TimeSpan.FromMinutes(10);
}
2021-11-23 12:25:34 +00:00
2022-02-15 11:52:43 +00:00
public CachedUserService(
EFUserService service,
CoreBaseSettings coreBaseSettings,
UserServiceCache userServiceCache
) : this()
{
2022-03-25 14:54:34 +00:00
Service = service ?? throw new ArgumentNullException(nameof(service));
CoreBaseSettings = coreBaseSettings;
UserServiceCache = userServiceCache;
Cache = userServiceCache.Cache;
CacheUserInfoItem = userServiceCache.CacheUserInfoItem;
CacheUserPhotoItem = userServiceCache.CacheUserPhotoItem;
CacheGroupCacheItem = userServiceCache.CacheGroupCacheItem;
CacheUserGroupRefItem = userServiceCache.CacheUserGroupRefItem;
2022-02-15 11:52:43 +00:00
}
2020-02-20 14:57:48 +00:00
2022-02-15 11:52:43 +00:00
public IQueryable<UserInfo> GetUsers(
int tenant,
2022-10-18 11:22:02 +00:00
bool isDocSpaceAdmin,
2022-02-15 11:52:43 +00:00
EmployeeStatus? employeeStatus,
List<List<Guid>> includeGroups,
List<Guid> excludeGroups,
EmployeeActivationStatus? activationStatus,
2023-05-17 08:20:27 +00:00
AccountLoginType? accountLoginType,
2022-02-15 11:52:43 +00:00
string text,
string sortBy,
bool sortOrderAsc,
long limit,
long offset,
out int total,
out int count)
{
2023-05-17 08:20:27 +00:00
return Service.GetUsers(tenant, isDocSpaceAdmin, employeeStatus, includeGroups, excludeGroups, activationStatus, accountLoginType, text, sortBy, sortOrderAsc, limit, offset, out total, out count);
2022-02-15 11:52:43 +00:00
}
2021-11-23 12:25:34 +00:00
2022-02-15 11:52:43 +00:00
public UserInfo GetUser(int tenant, Guid id)
{
var key = UserServiceCache.GetUserCacheKey(tenant, id);
2022-03-25 14:54:34 +00:00
var user = Cache.Get<UserInfo>(key);
2021-09-27 16:59:09 +00:00
2022-02-15 11:52:43 +00:00
if (user == null)
2021-11-23 12:25:34 +00:00
{
2022-03-25 14:54:34 +00:00
user = Service.GetUser(tenant, id);
2021-09-27 16:59:09 +00:00
2022-02-15 11:52:43 +00:00
if (user != null)
2021-09-27 16:59:09 +00:00
{
2022-03-25 14:54:34 +00:00
Cache.Insert(key, user, _cacheExpiration);
2021-09-27 16:59:09 +00:00
}
2020-12-28 13:22:08 +00:00
}
2022-02-15 11:52:43 +00:00
return user;
}
2020-12-28 13:22:08 +00:00
2022-02-15 11:52:43 +00:00
public UserInfo GetUser(int tenant, string email)
{
2022-03-25 14:54:34 +00:00
return Service.GetUser(tenant, email);
2022-02-15 11:52:43 +00:00
}
2021-09-28 17:29:25 +00:00
2022-02-15 11:52:43 +00:00
public UserInfo GetUserByUserName(int tenant, string userName)
{
2022-03-25 14:54:34 +00:00
return Service.GetUserByUserName(tenant, userName);
2022-02-15 11:52:43 +00:00
}
2021-09-28 17:29:25 +00:00
2022-02-15 11:52:43 +00:00
public UserInfo GetUserByPasswordHash(int tenant, string login, string passwordHash)
{
2022-03-25 14:54:34 +00:00
return Service.GetUserByPasswordHash(tenant, login, passwordHash);
2022-02-15 11:52:43 +00:00
}
public IEnumerable<UserInfo> GetUsersAllTenants(IEnumerable<Guid> userIds)
{
2022-03-25 14:54:34 +00:00
return Service.GetUsersAllTenants(userIds);
2022-02-15 11:52:43 +00:00
}
2022-02-15 11:52:43 +00:00
public UserInfo SaveUser(int tenant, UserInfo user)
{
2022-03-25 14:54:34 +00:00
user = Service.SaveUser(tenant, user);
CacheUserInfoItem.Publish(new UserInfoCacheItem { Id = user.Id.ToString(), Tenant = tenant }, CacheNotifyAction.Any);
2022-02-15 11:52:43 +00:00
return user;
}
2021-11-23 12:25:34 +00:00
public IEnumerable<int> GetTenantsWithFeeds(DateTime from)
{
return Service.GetTenantsWithFeeds(from);
}
2022-02-15 11:52:43 +00:00
public void RemoveUser(int tenant, Guid id)
{
2022-03-25 14:54:34 +00:00
Service.RemoveUser(tenant, id);
CacheUserInfoItem.Publish(new UserInfoCacheItem { Tenant = tenant, Id = id.ToString() }, CacheNotifyAction.Any);
2022-02-15 11:52:43 +00:00
}
public byte[] GetUserPhoto(int tenant, Guid id)
{
2022-03-25 14:54:34 +00:00
var photo = Cache.Get<byte[]>(UserServiceCache.GetUserPhotoCacheKey(tenant, id));
2022-02-15 11:52:43 +00:00
if (photo == null)
{
2022-03-25 14:54:34 +00:00
photo = Service.GetUserPhoto(tenant, id);
Cache.Insert(UserServiceCache.GetUserPhotoCacheKey(tenant, id), photo, _photoExpiration);
2021-11-23 12:25:34 +00:00
}
2021-09-28 17:29:25 +00:00
2022-02-15 11:52:43 +00:00
return photo;
}
2022-02-15 11:52:43 +00:00
public void SetUserPhoto(int tenant, Guid id, byte[] photo)
{
2022-03-25 14:54:34 +00:00
Service.SetUserPhoto(tenant, id, photo);
2022-04-15 09:08:06 +00:00
CacheUserPhotoItem.Publish(new UserPhotoCacheItem { Key = UserServiceCache.GetUserPhotoCacheKey(tenant, id) }, CacheNotifyAction.Remove);
CacheUserInfoItem.Publish(new UserInfoCacheItem { Id = id.ToString(), Tenant = tenant }, CacheNotifyAction.Any);
2022-02-15 11:52:43 +00:00
}
2021-09-28 17:29:25 +00:00
2022-02-15 11:52:43 +00:00
public DateTime GetUserPasswordStamp(int tenant, Guid id)
{
2022-03-25 14:54:34 +00:00
return Service.GetUserPasswordStamp(tenant, id);
2022-02-15 11:52:43 +00:00
}
2021-11-23 12:25:34 +00:00
2022-02-15 11:52:43 +00:00
public void SetUserPasswordHash(int tenant, Guid id, string passwordHash)
{
2022-03-25 14:54:34 +00:00
Service.SetUserPasswordHash(tenant, id, passwordHash);
2022-02-15 11:52:43 +00:00
}
2022-02-15 11:52:43 +00:00
public Group GetGroup(int tenant, Guid id)
{
var key = UserServiceCache.GetGroupCacheKey(tenant, id);
2022-03-25 14:54:34 +00:00
var group = Cache.Get<Group>(key);
2021-09-27 16:59:09 +00:00
2022-02-15 11:52:43 +00:00
if (group == null)
2021-09-27 16:59:09 +00:00
{
2022-03-25 14:54:34 +00:00
group = Service.GetGroup(tenant, id);
2021-09-27 16:59:09 +00:00
2022-03-17 15:01:39 +00:00
if (group != null)
{
2022-03-25 14:54:34 +00:00
Cache.Insert(key, group, _cacheExpiration);
2022-03-17 15:01:39 +00:00
}
2022-02-15 11:52:43 +00:00
}
2021-09-27 16:59:09 +00:00
2022-02-15 11:52:43 +00:00
return group;
}
2021-09-27 16:59:09 +00:00
2022-02-15 11:52:43 +00:00
public Group SaveGroup(int tenant, Group group)
{
2022-03-25 14:54:34 +00:00
group = Service.SaveGroup(tenant, group);
2022-08-31 18:06:26 +00:00
CacheGroupCacheItem.Publish(new GroupCacheItem { Id = group.Id.ToString(), Tenant = tenant }, CacheNotifyAction.Any);
2021-11-23 12:25:34 +00:00
2022-02-15 11:52:43 +00:00
return group;
}
2022-02-15 11:52:43 +00:00
public void RemoveGroup(int tenant, Guid id)
{
2022-03-25 14:54:34 +00:00
Service.RemoveGroup(tenant, id);
2022-08-31 18:06:26 +00:00
CacheGroupCacheItem.Publish(new GroupCacheItem { Id = id.ToString(), Tenant = tenant }, CacheNotifyAction.Any);
2022-02-15 11:52:43 +00:00
}
2021-11-23 12:25:34 +00:00
2022-02-15 11:52:43 +00:00
public IDictionary<string, UserGroupRef> GetUserGroupRefs(int tenant)
{
var key = UserServiceCache.GetRefCacheKey(tenant);
2022-04-14 19:23:57 +00:00
if (Cache.Get<UserGroupRefStore>(key) is not IDictionary<string, UserGroupRef> refs)
2021-11-23 12:25:34 +00:00
{
2022-03-25 14:54:34 +00:00
refs = Service.GetUserGroupRefs(tenant);
Cache.Insert(key, new UserGroupRefStore(refs), _cacheExpiration);
2021-11-23 12:25:34 +00:00
}
2022-02-15 11:52:43 +00:00
return refs;
}
2021-11-23 12:25:34 +00:00
2022-02-15 11:52:43 +00:00
public UserGroupRef GetUserGroupRef(int tenant, Guid groupId, UserGroupRefType refType)
{
var key = UserServiceCache.GetRefCacheKey(tenant, groupId, refType);
2022-03-25 14:54:34 +00:00
var groupRef = Cache.Get<UserGroupRef>(key);
2022-02-15 11:52:43 +00:00
if (groupRef == null)
2021-11-23 12:25:34 +00:00
{
2022-03-25 14:54:34 +00:00
groupRef = Service.GetUserGroupRef(tenant, groupId, refType);
2022-02-15 11:52:43 +00:00
if (groupRef != null)
2021-11-23 12:25:34 +00:00
{
2022-03-25 14:54:34 +00:00
Cache.Insert(key, groupRef, _cacheExpiration);
2021-11-23 12:25:34 +00:00
}
2021-09-28 17:29:25 +00:00
}
2022-02-15 11:52:43 +00:00
return groupRef;
}
2021-09-28 17:29:25 +00:00
2022-02-15 11:52:43 +00:00
public UserGroupRef SaveUserGroupRef(int tenant, UserGroupRef r)
{
2022-03-25 14:54:34 +00:00
r = Service.SaveUserGroupRef(tenant, r);
CacheUserGroupRefItem.Publish(r, CacheNotifyAction.InsertOrUpdate);
2021-09-28 17:29:25 +00:00
2022-02-15 11:52:43 +00:00
return r;
}
2021-09-28 17:29:25 +00:00
2022-02-15 11:52:43 +00:00
public void RemoveUserGroupRef(int tenant, Guid userId, Guid groupId, UserGroupRefType refType)
{
2022-03-25 14:54:34 +00:00
Service.RemoveUserGroupRef(tenant, userId, groupId, refType);
2021-11-23 12:25:34 +00:00
2022-08-31 18:06:26 +00:00
var r = new UserGroupRef(userId, groupId, refType) { Tenant = tenant, Removed = true };
2022-03-25 14:54:34 +00:00
CacheUserGroupRefItem.Publish(r, CacheNotifyAction.Remove);
2022-02-15 11:52:43 +00:00
}
2021-11-23 12:25:34 +00:00
2022-02-15 11:52:43 +00:00
public IEnumerable<UserInfo> GetUsers(int tenant)
{
var key = UserServiceCache.GetUserCacheKey(tenant);
2022-03-25 14:54:34 +00:00
var users = Cache.Get<IEnumerable<UserInfo>>(key);
2022-02-15 11:52:43 +00:00
if (users == null)
2021-11-23 12:25:34 +00:00
{
2022-03-25 14:54:34 +00:00
users = Service.GetUsers(tenant);
2021-11-23 12:25:34 +00:00
2022-03-25 14:54:34 +00:00
Cache.Insert(key, users, _cacheExpiration);
2021-11-23 12:25:34 +00:00
}
2022-02-15 11:52:43 +00:00
return users;
}
2021-11-23 12:25:34 +00:00
2022-02-15 11:52:43 +00:00
public IEnumerable<Group> GetGroups(int tenant)
{
var key = UserServiceCache.GetGroupCacheKey(tenant);
2022-03-25 14:54:34 +00:00
var groups = Cache.Get<IEnumerable<Group>>(key);
2022-02-15 11:52:43 +00:00
if (groups == null)
2021-11-23 12:25:34 +00:00
{
2022-03-25 14:54:34 +00:00
groups = Service.GetGroups(tenant);
Cache.Insert(key, groups, _cacheExpiration);
2021-11-23 12:25:34 +00:00
}
2021-09-28 17:29:25 +00:00
2022-02-15 11:52:43 +00:00
return groups;
}
2022-02-15 11:52:43 +00:00
public void InvalidateCache()
{
}
2021-11-23 12:25:34 +00:00
2022-02-15 11:52:43 +00:00
public UserInfo GetUser(int tenant, Guid id, Expression<Func<User, UserInfo>> exp)
{
if (exp == null)
2021-11-23 12:25:34 +00:00
{
2022-02-15 11:52:43 +00:00
return GetUser(tenant, id);
2021-11-23 12:25:34 +00:00
}
2020-02-25 08:02:13 +00:00
2022-03-25 14:54:34 +00:00
return Service.GetUser(tenant, id, exp);
2021-11-23 12:25:34 +00:00
}
2022-06-01 14:07:08 +00:00
public IEnumerable<string> GetDavUserEmails(int tenant)
{
return Service.GetDavUserEmails(tenant);
}
2021-11-23 12:25:34 +00:00
}