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

772 lines
29 KiB
C#
Raw Normal View History

2019-05-15 14:56:09 +00:00
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL 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 more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Collections.Generic;
2019-10-10 08:52:21 +00:00
using System.Linq;
2019-11-25 09:49:12 +00:00
using System.Linq.Expressions;
using System.Text;
2019-12-11 14:30:28 +00:00
2020-10-18 16:03:14 +00:00
using ASC.Common;
2019-11-25 09:49:12 +00:00
using ASC.Core.Common.EF;
2019-05-15 14:56:09 +00:00
using ASC.Core.Tenants;
using ASC.Core.Users;
2019-11-15 15:04:05 +00:00
using ASC.Security.Cryptography;
2020-02-20 08:05:10 +00:00
using Microsoft.Extensions.Options;
2019-05-15 14:56:09 +00:00
namespace ASC.Core.Data
2020-10-18 16:03:14 +00:00
{
[Scope]
2020-02-20 08:05:10 +00:00
public class ConfigureEFUserService : IConfigureNamedOptions<EFUserService>
{
2020-08-12 09:58:08 +00:00
private DbContextManager<UserDbContext> DbContextManager { get; }
2020-02-20 08:05:10 +00:00
public string DbId { get; set; }
public ConfigureEFUserService(DbContextManager<UserDbContext> dbContextManager)
{
DbContextManager = dbContextManager;
}
public void Configure(string name, EFUserService options)
{
DbId = name;
2020-10-18 19:00:38 +00:00
options.LazyUserDbContext = new Lazy<UserDbContext>(() => DbContextManager.Get(name));
2020-02-20 08:05:10 +00:00
options.UserDbContextManager = DbContextManager;
}
public void Configure(EFUserService options)
{
2020-10-18 19:00:38 +00:00
options.LazyUserDbContext = new Lazy<UserDbContext>(() => DbContextManager.Value);
2020-02-20 08:05:10 +00:00
options.UserDbContextManager = DbContextManager;
}
}
2020-10-18 16:03:14 +00:00
[Scope]
2019-11-25 09:49:12 +00:00
public class EFUserService : IUserService
2019-11-15 15:04:05 +00:00
{
2020-11-24 10:15:11 +00:00
private static Expression<Func<User, UserInfo>> FromUserToUserInfo { get; set; }
private static Func<UserInfo, User> FromUserInfoToUser { get; set; }
private static Expression<Func<DbGroup, Group>> FromDbGroupToGroup { get; set; }
private static Func<Group, DbGroup> FromGroupToDbGroup { get; set; }
private static Expression<Func<UserGroup, UserGroupRef>> FromUserGroupToUserGroupRef { get; set; }
private static Func<UserGroupRef, UserGroup> FromUserGroupRefToUserGroup { get; set; }
2019-11-15 15:04:05 +00:00
2020-10-18 19:00:38 +00:00
internal UserDbContext UserDbContext { get => LazyUserDbContext.Value; }
internal Lazy<UserDbContext> LazyUserDbContext { get; set; }
2020-02-20 08:05:10 +00:00
internal DbContextManager<UserDbContext> UserDbContextManager { get; set; }
private PasswordHasher PasswordHasher { get; }
public MachinePseudoKeys MachinePseudoKeys { get; }
2020-02-20 08:05:10 +00:00
internal string DbId { get; set; }
2020-11-24 10:15:11 +00:00
static EFUserService()
2019-11-15 15:04:05 +00:00
{
2019-11-25 13:04:58 +00:00
FromUserToUserInfo = user => new UserInfo
{
ActivationStatus = user.ActivationStatus,
BirthDate = user.Birthdate,
CreateDate = user.CreateOn,
CultureName = user.Culture,
Email = user.Email,
FirstName = user.FirstName,
ID = user.Id,
LastModified = user.LastModified,
LastName = user.LastName,
Location = user.Location,
MobilePhone = user.Phone,
MobilePhoneActivationStatus = user.PhoneActivation,
Notes = user.Notes,
Removed = user.Removed,
Sex = user.Sex,
Sid = user.Sid,
SsoNameId = user.SsoNameId,
SsoSessionId = user.SsoSessionId,
Status = user.Status,
Tenant = user.Tenant,
TerminatedDate = user.TerminatedDate,
Title = user.Title,
UserName = user.UserName,
WorkFromDate = user.WorkFromDate,
Contacts = user.Contacts
};
FromUserInfoToUser = user => new User
{
ActivationStatus = user.ActivationStatus,
Birthdate = user.BirthDate,
CreateOn = user.CreateDate,
Culture = user.CultureName,
Email = user.Email,
FirstName = user.FirstName,
Id = user.ID,
LastModified = user.LastModified,
LastName = user.LastName,
Location = user.Location,
Phone = user.MobilePhone,
PhoneActivation = user.MobilePhoneActivationStatus,
Notes = user.Notes,
Removed = user.Removed,
Sex = user.Sex,
Sid = user.Sid,
SsoNameId = user.SsoNameId,
SsoSessionId = user.SsoSessionId,
Status = user.Status,
Tenant = user.Tenant,
TerminatedDate = user.TerminatedDate,
Title = user.Title,
UserName = user.UserName,
WorkFromDate = user.WorkFromDate,
Contacts = user.Contacts
};
FromDbGroupToGroup = group => new Group
{
Id = group.Id,
Name = group.Name,
CategoryId = group.CategoryId ?? Guid.Empty,
ParentId = group.ParentId ?? Guid.Empty,
2019-11-25 13:04:58 +00:00
Sid = group.Sid,
Removed = group.Removed,
LastModified = group.LastModified,
Tenant = group.Tenant
};
FromGroupToDbGroup = group => new DbGroup
{
Id = group.Id,
Name = group.Name,
CategoryId = group.CategoryId,
ParentId = group.ParentId,
Sid = group.Sid,
Removed = group.Removed,
LastModified = group.LastModified,
Tenant = group.Tenant
};
FromUserGroupToUserGroupRef = userGroup => new UserGroupRef
{
GroupId = userGroup.GroupId,
UserId = userGroup.UserId,
Tenant = userGroup.Tenant,
RefType = userGroup.RefType,
LastModified = userGroup.LastModified,
Removed = userGroup.Removed
};
FromUserGroupRefToUserGroup = userGroup => new UserGroup
{
GroupId = userGroup.GroupId,
UserId = userGroup.UserId,
Tenant = userGroup.Tenant,
RefType = userGroup.RefType,
LastModified = userGroup.LastModified,
Removed = userGroup.Removed
};
2019-12-17 08:27:38 +00:00
}
2019-11-25 11:49:21 +00:00
2020-11-24 10:15:11 +00:00
public EFUserService()
{
}
public EFUserService(DbContextManager<UserDbContext> userDbContextManager, PasswordHasher passwordHasher, MachinePseudoKeys machinePseudoKeys)
2020-02-20 14:57:48 +00:00
{
UserDbContextManager = userDbContextManager;
PasswordHasher = passwordHasher;
MachinePseudoKeys = machinePseudoKeys;
2020-10-18 19:00:38 +00:00
LazyUserDbContext = new Lazy<UserDbContext>(() => UserDbContextManager.Value);
2020-02-20 14:57:48 +00:00
}
2019-11-15 15:04:05 +00:00
public Group GetGroup(int tenant, Guid id)
{
2019-11-25 09:49:12 +00:00
return GetGroupQuery(UserDbContext, tenant, default)
.Where(r => r.Id == id)
.Select(FromDbGroupToGroup)
.FirstOrDefault();
2019-11-15 15:04:05 +00:00
}
public IDictionary<Guid, Group> GetGroups(int tenant, DateTime from)
{
2019-11-25 09:49:12 +00:00
return GetGroupQuery(UserDbContext, tenant, from)
.Select(FromDbGroupToGroup)
.ToDictionary(r => r.Id, r => r);
2019-11-15 15:04:05 +00:00
}
public UserInfo GetUser(int tenant, Guid id)
{
2019-11-25 09:49:12 +00:00
return GetUserQuery(UserDbContext, tenant, default)
.Where(r => r.Id == id)
.Select(FromUserToUserInfo)
.FirstOrDefault();
2019-11-15 15:04:05 +00:00
}
public UserInfo GetUserByPasswordHash(int tenant, string login, string passwordHash)
2019-11-15 15:04:05 +00:00
{
2019-11-25 09:49:12 +00:00
if (string.IsNullOrEmpty(login)) throw new ArgumentNullException("login");
if (Guid.TryParse(login, out var userId))
2019-11-25 09:49:12 +00:00
{
RegeneratePassword(tenant, userId);
var pwdHash = GetPasswordHash(userId, passwordHash);
var oldHash = Hasher.Base64Hash(passwordHash, HashAlg.SHA256);
var q = UserDbContext.Users
.Where(r => !r.Removed)
.Where(r => r.Id == userId)
.Join(UserDbContext.UserSecurity, r => r.Id, r => r.UserId, (user, security) => new DbUserSecurity
{
User = user,
UserSecurity = security
})
.Where(r => r.UserSecurity.PwdHash == pwdHash || r.UserSecurity.PwdHash == oldHash) //todo: remove old scheme
;
if (tenant != Tenant.DEFAULT_TENANT)
{
q = q.Where(r => r.User.Tenant == tenant);
}
2020-09-30 11:20:54 +00:00
return q.Select(r => r.User).Select(FromUserToUserInfo).FirstOrDefault();
2019-11-25 09:49:12 +00:00
}
else
2019-11-25 09:49:12 +00:00
{
var q = UserDbContext.Users
.Where(r => !r.Removed)
.Where(r => r.Email == login)
;
if (tenant != Tenant.DEFAULT_TENANT)
{
q = q.Where(r => r.Tenant == tenant);
}
var user = q.Select(FromUserToUserInfo).FirstOrDefault();
if (user != null)
{
RegeneratePassword(tenant, user.ID);
2019-11-25 09:49:12 +00:00
var pwdHash = GetPasswordHash(user.ID, passwordHash);
var oldHash = Hasher.Base64Hash(passwordHash, HashAlg.SHA256);
var count = UserDbContext.UserSecurity
.Where(r => r.UserId == user.ID)
.Where(r => r.PwdHash == pwdHash || r.PwdHash == oldHash)
.Count();//todo: remove old scheme
if (count > 0) return user;
}
return null;
2019-11-25 09:49:12 +00:00
}
}
2019-11-25 09:49:12 +00:00
//todo: remove
private void RegeneratePassword(int tenant, Guid userId)
{
var h2 = UserDbContext.UserSecurity
.Where(r => r.Tenant == tenant)
.Where(r => r.UserId == userId)
.Select(r => r.PwdHashSha512)
.FirstOrDefault();
if (string.IsNullOrEmpty(h2)) return;
var password = Crypto.GetV(h2, 1, false);
var passwordHash = PasswordHasher.GetClientPassword(password);
SetUserPasswordHash(tenant, userId, passwordHash);
2019-11-15 15:04:05 +00:00
}
public IDictionary<string, UserGroupRef> GetUserGroupRefs(int tenant, DateTime from)
{
2019-12-02 09:12:16 +00:00
IQueryable<UserGroup> q = UserDbContext.UserGroups;
2019-11-25 09:49:12 +00:00
if (tenant != Tenant.DEFAULT_TENANT)
{
q = q.Where(r => r.Tenant == tenant);
}
if (from != default)
{
2020-01-21 10:52:04 +00:00
q = q.Where(r => r.LastModified >= from);
2019-11-25 09:49:12 +00:00
}
return q.Select(FromUserGroupToUserGroupRef).ToDictionary(r => r.CreateKey(), r => r);
2019-11-15 15:04:05 +00:00
}
public DateTime GetUserPasswordStamp(int tenant, Guid id)
2019-11-15 15:04:05 +00:00
{
var stamp = UserDbContext.UserSecurity
2019-11-25 09:49:12 +00:00
.Where(r => r.Tenant == tenant)
.Where(r => r.UserId == id)
.Select(r => r.LastModified)
2019-11-25 09:49:12 +00:00
.FirstOrDefault();
return stamp ?? DateTime.MinValue;
2019-11-15 15:04:05 +00:00
}
public byte[] GetUserPhoto(int tenant, Guid id)
{
2019-11-25 09:49:12 +00:00
var photo = UserDbContext.Photos
.Where(r => r.Tenant == tenant)
.Where(r => r.UserId == id)
.Select(r => r.Photo)
.FirstOrDefault();
return photo ?? new byte[0];
2019-11-15 15:04:05 +00:00
}
public IDictionary<Guid, UserInfo> GetUsers(int tenant, DateTime from)
{
2019-11-25 09:49:12 +00:00
return GetUserQuery(UserDbContext, tenant, from)
.Select(FromUserToUserInfo)
.ToDictionary(r => r.ID, r => r);
}
public IQueryable<UserInfo> GetUsers(int tenant, bool isAdmin, 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)
{
2020-02-20 08:05:10 +00:00
var userDbContext = UserDbContextManager.GetNew(DbId);
2019-11-26 09:31:53 +00:00
var totalQuery = userDbContext.Users.Where(r => r.Tenant == tenant);
2019-11-25 09:49:12 +00:00
totalQuery = GetUserQueryForFilter(totalQuery, isAdmin, employeeStatus, includeGroups, excludeGroups, activationStatus, text);
total = totalQuery.Count();
2019-11-26 09:31:53 +00:00
var q = GetUserQuery(userDbContext, tenant, default);
2019-11-25 09:49:12 +00:00
q = GetUserQueryForFilter(q, isAdmin, employeeStatus, includeGroups, excludeGroups, activationStatus, text);
if (!string.IsNullOrEmpty(sortBy))
{
q = q.OrderBy(sortBy, sortOrderAsc);
}
if (offset != 0)
{
q = q.Skip((int)offset);
}
if (limit != 0)
{
q = q.Take((int)limit);
}
2019-11-26 09:31:53 +00:00
count = q.Count();
2019-11-25 09:49:12 +00:00
return q.Select(FromUserToUserInfo);
2019-11-15 15:04:05 +00:00
}
2019-11-25 09:49:12 +00:00
public IQueryable<UserInfo> GetUsers(int tenant, out int total)
2019-11-15 15:04:05 +00:00
{
2020-02-20 08:05:10 +00:00
var userDbContext = UserDbContextManager.GetNew(DbId);
2019-11-26 09:31:53 +00:00
total = userDbContext.Users.Where(r => r.Tenant == tenant).Count();
return userDbContext.Users.Where(r => r.Tenant == tenant).Select(FromUserToUserInfo);
2019-11-15 15:04:05 +00:00
}
2019-11-25 09:49:12 +00:00
2019-11-15 15:04:05 +00:00
public void RemoveGroup(int tenant, Guid id)
{
2019-11-25 09:49:12 +00:00
RemoveGroup(tenant, id, false);
}
public void RemoveGroup(int tenant, Guid id, bool immediate)
{
var ids = CollectGroupChilds(tenant, id);
2020-02-06 15:35:24 +00:00
var stringIds = ids.Select(r => r.ToString()).ToList();
2019-11-25 09:49:12 +00:00
2019-11-29 13:47:05 +00:00
using var tr = UserDbContext.Database.BeginTransaction();
2019-11-25 09:49:12 +00:00
UserDbContext.Acl.RemoveRange(UserDbContext.Acl.Where(r => r.Tenant == tenant && ids.Any(i => i == r.Subject)));
2020-02-06 15:35:24 +00:00
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
var userGroups = UserDbContext.UserGroups.Where(r => r.Tenant == tenant && ids.Any(i => i == r.GroupId));
var groups = UserDbContext.Groups.Where(r => r.Tenant == tenant && ids.Any(i => i == r.Id));
if (immediate)
{
UserDbContext.UserGroups.RemoveRange(userGroups);
UserDbContext.Groups.RemoveRange(groups);
}
else
{
foreach (var ug in userGroups)
{
ug.Removed = true;
ug.LastModified = DateTime.UtcNow;
}
foreach (var g in groups)
{
g.Removed = true;
g.LastModified = DateTime.UtcNow;
}
}
UserDbContext.SaveChanges();
2019-11-29 13:47:05 +00:00
tr.Commit();
2019-11-15 15:04:05 +00:00
}
public void RemoveUser(int tenant, Guid id)
{
2019-11-25 09:49:12 +00:00
RemoveUser(tenant, id, false);
}
public void RemoveUser(int tenant, Guid id, bool immediate)
{
2019-11-29 13:47:05 +00:00
using var tr = UserDbContext.Database.BeginTransaction();
2019-11-25 09:49:12 +00:00
UserDbContext.Acl.RemoveRange(UserDbContext.Acl.Where(r => r.Tenant == tenant && r.Subject == id));
2019-12-02 12:04:22 +00:00
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()));
2019-11-25 09:49:12 +00:00
UserDbContext.Photos.RemoveRange(UserDbContext.Photos.Where(r => r.Tenant == tenant && r.UserId == id));
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)
{
UserDbContext.UserGroups.RemoveRange(userGroups);
UserDbContext.Users.RemoveRange(users);
UserDbContext.UserSecurity.RemoveRange(userSecurity);
}
else
{
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;
}
}
UserDbContext.SaveChanges();
2019-11-29 13:47:05 +00:00
tr.Commit();
2019-11-15 15:04:05 +00:00
}
public void RemoveUserGroupRef(int tenant, Guid userId, Guid groupId, UserGroupRefType refType)
{
2019-11-25 09:49:12 +00:00
RemoveUserGroupRef(tenant, userId, groupId, refType, false);
}
public void RemoveUserGroupRef(int tenant, Guid userId, Guid groupId, UserGroupRefType refType, bool immediate)
{
2019-11-29 13:47:05 +00:00
using var tr = UserDbContext.Database.BeginTransaction();
2019-11-25 09:49:12 +00:00
var userGroups = UserDbContext.UserGroups.Where(r => r.Tenant == tenant && r.UserId == userId && r.GroupId == groupId && r.RefType == refType);
if (immediate)
{
UserDbContext.UserGroups.RemoveRange(userGroups);
}
else
{
foreach (var u in userGroups)
{
u.LastModified = DateTime.UtcNow;
u.Removed = true;
}
}
var user = UserDbContext.Users.First(r => r.Tenant == tenant && r.Id == userId);
user.LastModified = DateTime.UtcNow;
UserDbContext.SaveChanges();
2019-11-29 13:47:05 +00:00
tr.Commit();
2019-11-15 15:04:05 +00:00
}
public Group SaveGroup(int tenant, Group group)
{
2019-11-25 09:49:12 +00:00
if (group == null) throw new ArgumentNullException("user");
if (group.Id == default) group.Id = Guid.NewGuid();
group.LastModified = DateTime.UtcNow;
group.Tenant = tenant;
2019-11-25 13:04:58 +00:00
var dbGroup = FromGroupToDbGroup(group);
2019-12-17 13:01:59 +00:00
UserDbContext.AddOrUpdate(r => r.Groups, dbGroup);
2019-11-25 11:49:21 +00:00
UserDbContext.SaveChanges();
2019-11-25 09:49:12 +00:00
2019-11-25 13:04:58 +00:00
return group;
2019-11-15 15:04:05 +00:00
}
public UserInfo SaveUser(int tenant, UserInfo user)
{
2019-11-25 09:49:12 +00:00
if (user == null) throw new ArgumentNullException("user");
if (string.IsNullOrEmpty(user.UserName)) throw new ArgumentOutOfRangeException("Empty username.");
if (user.ID == default) user.ID = Guid.NewGuid();
if (user.CreateDate == default) user.CreateDate = DateTime.UtcNow;
user.LastModified = DateTime.UtcNow;
user.Tenant = tenant;
user.UserName = user.UserName.Trim();
user.Email = user.Email.Trim();
2019-12-17 13:01:59 +00:00
using var tx = UserDbContext.Database.BeginTransaction();
2019-11-25 11:49:21 +00:00
var count = UserDbContext.Users.Where(r => r.UserName == user.UserName && r.Id != user.ID && !r.Removed).Count();
2019-11-25 09:49:12 +00:00
if (count != 0)
{
throw new ArgumentOutOfRangeException("Duplicate username.");
}
2019-12-17 13:01:59 +00:00
count = UserDbContext.Users.Where(r => r.Email == user.Email && r.Id != user.ID && !r.Removed).Count();
if (count != 0)
{
throw new ArgumentOutOfRangeException("Duplicate email.");
}
UserDbContext.AddOrUpdate(r => r.Users, FromUserInfoToUser(user));
2019-11-25 11:49:21 +00:00
UserDbContext.SaveChanges();
2019-12-17 13:01:59 +00:00
tx.Commit();
2019-11-25 09:49:12 +00:00
return user;
2019-11-15 15:04:05 +00:00
}
public UserGroupRef SaveUserGroupRef(int tenant, UserGroupRef r)
{
2019-11-25 09:49:12 +00:00
if (r == null) throw new ArgumentNullException("userGroupRef");
r.LastModified = DateTime.UtcNow;
r.Tenant = tenant;
2019-11-29 13:47:05 +00:00
using var tr = UserDbContext.Database.BeginTransaction();
2019-12-17 13:01:59 +00:00
UserDbContext.AddOrUpdate(r => r.UserGroups, FromUserGroupRefToUserGroup(r));
2019-11-25 09:49:12 +00:00
2019-12-17 13:01:59 +00:00
var user = UserDbContext.Users.FirstOrDefault(a => a.Tenant == tenant && a.Id == r.UserId);
if (user != null)
{
user.LastModified = r.LastModified;
}
2019-11-25 09:49:12 +00:00
2019-12-17 13:01:59 +00:00
UserDbContext.SaveChanges();
2019-11-29 13:47:05 +00:00
tr.Commit();
2019-11-25 09:49:12 +00:00
return r;
2019-11-15 15:04:05 +00:00
}
public void SetUserPasswordHash(int tenant, Guid id, string passwordHash)
2019-11-15 15:04:05 +00:00
{
var h1 = GetPasswordHash(id, passwordHash);
2019-11-25 09:49:12 +00:00
2019-12-17 13:01:59 +00:00
var us = new UserSecurity
{
Tenant = tenant,
2019-12-17 13:01:59 +00:00
UserId = id,
PwdHash = h1,
2020-09-30 12:54:36 +00:00
PwdHashSha512 = null,//todo: remove
LastModified = DateTime.UtcNow
2019-12-17 13:01:59 +00:00
};
UserDbContext.AddOrUpdate(r => r.UserSecurity, us);
2019-11-25 11:49:21 +00:00
UserDbContext.SaveChanges();
2019-11-15 15:04:05 +00:00
}
public void SetUserPhoto(int tenant, Guid id, byte[] photo)
{
2019-12-02 12:04:22 +00:00
using var tr = UserDbContext.Database.BeginTransaction();
2019-11-25 11:49:21 +00:00
var userPhoto = UserDbContext.Photos.FirstOrDefault(r => r.UserId == id && r.Tenant == tenant);
2019-11-25 09:49:12 +00:00
if (photo != null && photo.Length != 0)
{
if (userPhoto == null)
{
userPhoto = new UserPhoto
{
Tenant = tenant,
UserId = id,
Photo = photo
};
}
else
{
userPhoto.Photo = photo;
}
2019-12-17 13:01:59 +00:00
UserDbContext.AddOrUpdate(r => r.Photos, userPhoto);
2019-11-25 09:49:12 +00:00
}
else if (userPhoto != null)
{
2019-11-25 11:49:21 +00:00
UserDbContext.Photos.Remove(userPhoto);
2019-11-25 09:49:12 +00:00
}
2019-11-25 11:49:21 +00:00
UserDbContext.SaveChanges();
2019-12-02 12:04:22 +00:00
tr.Commit();
2019-11-15 15:04:05 +00:00
}
2019-11-25 09:49:12 +00:00
private IQueryable<User> GetUserQuery(UserDbContext UserDbContext, int tenant, DateTime from)
{
var q = UserDbContext.Users.Where(r => true);
2019-11-25 09:49:12 +00:00
if (tenant != Tenant.DEFAULT_TENANT)
{
q = q.Where(r => r.Tenant == tenant);
}
2019-11-25 09:49:12 +00:00
if (from != default)
{
2019-11-25 09:49:12 +00:00
q = q.Where(r => r.LastModified >= from);
}
2019-11-25 09:49:12 +00:00
return q;
}
private IQueryable<DbGroup> GetGroupQuery(UserDbContext UserDbContext, int tenant, DateTime from)
{
var q = UserDbContext.Groups.Where(r => true);
if (tenant != Tenant.DEFAULT_TENANT)
{
2019-11-25 09:49:12 +00:00
q = q.Where(r => r.Tenant == tenant);
}
2019-11-25 09:49:12 +00:00
if (from != default)
{
2019-11-25 09:49:12 +00:00
q = q.Where(r => r.LastModified >= from);
}
2019-08-30 12:40:57 +00:00
2019-11-25 09:49:12 +00:00
return q;
}
2019-11-25 09:49:12 +00:00
private IQueryable<User> GetUserQueryForFilter(
IQueryable<User> q,
bool isAdmin,
EmployeeStatus? employeeStatus,
2019-08-08 14:42:29 +00:00
List<List<Guid>> includeGroups,
List<Guid> excludeGroups,
EmployeeActivationStatus? activationStatus,
string text)
{
2019-11-25 09:49:12 +00:00
q = q.Where(r => !r.Removed);
if (includeGroups != null && includeGroups.Any())
{
2019-11-25 09:49:12 +00:00
Expression or = Expression.Empty();
2019-08-08 14:42:29 +00:00
2019-11-25 09:49:12 +00:00
foreach (var ig in includeGroups)
{
2019-11-25 09:49:12 +00:00
q = q.Where(r => r.Groups.Any(a => !a.Removed && a.Tenant == r.Tenant && a.UserId == r.Id && ig.Any(r => r == a.GroupId)));
}
}
if (excludeGroups != null && excludeGroups.Any())
{
2019-11-25 09:49:12 +00:00
foreach (var eg in excludeGroups)
{
2019-11-25 09:49:12 +00:00
q = q.Where(r => !r.Groups.Any(a => !a.Removed && a.Tenant == r.Tenant && a.UserId == r.Id && a.GroupId == eg));
}
}
2019-08-14 12:12:48 +00:00
if (!isAdmin && employeeStatus == null)
{
2019-11-25 09:49:12 +00:00
q = q.Where(r => r.Status != EmployeeStatus.Terminated);
2019-08-14 12:12:48 +00:00
}
if (employeeStatus != null)
{
switch (employeeStatus)
{
case EmployeeStatus.LeaveOfAbsence:
case EmployeeStatus.Terminated:
2019-08-06 09:37:00 +00:00
if (isAdmin)
{
2019-11-25 09:49:12 +00:00
q = q.Where(u => u.Status == EmployeeStatus.Terminated);
2019-08-06 09:37:00 +00:00
}
else
{
2019-11-25 09:49:12 +00:00
q = q.Where(u => false);
2019-08-06 09:37:00 +00:00
}
break;
case EmployeeStatus.All:
2019-11-25 09:49:12 +00:00
if (!isAdmin) q = q.Where(r => r.Status != EmployeeStatus.Terminated);
break;
case EmployeeStatus.Default:
case EmployeeStatus.Active:
2019-11-25 09:49:12 +00:00
q = q.Where(u => u.Status == EmployeeStatus.Active);
break;
}
}
if (activationStatus != null)
{
2019-11-25 09:49:12 +00:00
q = q.Where(r => r.ActivationStatus == activationStatus.Value);
}
if (!string.IsNullOrEmpty(text))
{
2019-12-25 15:28:19 +00:00
q = q.Where(
u => u.FirstName.Contains(text, StringComparison.InvariantCultureIgnoreCase) ||
u.LastName.Contains(text, StringComparison.InvariantCultureIgnoreCase) ||
u.Title.Contains(text, StringComparison.InvariantCultureIgnoreCase) ||
u.Location.Contains(text, StringComparison.InvariantCultureIgnoreCase) ||
u.Email.Contains(text, StringComparison.InvariantCultureIgnoreCase));
}
return q;
}
2019-11-25 09:49:12 +00:00
private List<Guid> CollectGroupChilds(int tenant, Guid id)
2019-11-25 11:49:21 +00:00
{
2019-11-25 09:49:12 +00:00
var result = new List<Guid>();
2019-11-25 09:49:12 +00:00
var childs = UserDbContext.Groups
.Where(r => r.Tenant == tenant)
.Where(r => r.ParentId == id)
.Select(r => r.Id);
2019-05-15 14:56:09 +00:00
foreach (var child in childs)
{
result.Add(child);
result.AddRange(CollectGroupChilds(tenant, child));
2019-11-25 09:49:12 +00:00
}
2019-05-15 14:56:09 +00:00
result.Add(id);
return result.Distinct().ToList();
2019-11-25 09:49:12 +00:00
}
2020-02-25 08:02:13 +00:00
public UserInfo GetUser(int tenant, Guid id, Expression<Func<User, UserInfo>> exp)
{
return GetUserQuery(UserDbContext, tenant, default)
.Where(r => r.Id == id)
.Select(exp ?? FromUserToUserInfo)
.FirstOrDefault();
}
protected string GetPasswordHash(Guid userId, string password)
{
return Hasher.Base64Hash(password + userId + Encoding.UTF8.GetString(MachinePseudoKeys.GetMachineConstant()), HashAlg.SHA512);
}
}
public class DbUserSecurity
{
public User User { get; set; }
public UserSecurity UserSecurity { get; set; }
2019-05-15 14:56:09 +00:00
}
}