| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using System.Transactions;
- using Abp;
- using Abp.Dependency;
- using Abp.Domain.Repositories;
- using Abp.Domain.Uow;
- using Abp.Linq;
- using IwbZero.Authorization.Permissions;
- using IwbZero.Authorization.Roles;
- using Microsoft.AspNet.Identity;
- namespace IwbZero.Authorization.Users
- {
- public abstract class IwbUserStore<TRole, TUser> : IUserPasswordStore<TUser, long>,
- IUserEmailStore<TUser, long>,
- IUserLoginStore<TUser, long>,
- IUserRoleStore<TUser, long>,
- IQueryableUserStore<TUser, long>,
- IUserLockoutStore<TUser, long>,
- IIwbUserPermissionStore<TUser>,
- IUserPhoneNumberStore<TUser, long>,
- //IUserClaimStore<SysUser, long>,
- IUserSecurityStampStore<TUser, long>,
- IUserTwoFactorStore<TUser, long>,
- ITransientDependency
- where TRole : IwbSysRole<TUser>, new()
- where TUser : IwbSysUser<TUser>, new()
- {
- public IAsyncQueryableExecuter AsyncQueryableExecuter { get; set; }
- private readonly IRepository<TUser, long> _userRepository;
- private readonly IRepository<TRole, int> _roleRepository;
- private readonly IRepository<SysUserRole, long> _userRoleRepository;
- private readonly IRepository<UserLogin, long> _userLoginRepository;
- private readonly IRepository<SysPermission, long> _userPermissionSettingRepository;
- private readonly IUnitOfWorkManager _unitOfWorkManager;
- /// <summary>
- /// Constructor.
- /// </summary>
- public IwbUserStore(
- IRepository<TUser, long> userRepository,
- IRepository<SysUserRole, long> userRoleRepository,
- IRepository<TRole, int> roleRepository,
- IRepository<UserLogin, long> userLoginRepository,
- IRepository<SysPermission, long> userPermissionSettingRepository,
- IUnitOfWorkManager unitOfWorkManager)
- {
- _userRepository = userRepository;
- _userRoleRepository = userRoleRepository;
- _roleRepository = roleRepository;
- _userLoginRepository = userLoginRepository;
- _unitOfWorkManager = unitOfWorkManager;
- _userPermissionSettingRepository = userPermissionSettingRepository;
- AsyncQueryableExecuter = NullAsyncQueryableExecuter.Instance;
- }
- #region IQueryableUserStore
- public virtual IQueryable<TUser> Users => _userRepository.GetAll();
- #endregion
- #region IUserStore
- public virtual async Task CreateAsync(TUser user)
- {
- await _userRepository.InsertAsync(user);
- }
- public virtual async Task UpdateAsync(TUser user)
- {
- await _userRepository.UpdateAsync(user);
- }
- public virtual async Task DeleteAsync(TUser user)
- {
- await _userRepository.DeleteAsync(user.Id);
- }
- public virtual async Task<TUser> FindByIdAsync(long userId)
- {
- return await _userRepository.FirstOrDefaultAsync(userId);
- }
- public virtual async Task<TUser> FindByNameAsync(string userName)
- {
- return await _userRepository.FirstOrDefaultAsync(
- user => user.UserName == userName
- );
- }
- public virtual async Task<TUser> FindByEmailAsync(string email)
- {
- return await _userRepository.FirstOrDefaultAsync(
- user => user.EmailAddress == email
- );
- }
- /// <summary>
- /// Tries to find a user with user name or email address in current tenant.
- /// </summary>
- /// <param name="userNameOrEmailAddress">User name or email address</param>
- /// <returns>User or null</returns>
- public virtual async Task<TUser> FindByNameOrEmailAsync(string userNameOrEmailAddress)
- {
- return await _userRepository.FirstOrDefaultAsync(
- user => (user.UserName == userNameOrEmailAddress || user.EmailAddress == userNameOrEmailAddress)
- );
- }
- /// <summary>
- /// Tries to find a user with user name or email address in given tenant.
- /// </summary>
- /// <param name="tenantId">Tenant Id</param>
- /// <param name="userNameOrEmailAddress">User name or email address</param>
- /// <returns>User or null</returns>
- [UnitOfWork]
- public virtual async Task<TUser> FindByNameOrEmailAsync(int? tenantId, string userNameOrEmailAddress)
- {
- using (_unitOfWorkManager.Current.SetTenantId(tenantId))
- {
- return await FindByNameOrEmailAsync(userNameOrEmailAddress);
- }
- }
- #endregion
- #region IUserPasswordStore
- public virtual Task SetPasswordHashAsync(TUser user, string passwordHash)
- {
- user.Password = passwordHash;
- return Task.FromResult(0);
- }
- public virtual Task<string> GetPasswordHashAsync(TUser user)
- {
- return Task.FromResult(user.Password);
- }
- public virtual Task<bool> HasPasswordAsync(TUser user)
- {
- return Task.FromResult(!string.IsNullOrEmpty(user.Password));
- }
- #endregion
- #region IUserEmailStore
- public virtual Task SetEmailAsync(TUser user, string email)
- {
- user.EmailAddress = email;
- return Task.FromResult(0);
- }
- public virtual Task<string> GetEmailAsync(TUser user)
- {
- return Task.FromResult(user.EmailAddress);
- }
- public virtual Task<bool> GetEmailConfirmedAsync(TUser user)
- {
- return Task.FromResult(user.IsEmailConfirmed);
- }
- public virtual Task SetEmailConfirmedAsync(TUser user, bool confirmed)
- {
- user.IsEmailConfirmed = confirmed;
- return Task.FromResult(0);
- }
- #endregion
- #region IUserLoginStore
- public virtual async Task AddLoginAsync(TUser user, UserLoginInfo login)
- {
- await _userLoginRepository.InsertAsync(
- new UserLogin
- {
- //TenantId = user.TenantId,
- LoginProvider = login.LoginProvider,
- ProviderKey = login.ProviderKey,
- UserId = user.Id
- });
- }
- public virtual async Task RemoveLoginAsync(TUser user, UserLoginInfo login)
- {
- await _userLoginRepository.DeleteAsync(
- ul => ul.UserId == user.Id &&
- ul.LoginProvider == login.LoginProvider &&
- ul.ProviderKey == login.ProviderKey
- );
- }
- public virtual async Task<IList<UserLoginInfo>> GetLoginsAsync(TUser user)
- {
- return (await _userLoginRepository.GetAllListAsync(ul => ul.UserId == user.Id))
- .Select(ul => new UserLoginInfo(ul.LoginProvider, ul.ProviderKey))
- .ToList();
- }
- public virtual async Task<TUser> FindAsync(UserLoginInfo login)
- {
- var userLogin = await _userLoginRepository.FirstOrDefaultAsync(
- ul => ul.LoginProvider == login.LoginProvider && ul.ProviderKey == login.ProviderKey
- );
- if (userLogin == null)
- {
- return null;
- }
- return await _userRepository.FirstOrDefaultAsync(u => u.Id == userLogin.UserId);
- }
- [UnitOfWork]
- public virtual Task<List<TUser>> FindAllAsync(UserLoginInfo login)
- {
- var query = from userLogin in _userLoginRepository.GetAll()
- join user in _userRepository.GetAll() on userLogin.UserId equals user.Id
- where userLogin.LoginProvider == login.LoginProvider && userLogin.ProviderKey == login.ProviderKey
- select user;
- return Task.FromResult(query.ToList());
- }
- public virtual Task<TUser> FindAsync(int? tenantId, UserLoginInfo login)
- {
- using (_unitOfWorkManager.Current.SetTenantId(tenantId))
- {
- var query = from userLogin in _userLoginRepository.GetAll()
- join user in _userRepository.GetAll() on userLogin.UserId equals user.Id
- where userLogin.LoginProvider == login.LoginProvider && userLogin.ProviderKey == login.ProviderKey
- select user;
- return Task.FromResult(query.FirstOrDefault());
- }
- }
-
- #endregion
- #region IUserRoleStore
- public virtual async Task AddToRoleAsync(TUser user, string roleName)
- {
- var role = await GetRoleByNameAsync(roleName);
- await _userRoleRepository.InsertAsync(new SysUserRole(user.Id, role.Id));
- }
- public virtual async Task RemoveFromRoleAsync(TUser user, string roleName)
- {
- var role = await GetRoleByNameAsync(roleName);
- var userRole = await _userRoleRepository.FirstOrDefaultAsync(ur => ur.UserId == user.Id && ur.RoleId == role.Id);
- if (userRole == null)
- {
- return;
- }
- await _userRoleRepository.DeleteAsync(userRole);
- }
- [UnitOfWork]
- public virtual async Task<IList<string>> GetRolesAsync(TUser user)
- {
- var query = from userRole in _userRoleRepository.GetAll()
- join role in _roleRepository.GetAll() on userRole.RoleId equals role.Id
- where userRole.UserId == user.Id
- select role.Name;
- return await AsyncQueryableExecuter.ToListAsync(query);
- }
- public virtual async Task<bool> IsInRoleAsync(TUser user, string roleName)
- {
- var role = await GetRoleByNameAsync(roleName);
- return await _userRoleRepository.FirstOrDefaultAsync(ur => ur.UserId == user.Id && ur.RoleId == role.Id) != null;
- }
- #endregion
- #region IUserPermissionStore
- public virtual async Task AddPermissionAsync(TUser user, IwbPermissionGrantInfo iwbPermissionGrant)
- {
- if (await HasPermissionAsync(user.Id, iwbPermissionGrant))
- {
- return;
- }
- await _userPermissionSettingRepository.InsertAsync(
- new SysPermission
- {
- PermissionNo = Guid.NewGuid().ToString("N"),
- Master = 1,
- MasterValue = user.Id + "",
- PermissionName = iwbPermissionGrant.Name,
- IsGranted = iwbPermissionGrant.IsGranted
- });
- }
- public virtual async Task RemovePermissionAsync(TUser user, IwbPermissionGrantInfo iwbPermissionGrant)
- {
- await _userPermissionSettingRepository.DeleteAsync(
- p => p.Master == 1 &&
- p.MasterValue == user.Id + "" &&
- p.PermissionName == iwbPermissionGrant.Name &&
- p.IsGranted == iwbPermissionGrant.IsGranted
- );
- }
- public virtual async Task<IList<IwbPermissionGrantInfo>> GetPermissionsAsync(long userId)
- {
- return (await _userPermissionSettingRepository.GetAllListAsync(p => p.Master == 1 && p.MasterValue == userId + ""))
- .Select(p => new IwbPermissionGrantInfo(p.PermissionName, p.IsGranted))
- .ToList();
- }
- public virtual async Task<bool> HasPermissionAsync(long userId, IwbPermissionGrantInfo iwbPermissionGrant)
- {
- return await _userPermissionSettingRepository.FirstOrDefaultAsync(
- p => p.Master == 1 &&
- p.MasterValue == userId + "" &&
- p.PermissionName == iwbPermissionGrant.Name &&
- p.IsGranted == iwbPermissionGrant.IsGranted
- ) != null;
- }
- public virtual async Task RemoveAllPermissionSettingsAsync(TUser user)
- {
- await _userPermissionSettingRepository.DeleteAsync(p => p.Master == 1 && p.MasterValue == user.Id + "");
- }
- #endregion
- #region IUserLockoutStore
- public Task<DateTimeOffset> GetLockoutEndDateAsync(TUser user)
- {
- return Task.FromResult(
- user.LockoutEndDateUtc.HasValue
- ? new DateTimeOffset(DateTime.SpecifyKind(user.LockoutEndDateUtc.Value, DateTimeKind.Utc))
- : new DateTimeOffset()
- );
- }
- public Task SetLockoutEndDateAsync(TUser user, DateTimeOffset lockoutEnd)
- {
- user.LockoutEndDateUtc = lockoutEnd == DateTimeOffset.MinValue ? new DateTime?() : lockoutEnd.UtcDateTime;
- return Task.FromResult(0);
- }
- public Task<int> IncrementAccessFailedCountAsync(TUser user)
- {
- return Task.FromResult(++user.AccessFailedCount);
- }
- public Task ResetAccessFailedCountAsync(TUser user)
- {
- user.AccessFailedCount = 0;
- return Task.FromResult(0);
- }
- public Task<int> GetAccessFailedCountAsync(TUser user)
- {
- return Task.FromResult(user.AccessFailedCount);
- }
- public Task<bool> GetLockoutEnabledAsync(TUser user)
- {
- return Task.FromResult(user.IsLockoutEnabled);
- }
- public Task SetLockoutEnabledAsync(TUser user, bool enabled)
- {
- user.IsLockoutEnabled = enabled;
- return Task.FromResult(0);
- }
- #endregion
- #region IUserPhoneNumberStore
- public Task SetPhoneNumberAsync(TUser user, string phoneNumber)
- {
- user.PhoneNumber = phoneNumber;
- return Task.FromResult(0);
- }
- public Task<string> GetPhoneNumberAsync(TUser user)
- {
- return Task.FromResult(user.PhoneNumber);
- }
- public Task<bool> GetPhoneNumberConfirmedAsync(TUser user)
- {
- return Task.FromResult(user.IsPhoneNumberConfirmed);
- }
- public Task SetPhoneNumberConfirmedAsync(TUser user, bool confirmed)
- {
- user.IsPhoneNumberConfirmed = confirmed;
- return Task.FromResult(0);
- }
- #endregion
- #region Helpers
- private async Task<TRole> GetRoleByNameAsync(string roleName)
- {
- var role = await _roleRepository.FirstOrDefaultAsync(r => r.Name == roleName);
- if (role == null)
- {
- throw new AbpException("Could not find a role with name: " + roleName);
- }
- return role;
- }
- #endregion
- #region IUserSecurityStampStore
- public Task SetSecurityStampAsync(TUser user, string stamp)
- {
- user.SecurityStamp = stamp;
- return Task.FromResult(0);
- }
- public Task<string> GetSecurityStampAsync(TUser user)
- {
- return Task.FromResult(user.SecurityStamp);
- }
- #endregion
- public Task SetTwoFactorEnabledAsync(TUser user, bool enabled)
- {
- user.IsTwoFactorEnabled = enabled;
- return Task.FromResult(0);
- }
- public Task<bool> GetTwoFactorEnabledAsync(TUser user)
- {
- return Task.FromResult(user.IsTwoFactorEnabled);
- }
- public async Task<string> GetUserNameFromDatabaseAsync(long userId)
- {
- //note: This workaround will not be needed after fixing https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1828
- var outerUow = _unitOfWorkManager.Current;
- using (var uow = _unitOfWorkManager.Begin(new UnitOfWorkOptions
- {
- Scope = TransactionScopeOption.RequiresNew,
- IsTransactional = false,
- IsolationLevel = IsolationLevel.ReadUncommitted
- }))
- {
- if (outerUow != null)
- {
- _unitOfWorkManager.Current.SetTenantId(outerUow.GetTenantId());
- }
- var user = await _userRepository.GetAsync(userId);
- await uow.CompleteAsync();
- return user.UserName;
- }
- }
- public async Task<TUser> GetUserFromDatabaseAsync(long userId)
- {
- //note: This workaround will not be needed after fixing https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1828
- var outerUow = _unitOfWorkManager.Current;
- using (var uow = _unitOfWorkManager.Begin(new UnitOfWorkOptions
- {
- Scope = TransactionScopeOption.RequiresNew,
- IsTransactional = false,
- IsolationLevel = IsolationLevel.ReadUncommitted
- }))
- {
- if (outerUow != null)
- {
- _unitOfWorkManager.Current.SetTenantId(outerUow.GetTenantId());
- }
- var user = await _userRepository.GetAsync(userId);
- await uow.CompleteAsync();
- return user;
- }
- }
- #region IDisposable
- public virtual void Dispose()
- {
- //No need to dispose since using IOC.
- }
- #endregion
- }
- }
|