DocSpace-buildtools/common/ASC.Core.Common/Data/DbUserService.cs

753 lines
27 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
2022-02-15 11:52:43 +00:00
namespace ASC.Core.Data;
[Scope]
public class EFUserService : IUserService
{
2022-07-28 12:29:03 +00:00
private readonly IDbContextFactory<UserDbContext> _dbContextFactory;
private readonly MachinePseudoKeys _machinePseudoKeys;
2022-02-15 11:52:43 +00:00
private readonly IMapper _mapper;
public EFUserService(
2022-07-28 12:29:03 +00:00
IDbContextFactory<UserDbContext> dbContextFactory,
2022-02-15 11:52:43 +00:00
MachinePseudoKeys machinePseudoKeys,
IMapper mapper)
{
2022-07-28 12:29:03 +00:00
_dbContextFactory = dbContextFactory;
_machinePseudoKeys = machinePseudoKeys;
2022-02-15 11:52:43 +00:00
_mapper = mapper;
2020-02-20 08:05:10 +00:00
}
2022-02-15 11:52:43 +00:00
public Group GetGroup(int tenant, Guid id)
2019-11-15 15:04:05 +00:00
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
return GetGroupQuery(userDbContext, tenant)
2022-02-15 11:52:43 +00:00
.Where(r => r.Id == id)
.ProjectTo<Group>(_mapper.ConfigurationProvider)
.FirstOrDefault();
}
2019-11-25 11:49:21 +00:00
2022-02-15 11:52:43 +00:00
public IEnumerable<Group> GetGroups(int tenant)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
return GetGroupQuery(userDbContext, tenant)
2022-02-15 11:52:43 +00:00
.ProjectTo<Group>(_mapper.ConfigurationProvider)
.ToList();
}
2020-11-24 10:15:11 +00:00
2022-02-15 11:52:43 +00:00
public UserInfo GetUser(int tenant, Guid id)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
return GetUserQuery(userDbContext, tenant)
2022-02-15 11:52:43 +00:00
.Where(r => r.Id == id)
.ProjectTo<UserInfo>(_mapper.ConfigurationProvider)
.FirstOrDefault();
}
2020-02-20 14:57:48 +00:00
2022-02-15 11:52:43 +00:00
public UserInfo GetUser(int tenant, string email)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
return GetUserQuery(userDbContext, tenant)
2022-02-15 11:52:43 +00:00
.ProjectTo<UserInfo>(_mapper.ConfigurationProvider)
.FirstOrDefault(r => r.Email == email && !r.Removed);
}
2019-11-15 15:04:05 +00:00
2022-02-15 11:52:43 +00:00
public UserInfo GetUserByUserName(int tenant, string userName)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
return GetUserQuery(userDbContext, tenant)
2022-02-15 11:52:43 +00:00
.ProjectTo<UserInfo>(_mapper.ConfigurationProvider)
.FirstOrDefault(r => r.UserName == userName && !r.Removed);
}
2019-11-15 15:04:05 +00:00
2022-02-15 11:52:43 +00:00
public UserInfo GetUserByPasswordHash(int tenant, string login, string passwordHash)
{
2022-03-09 17:15:51 +00:00
ArgumentNullOrEmptyException.ThrowIfNullOrEmpty(login);
2019-11-15 15:04:05 +00:00
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
2022-02-15 11:52:43 +00:00
if (Guid.TryParse(login, out var userId))
2020-12-28 13:22:08 +00:00
{
2022-02-15 11:52:43 +00:00
var pwdHash = GetPasswordHash(userId, passwordHash);
2021-08-06 14:30:51 +00:00
2022-07-28 12:29:03 +00:00
var q = GetUserQuery(userDbContext, tenant)
2022-02-15 11:52:43 +00:00
.Where(r => !r.Removed)
.Where(r => r.Id == userId)
2022-07-28 12:29:03 +00:00
.Join(userDbContext.UserSecurity, r => r.Id, r => r.UserId, (user, security) => new DbUserSecurity
2022-02-15 11:52:43 +00:00
{
User = user,
UserSecurity = security
})
2022-06-01 14:07:08 +00:00
.Where(r => r.UserSecurity.PwdHash == pwdHash)
2022-02-15 11:52:43 +00:00
;
if (tenant != Tenant.DefaultTenant)
{
2022-02-15 11:52:43 +00:00
q = q.Where(r => r.UserSecurity.Tenant == tenant);
}
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
return q.Select(r => r.User)
.ProjectTo<UserInfo>(_mapper.ConfigurationProvider)
.FirstOrDefault();
}
else
{
2022-07-28 12:29:03 +00:00
var q = GetUserQuery(userDbContext, tenant)
2022-02-15 11:52:43 +00:00
.Where(r => !r.Removed)
.Where(r => r.Email == login);
var users = q.ProjectTo<UserInfo>(_mapper.ConfigurationProvider).ToList();
foreach (var user in users)
2019-11-25 09:49:12 +00:00
{
2022-02-15 11:52:43 +00:00
var pwdHash = GetPasswordHash(user.Id, passwordHash);
2022-07-28 12:29:03 +00:00
var any = userDbContext.UserSecurity
2022-06-01 14:07:08 +00:00
.Any(r => r.UserId == user.Id && (r.PwdHash == pwdHash));
2022-02-15 11:52:43 +00:00
if (any)
{
2022-06-01 14:07:08 +00:00
return user;
2022-02-15 11:52:43 +00:00
}
2019-11-25 09:49:12 +00:00
}
2020-12-23 10:12:07 +00:00
2022-06-01 14:07:08 +00:00
return null;
2022-02-15 11:52:43 +00:00
}
}
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
public IEnumerable<UserInfo> GetUsersAllTenants(IEnumerable<Guid> userIds)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
var q = userDbContext.Users
2022-02-15 11:52:43 +00:00
.Where(r => userIds.Contains(r.Id))
.Where(r => !r.Removed);
2022-02-15 11:52:43 +00:00
return q.ProjectTo<UserInfo>(_mapper.ConfigurationProvider).ToList();
}
2022-02-15 11:52:43 +00:00
public UserGroupRef GetUserGroupRef(int tenant, Guid groupId, UserGroupRefType refType)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
IQueryable<UserGroup> q = userDbContext.UserGroups;
2020-12-28 13:22:08 +00:00
2022-02-15 11:52:43 +00:00
if (tenant != Tenant.DefaultTenant)
{
q = q.Where(r => r.Tenant == tenant);
}
2022-07-22 19:31:42 +00:00
return q.Where(r => r.UserGroupId == groupId && r.RefType == refType && !r.Removed)
2022-02-15 11:52:43 +00:00
.ProjectTo<UserGroupRef>(_mapper.ConfigurationProvider).SingleOrDefault();
}
2020-12-28 13:22:08 +00:00
2022-02-15 11:52:43 +00:00
public IDictionary<string, UserGroupRef> GetUserGroupRefs(int tenant)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
IQueryable<UserGroup> q = userDbContext.UserGroups;
2019-11-15 15:04:05 +00:00
2022-02-15 11:52:43 +00:00
if (tenant != Tenant.DefaultTenant)
{
2022-02-15 11:52:43 +00:00
q = q.Where(r => r.Tenant == tenant);
}
2022-02-15 11:52:43 +00:00
return q.ProjectTo<UserGroupRef>(_mapper.ConfigurationProvider)
.AsEnumerable().ToDictionary(r => r.CreateKey(), r => r);
}
2022-02-15 11:52:43 +00:00
public DateTime GetUserPasswordStamp(int tenant, Guid id)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
var stamp = userDbContext.UserSecurity
2022-02-15 11:52:43 +00:00
.Where(r => r.Tenant == tenant)
.Where(r => r.UserId == id)
.Select(r => r.LastModified)
.FirstOrDefault();
2022-02-15 11:52:43 +00:00
return stamp ?? DateTime.MinValue;
}
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
public byte[] GetUserPhoto(int tenant, Guid id)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
var photo = userDbContext.Photos
2022-02-15 11:52:43 +00:00
.Where(r => r.Tenant == tenant)
.Where(r => r.UserId == id)
.Select(r => r.Photo)
.FirstOrDefault();
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
return photo ?? Array.Empty<byte>();
}
2019-11-15 15:04:05 +00:00
2022-02-15 11:52:43 +00:00
public IEnumerable<UserInfo> GetUsers(int tenant)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
return GetUserQuery(userDbContext, tenant)
2022-02-15 11:52:43 +00:00
.ProjectTo<UserInfo>(_mapper.ConfigurationProvider)
.ToList();
}
2019-11-25 09:49:12 +00:00
2022-10-18 11:22:02 +00:00
public IQueryable<UserInfo> GetUsers(int tenant, bool isDocSpaceAdmin, EmployeeStatus? employeeStatus, List<List<Guid>> includeGroups, List<Guid> excludeGroups, EmployeeActivationStatus? activationStatus, string text, string sortBy, bool sortOrderAsc, long limit, long offset, out int total, out int count)
2022-02-15 11:52:43 +00:00
{
2022-07-28 12:29:03 +00:00
var userDbContext = _dbContextFactory.CreateDbContext();
2022-02-15 11:52:43 +00:00
var totalQuery = GetUserQuery(userDbContext, tenant);
2022-10-18 11:22:02 +00:00
totalQuery = GetUserQueryForFilter(userDbContext, totalQuery, isDocSpaceAdmin, employeeStatus, includeGroups, excludeGroups, activationStatus, text);
2022-02-15 11:52:43 +00:00
total = totalQuery.Count();
2019-11-15 15:04:05 +00:00
2022-02-15 11:52:43 +00:00
var q = GetUserQuery(userDbContext, tenant);
2022-10-18 11:22:02 +00:00
q = GetUserQueryForFilter(userDbContext, q, isDocSpaceAdmin, employeeStatus, includeGroups, excludeGroups, activationStatus, text);
2019-11-25 09:49:12 +00:00
2023-01-25 12:58:30 +00:00
var orderedQuery = q.OrderBy(r => r.ActivationStatus == EmployeeActivationStatus.Pending);
q = orderedQuery;
2022-02-15 11:52:43 +00:00
if (!string.IsNullOrEmpty(sortBy))
{
2022-11-14 09:17:33 +00:00
if (sortBy == "type")
{
2022-12-21 12:57:32 +00:00
var q1 = from user in q
join userGroup in userDbContext.UserGroups.Where(g => !g.Removed && (g.UserGroupId == Users.Constants.GroupAdmin.ID || g.UserGroupId == Users.Constants.GroupUser.ID))
on user.Id equals userGroup.Userid into joinedGroup
from @group in joinedGroup.DefaultIfEmpty()
select new { user, @group };
2022-11-14 09:17:33 +00:00
2023-01-25 12:58:30 +00:00
if (sortOrderAsc)
{
q = q1.OrderBy(r => r.user.ActivationStatus == EmployeeActivationStatus.Pending)
.ThenBy(r => r.group != null && r.group.UserGroupId == Users.Constants.GroupAdmin.ID ? 1 : r.group == null ? 2 : 3).Select(r => r.user);
}
else
{
q = q1.OrderBy(r => r.user.ActivationStatus == EmployeeActivationStatus.Pending)
.ThenByDescending(u => u.group != null && u.group.UserGroupId == Users.Constants.GroupAdmin.ID ? 1 : u.group == null ? 2 : 3).Select(r => r.user);
}
2022-11-14 09:17:33 +00:00
}
else
{
2023-01-25 12:58:30 +00:00
q = orderedQuery.ThenBy(sortBy, sortOrderAsc);
2022-11-14 09:17:33 +00:00
}
2019-11-15 15:04:05 +00:00
}
2022-02-15 11:52:43 +00:00
if (offset != 0)
2019-11-15 15:04:05 +00:00
{
2022-02-15 11:52:43 +00:00
q = q.Skip((int)offset);
2019-11-25 09:49:12 +00:00
}
2022-02-15 11:52:43 +00:00
if (limit != 0)
2019-11-25 09:49:12 +00:00
{
2022-02-15 11:52:43 +00:00
q = q.Take((int)limit);
}
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
count = q.Count();
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
return q.ProjectTo<UserInfo>(_mapper.ConfigurationProvider);
}
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
public IQueryable<UserInfo> GetUsers(int tenant, out int total)
{
2022-07-28 12:29:03 +00:00
var userDbContext = _dbContextFactory.CreateDbContext();
2022-02-15 11:52:43 +00:00
total = userDbContext.Users.Count(r => r.Tenant == tenant);
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
return GetUserQuery(userDbContext, tenant)
.ProjectTo<UserInfo>(_mapper.ConfigurationProvider);
}
2019-11-25 09:49:12 +00:00
public IEnumerable<int> GetTenantsWithFeeds(DateTime from)
{
var userDbContext = _dbContextFactory.CreateDbContext();
var tenants = userDbContext.Users.Where(u => u.LastModified > from).Select(u => u.Tenant).Distinct().ToList();
return tenants;
}
2022-02-15 11:52:43 +00:00
public void RemoveGroup(int tenant, Guid id)
{
RemoveGroup(tenant, id, false);
}
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
public void RemoveGroup(int tenant, Guid id, bool immediate)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
var ids = CollectGroupChilds(userDbContext, tenant, id);
2022-02-15 11:52:43 +00:00
var stringIds = ids.Select(r => r.ToString()).ToList();
2019-11-25 09:49:12 +00:00
2022-07-28 12:29:03 +00:00
var strategy = userDbContext.Database.CreateExecutionStrategy();
2019-11-15 15:04:05 +00:00
strategy.Execute(() =>
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
using var tr = userDbContext.Database.BeginTransaction();
2019-11-15 15:04:05 +00:00
2022-07-28 12:29:03 +00:00
userDbContext.Acl.RemoveRange(userDbContext.Acl.Where(r => r.Tenant == tenant && ids.Any(i => i == r.Subject)));
userDbContext.Subscriptions.RemoveRange(userDbContext.Subscriptions.Where(r => r.Tenant == tenant && stringIds.Any(i => i == r.Recipient)));
userDbContext.SubscriptionMethods.RemoveRange(userDbContext.SubscriptionMethods.Where(r => r.Tenant == tenant && stringIds.Any(i => i == r.Recipient)));
2019-11-25 09:49:12 +00:00
2022-07-28 12:29:03 +00:00
var userGroups = userDbContext.UserGroups.Where(r => r.Tenant == tenant && ids.Any(i => i == r.UserGroupId));
var groups = userDbContext.Groups.Where(r => r.Tenant == tenant && ids.Any(i => i == r.Id));
if (immediate)
2019-11-25 09:49:12 +00:00
{
2022-07-28 12:29:03 +00:00
userDbContext.UserGroups.RemoveRange(userGroups);
userDbContext.Groups.RemoveRange(groups);
2019-11-25 09:49:12 +00:00
}
else
2019-11-25 09:49:12 +00:00
{
foreach (var ug in userGroups)
{
ug.Removed = true;
ug.LastModified = DateTime.UtcNow;
}
foreach (var g in groups)
{
g.Removed = true;
g.LastModified = DateTime.UtcNow;
}
2019-11-25 09:49:12 +00:00
}
2019-11-15 15:04:05 +00:00
2022-07-28 12:29:03 +00:00
userDbContext.SaveChanges();
tr.Commit();
});
2022-02-15 11:52:43 +00:00
}
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
public void RemoveUser(int tenant, Guid id)
{
RemoveUser(tenant, id, false);
}
2019-11-29 13:47:05 +00:00
2022-02-15 11:52:43 +00:00
public void RemoveUser(int tenant, Guid id, bool immediate)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
var strategy = userDbContext.Database.CreateExecutionStrategy();
2022-02-15 11:52:43 +00:00
strategy.Execute(() =>
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
using var tr = userDbContext.Database.BeginTransaction();
2019-11-25 09:49:12 +00:00
2022-07-28 12:29:03 +00:00
userDbContext.Acl.RemoveRange(userDbContext.Acl.Where(r => r.Tenant == tenant && r.Subject == id));
userDbContext.Subscriptions.RemoveRange(userDbContext.Subscriptions.Where(r => r.Tenant == tenant && r.Recipient == id.ToString()));
userDbContext.SubscriptionMethods.RemoveRange(userDbContext.SubscriptionMethods.Where(r => r.Tenant == tenant && r.Recipient == id.ToString()));
userDbContext.Photos.RemoveRange(userDbContext.Photos.Where(r => r.Tenant == tenant && r.UserId == id));
2019-11-25 09:49:12 +00:00
2022-07-28 12:29:03 +00:00
var userGroups = userDbContext.UserGroups.Where(r => r.Tenant == tenant && r.Userid == id);
var users = userDbContext.Users.Where(r => r.Tenant == tenant && r.Id == id);
var userSecurity = userDbContext.UserSecurity.Where(r => r.Tenant == tenant && r.UserId == id);
if (immediate)
2019-11-25 09:49:12 +00:00
{
2022-07-28 12:29:03 +00:00
userDbContext.UserGroups.RemoveRange(userGroups);
userDbContext.Users.RemoveRange(users);
userDbContext.UserSecurity.RemoveRange(userSecurity);
2019-11-25 09:49:12 +00:00
}
else
2022-02-15 11:52:43 +00:00
{
foreach (var ug in userGroups)
{
ug.Removed = true;
ug.LastModified = DateTime.UtcNow;
}
foreach (var u in users)
{
u.Removed = true;
u.Status = EmployeeStatus.Terminated;
u.TerminatedDate = DateTime.UtcNow;
u.LastModified = DateTime.UtcNow;
}
2019-11-25 09:49:12 +00:00
}
2022-07-28 12:29:03 +00:00
userDbContext.SaveChanges();
2019-11-29 13:47:05 +00:00
tr.Commit();
});
2022-02-15 11:52:43 +00:00
}
2019-11-15 15:04:05 +00:00
2022-02-15 11:52:43 +00:00
public void RemoveUserGroupRef(int tenant, Guid userId, Guid groupId, UserGroupRefType refType)
{
RemoveUserGroupRef(tenant, userId, groupId, refType, false);
}
public void RemoveUserGroupRef(int tenant, Guid userId, Guid groupId, UserGroupRefType refType, bool immediate)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
var strategy = userDbContext.Database.CreateExecutionStrategy();
2022-02-15 11:52:43 +00:00
strategy.Execute(() =>
2019-11-25 09:49:12 +00:00
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
using var tr = userDbContext.Database.BeginTransaction();
2022-07-28 12:29:03 +00:00
var userGroups = userDbContext.UserGroups.Where(r => r.Tenant == tenant && r.Userid == userId && r.UserGroupId == groupId && r.RefType == refType);
if (immediate)
2019-11-25 09:49:12 +00:00
{
2022-07-28 12:29:03 +00:00
userDbContext.UserGroups.RemoveRange(userGroups);
2019-11-25 09:49:12 +00:00
}
else
{
foreach (var u in userGroups)
{
u.LastModified = DateTime.UtcNow;
u.Removed = true;
}
}
2022-07-28 12:29:03 +00:00
var user = userDbContext.Users.First(r => r.Tenant == tenant && r.Id == userId);
user.LastModified = DateTime.UtcNow;
2022-07-28 12:29:03 +00:00
userDbContext.SaveChanges();
2019-11-29 13:47:05 +00:00
tr.Commit();
});
2022-02-15 11:52:43 +00:00
}
public Group SaveGroup(int tenant, Group group)
{
2022-03-09 17:15:51 +00:00
ArgumentNullException.ThrowIfNull(group);
2019-11-15 15:04:05 +00:00
2022-02-15 11:52:43 +00:00
if (group.Id == default)
2019-11-15 15:04:05 +00:00
{
2022-02-15 11:52:43 +00:00
group.Id = Guid.NewGuid();
}
2022-02-15 11:52:43 +00:00
group.LastModified = DateTime.UtcNow;
group.Tenant = tenant;
2022-02-15 11:52:43 +00:00
var dbGroup = _mapper.Map<Group, DbGroup>(group);
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
2022-12-21 12:57:32 +00:00
userDbContext.AddOrUpdate(userDbContext.Groups, dbGroup);
2022-07-28 12:29:03 +00:00
userDbContext.SaveChanges();
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
return group;
}
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
public UserInfo SaveUser(int tenant, UserInfo user)
{
2022-03-09 17:15:51 +00:00
ArgumentNullException.ThrowIfNull(user);
2019-11-15 15:04:05 +00:00
2022-02-15 11:52:43 +00:00
if (string.IsNullOrEmpty(user.UserName))
2019-11-15 15:04:05 +00:00
{
2022-02-15 11:52:43 +00:00
throw new ArgumentOutOfRangeException("Empty username.");
}
2022-02-15 11:52:43 +00:00
if (user.Id == default)
{
user.Id = Guid.NewGuid();
}
2022-02-15 11:52:43 +00:00
if (user.CreateDate == default)
{
user.CreateDate = DateTime.UtcNow;
}
2022-02-15 11:52:43 +00:00
user.LastModified = DateTime.UtcNow;
user.Tenant = tenant;
user.UserName = user.UserName.Trim();
user.Email = user.Email.Trim();
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
var strategy = userDbContext.Database.CreateExecutionStrategy();
2019-11-25 09:49:12 +00:00
strategy.Execute(() =>
2022-02-15 11:52:43 +00:00
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
using var tx = userDbContext.Database.BeginTransaction();
var any = GetUserQuery(userDbContext, tenant)
.Any(r => r.UserName == user.UserName && r.Id != user.Id && !r.Removed);
2019-11-25 09:49:12 +00:00
if (any)
{
throw new ArgumentOutOfRangeException("Duplicate username.");
}
2019-11-25 09:49:12 +00:00
2022-07-28 12:29:03 +00:00
any = GetUserQuery(userDbContext, tenant)
.Any(r => r.Email == user.Email && r.Id != user.Id && !r.Removed);
2019-12-17 13:01:59 +00:00
if (any)
{
throw new ArgumentOutOfRangeException("Duplicate email.");
}
2022-12-21 12:57:32 +00:00
userDbContext.AddOrUpdate(userDbContext.Users, _mapper.Map<UserInfo, User>(user));
2022-07-28 12:29:03 +00:00
userDbContext.SaveChanges();
tx.Commit();
});
2019-12-17 13:01:59 +00:00
2022-02-15 11:52:43 +00:00
return user;
}
2019-11-25 09:49:12 +00:00
2022-03-09 17:15:51 +00:00
public UserGroupRef SaveUserGroupRef(int tenant, UserGroupRef userGroupRef)
2022-02-15 11:52:43 +00:00
{
2022-03-09 17:15:51 +00:00
ArgumentNullException.ThrowIfNull(userGroupRef);
2019-11-15 15:04:05 +00:00
2022-03-09 17:15:51 +00:00
userGroupRef.LastModified = DateTime.UtcNow;
userGroupRef.Tenant = tenant;
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
var strategy = userDbContext.Database.CreateExecutionStrategy();
2019-11-25 09:49:12 +00:00
strategy.Execute(() =>
2022-02-15 11:52:43 +00:00
{
2022-07-28 12:29:03 +00:00
using var tr = userDbContext.Database.BeginTransaction();
2022-07-28 12:29:03 +00:00
var user = GetUserQuery(userDbContext, tenant).FirstOrDefault(a => a.Tenant == tenant && a.Id == userGroupRef.UserId);
if (user != null)
{
user.LastModified = userGroupRef.LastModified;
2022-12-21 12:57:32 +00:00
userDbContext.AddOrUpdate(userDbContext.UserGroups, _mapper.Map<UserGroupRef, UserGroup>(userGroupRef));
}
2022-07-28 12:29:03 +00:00
userDbContext.SaveChanges();
tr.Commit();
});
2019-11-29 13:47:05 +00:00
2019-11-25 09:49:12 +00:00
2022-03-09 17:15:51 +00:00
return userGroupRef;
2022-02-15 11:52:43 +00:00
}
2019-11-29 13:47:05 +00:00
2022-02-15 11:52:43 +00:00
public void SetUserPasswordHash(int tenant, Guid id, string passwordHash)
{
var h1 = GetPasswordHash(id, passwordHash);
2019-11-15 15:04:05 +00:00
2022-02-15 11:52:43 +00:00
var us = new UserSecurity
2019-11-15 15:04:05 +00:00
{
2022-02-15 11:52:43 +00:00
Tenant = tenant,
UserId = id,
PwdHash = h1,
LastModified = DateTime.UtcNow
};
2019-11-25 09:49:12 +00:00
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
2022-12-21 12:57:32 +00:00
userDbContext.AddOrUpdate(userDbContext.UserSecurity, us);
2022-07-28 12:29:03 +00:00
userDbContext.SaveChanges();
2022-02-15 11:52:43 +00:00
}
2019-12-17 13:01:59 +00:00
2022-02-15 11:52:43 +00:00
public void SetUserPhoto(int tenant, Guid id, byte[] photo)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
var strategy = userDbContext.Database.CreateExecutionStrategy();
2019-11-15 15:04:05 +00:00
strategy.Execute(() =>
2019-11-15 15:04:05 +00:00
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
using var tr = userDbContext.Database.BeginTransaction();
2022-07-28 12:29:03 +00:00
var userPhoto = userDbContext.Photos.FirstOrDefault(r => r.UserId == id && r.Tenant == tenant);
if (photo != null && photo.Length != 0)
2019-11-25 09:49:12 +00:00
{
if (userPhoto == null)
{
userPhoto = new UserPhoto
{
Tenant = tenant,
UserId = id,
Photo = photo
};
}
else
2019-11-25 09:49:12 +00:00
{
userPhoto.Photo = photo;
}
2022-12-21 12:57:32 +00:00
userDbContext.AddOrUpdate(userDbContext.Photos, userPhoto);
2019-11-25 09:49:12 +00:00
}
else if (userPhoto != null)
2019-11-25 09:49:12 +00:00
{
2022-07-28 12:29:03 +00:00
userDbContext.Photos.Remove(userPhoto);
2019-11-25 09:49:12 +00:00
}
2022-07-28 12:29:03 +00:00
userDbContext.SaveChanges();
tr.Commit();
});
2022-02-15 11:52:43 +00:00
}
2022-02-15 11:52:43 +00:00
private IQueryable<User> GetUserQuery(UserDbContext userDbContext, int tenant)
{
var q = userDbContext.Users.AsQueryable();
var where = false;
2022-02-15 11:52:43 +00:00
if (tenant != Tenant.DefaultTenant)
{
q = q.Where(r => r.Tenant == tenant);
where = true;
2019-11-25 09:49:12 +00:00
}
2022-02-15 11:52:43 +00:00
if (!where)
2019-11-25 09:49:12 +00:00
{
2022-02-15 11:52:43 +00:00
q = q.Where(r => 1 == 0);
}
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
return q;
}
2022-07-28 12:29:03 +00:00
private IQueryable<DbGroup> GetGroupQuery(UserDbContext userDbContext, int tenant)
2022-02-15 11:52:43 +00:00
{
2022-07-28 12:29:03 +00:00
var q = userDbContext.Groups.Where(r => true);
2022-02-15 11:52:43 +00:00
if (tenant != Tenant.DefaultTenant)
{
2022-02-15 11:52:43 +00:00
q = q.Where(r => r.Tenant == tenant);
}
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
return q;
}
2022-02-15 11:52:43 +00:00
private IQueryable<User> GetUserQueryForFilter(
2022-07-28 12:29:03 +00:00
UserDbContext userDbContext,
2022-02-15 11:52:43 +00:00
IQueryable<User> q,
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,
string text)
{
q = q.Where(r => !r.Removed);
2022-02-15 11:52:43 +00:00
if (includeGroups != null && includeGroups.Count > 0)
{
foreach (var ig in includeGroups)
2019-08-14 12:12:48 +00:00
{
2022-07-28 12:29:03 +00:00
q = q.Where(r => userDbContext.UserGroups.Any(a => !a.Removed && a.Tenant == r.Tenant && a.Userid == r.Id && ig.Any(r => r == a.UserGroupId)));
2019-08-14 12:12:48 +00:00
}
2022-02-15 11:52:43 +00:00
}
2019-08-14 12:12:48 +00:00
2022-02-15 11:52:43 +00:00
if (excludeGroups != null && excludeGroups.Count > 0)
{
foreach (var eg in excludeGroups)
{
2022-07-28 12:29:03 +00:00
q = q.Where(r => !userDbContext.UserGroups.Any(a => !a.Removed && a.Tenant == r.Tenant && a.Userid == r.Id && a.UserGroupId == eg));
}
2022-02-15 11:52:43 +00:00
}
2022-10-18 11:22:02 +00:00
if (!isDocSpaceAdmin && employeeStatus == null)
2022-02-15 11:52:43 +00:00
{
q = q.Where(r => r.Status != EmployeeStatus.Terminated);
}
2022-02-15 11:52:43 +00:00
if (employeeStatus != null)
{
switch (employeeStatus)
{
2022-02-15 11:52:43 +00:00
case EmployeeStatus.LeaveOfAbsence:
case EmployeeStatus.Terminated:
2022-10-18 11:22:02 +00:00
if (isDocSpaceAdmin)
2022-02-15 11:52:43 +00:00
{
q = q.Where(u => u.Status == EmployeeStatus.Terminated);
}
else
{
q = q.Where(u => false);
}
break;
case EmployeeStatus.All:
2022-10-18 11:22:02 +00:00
if (!isDocSpaceAdmin)
2022-03-17 15:01:39 +00:00
{
q = q.Where(r => r.Status != EmployeeStatus.Terminated);
}
2022-02-15 11:52:43 +00:00
break;
case EmployeeStatus.Default:
case EmployeeStatus.Active:
q = q.Where(u => u.Status == EmployeeStatus.Active);
break;
}
}
2019-11-25 09:49:12 +00:00
2022-02-15 11:52:43 +00:00
if (activationStatus != null)
{
q = q.Where(r => r.ActivationStatus == activationStatus.Value);
2019-11-25 09:49:12 +00:00
}
2020-02-25 08:02:13 +00:00
2022-02-15 11:52:43 +00:00
if (!string.IsNullOrEmpty(text))
2020-02-25 08:02:13 +00:00
{
2022-02-15 11:52:43 +00:00
q = q.Where(
u => u.FirstName.Contains(text) ||
u.LastName.Contains(text) ||
u.Title.Contains(text) ||
u.Location.Contains(text) ||
u.Email.Contains(text));
}
2022-02-15 11:52:43 +00:00
return q;
}
2022-07-28 12:29:03 +00:00
private List<Guid> CollectGroupChilds(UserDbContext userDbContext, int tenant, Guid id)
2022-02-15 11:52:43 +00:00
{
var result = new List<Guid>();
2022-07-28 12:29:03 +00:00
var childs = userDbContext.Groups
2022-02-15 11:52:43 +00:00
.Where(r => r.Tenant == tenant)
.Where(r => r.ParentId == id)
.Select(r => r.Id);
foreach (var child in childs)
{
result.Add(child);
2022-07-28 12:29:03 +00:00
result.AddRange(CollectGroupChilds(userDbContext, tenant, child));
2020-02-25 08:02:13 +00:00
}
2022-02-15 11:52:43 +00:00
result.Add(id);
return result.Distinct().ToList();
}
public UserInfo GetUser(int tenant, Guid id, Expression<Func<User, UserInfo>> exp)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
var q = GetUserQuery(userDbContext, tenant).Where(r => r.Id == id);
2022-02-15 11:52:43 +00:00
if (exp != null)
{
2022-02-15 11:52:43 +00:00
return q.Select(exp).FirstOrDefault();
}
else
{
return q.ProjectTo<UserInfo>(_mapper.ConfigurationProvider).FirstOrDefault();
}
}
2022-06-01 14:07:08 +00:00
public IEnumerable<string> GetDavUserEmails(int tenant)
{
2022-07-28 12:29:03 +00:00
using var userDbContext = _dbContextFactory.CreateDbContext();
return (from usersDav in userDbContext.UsersDav
join users in userDbContext.Users on new { tenant = usersDav.TenantId, userId = usersDav.UserId } equals new { tenant = users.Tenant, userId = users.Id }
2022-06-01 14:07:08 +00:00
where usersDav.TenantId == tenant
select users.Email)
.Distinct()
.ToList();
}
2022-02-15 11:52:43 +00:00
protected string GetPasswordHash(Guid userId, string password)
{
2022-07-28 12:29:03 +00:00
return Hasher.Base64Hash(password + userId + Encoding.UTF8.GetString(_machinePseudoKeys.GetMachineConstant()), HashAlg.SHA512);
2022-02-15 11:52:43 +00:00
}
}
public class DbUserSecurity
{
public User User { get; set; }
public UserSecurity UserSecurity { get; set; }
}