From 2825bf20cc79e9a9d4f5a4a73a63ae9f9b04b4d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sat, 18 Jul 2015 11:36:45 +0300 Subject: [PATCH] Added LoginAsync for UserLoginInfo (external login). Resolved #87. --- .../Authorization/Users/AbpLoginResultType.cs | 34 +- .../Authorization/Users/AbpUserManager.cs | 1159 +++++++++-------- .../Authorization/Users/AbpUserStore.cs | 616 ++++----- src/Abp.Zero/Zero/AbpZeroCoreModule.cs | 80 +- 4 files changed, 982 insertions(+), 907 deletions(-) diff --git a/src/Abp.Zero/Authorization/Users/AbpLoginResultType.cs b/src/Abp.Zero/Authorization/Users/AbpLoginResultType.cs index 5c38d17e..1e537b03 100644 --- a/src/Abp.Zero/Authorization/Users/AbpLoginResultType.cs +++ b/src/Abp.Zero/Authorization/Users/AbpLoginResultType.cs @@ -1,15 +1,21 @@ -namespace Abp.Authorization.Users -{ - public enum AbpLoginResultType - { - Success = 1, - - InvalidUserNameOrEmailAddress, - InvalidPassword, - UserIsNotActive, - - InvalidTenancyName, - TenantIsNotActive, - UserEmailIsNotConfirmed - } +namespace Abp.Authorization.Users +{ + public enum AbpLoginResultType + { + Success = 1, + + InvalidUserNameOrEmailAddress, + + InvalidPassword, + + UserIsNotActive, + + InvalidTenancyName, + + TenantIsNotActive, + + UserEmailIsNotConfirmed, + + UnknownExternalLogin + } } \ No newline at end of file diff --git a/src/Abp.Zero/Authorization/Users/AbpUserManager.cs b/src/Abp.Zero/Authorization/Users/AbpUserManager.cs index ed1a52d3..44379672 100644 --- a/src/Abp.Zero/Authorization/Users/AbpUserManager.cs +++ b/src/Abp.Zero/Authorization/Users/AbpUserManager.cs @@ -1,557 +1,604 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Security.Claims; -using System.Threading.Tasks; -using Abp.Authorization.Roles; -using Abp.Configuration; -using Abp.Configuration.Startup; -using Abp.Dependency; -using Abp.Domain.Repositories; -using Abp.Domain.Uow; -using Abp.Extensions; -using Abp.IdentityFramework; -using Abp.Localization; -using Abp.MultiTenancy; -using Abp.Runtime.Security; -using Abp.Runtime.Session; -using Abp.Timing; -using Abp.Zero; -using Abp.Zero.Configuration; -using Microsoft.AspNet.Identity; - -namespace Abp.Authorization.Users -{ - /// - /// Extends of ASP.NET Identity Framework. - /// - public abstract class AbpUserManager : UserManager, ITransientDependency - where TTenant : AbpTenant - where TRole : AbpRole, new() - where TUser : AbpUser - { - private IUserPermissionStore UserPermissionStore - { - get - { - if (!(Store is IUserPermissionStore)) - { - throw new AbpException("Store is not IUserPermissionStore"); - } - - return Store as IUserPermissionStore; - } - } - - public ILocalizationManager LocalizationManager { get; set; } - - public IAbpSession AbpSession { get; set; } - - protected AbpRoleManager RoleManager { get; private set; } - - protected ISettingManager SettingManager { get; private set; } - - protected AbpUserStore AbpStore { get; private set; } - - private readonly IPermissionManager _permissionManager; - private readonly IUnitOfWorkManager _unitOfWorkManager; - private readonly IUserManagementConfig _userManagementConfig; - private readonly IIocResolver _iocResolver; - private readonly IRepository _tenantRepository; - private readonly IMultiTenancyConfig _multiTenancyConfig; - - //TODO: Non-generic parameters may be converted to property-injection - protected AbpUserManager( - AbpUserStore userStore, - AbpRoleManager roleManager, - IRepository tenantRepository, - IMultiTenancyConfig multiTenancyConfig, - IPermissionManager permissionManager, - IUnitOfWorkManager unitOfWorkManager, - ISettingManager settingManager, - IUserManagementConfig userManagementConfig, - IIocResolver iocResolver) - : base(userStore) - { - AbpStore = userStore; - RoleManager = roleManager; - SettingManager = settingManager; - _tenantRepository = tenantRepository; - _multiTenancyConfig = multiTenancyConfig; - _permissionManager = permissionManager; - _unitOfWorkManager = unitOfWorkManager; - _userManagementConfig = userManagementConfig; - _iocResolver = iocResolver; - LocalizationManager = NullLocalizationManager.Instance; - } - - public override async Task CreateAsync(TUser user) - { - var result = await CheckDuplicateUsernameOrEmailAddressAsync(user.Id, user.UserName, user.EmailAddress); - if (!result.Succeeded) - { - return result; - } - - if (AbpSession.TenantId.HasValue) - { - user.TenantId = AbpSession.TenantId.Value; - } - - return await base.CreateAsync(user); - } - - /// - /// Check whether a user is granted for a permission. - /// - /// User id - /// Permission name - public virtual async Task IsGrantedAsync(long userId, string permissionName) - { - return await IsGrantedAsync( - await GetUserByIdAsync(userId), - _permissionManager.GetPermission(permissionName) - ); - } - - /// - /// Check whether a user is granted for a permission. - /// - /// User - /// Permission - public virtual async Task IsGrantedAsync(TUser user, Permission permission) - { - //Check for multi-tenancy side - if (!permission.MultiTenancySides.HasFlag(AbpSession.MultiTenancySide)) - { - return false; - } - - //Check for user-specific value - if (await UserPermissionStore.HasPermissionAsync(user, new PermissionGrantInfo(permission.Name, true))) - { - return true; - } - - if (await UserPermissionStore.HasPermissionAsync(user, new PermissionGrantInfo(permission.Name, false))) - { - return false; - } - - //Check for roles - var roleNames = await GetRolesAsync(user.Id); - if (!roleNames.Any()) - { - return permission.IsGrantedByDefault; - } - - foreach (var roleName in roleNames) - { - if (await RoleManager.HasPermissionAsync(roleName, permission.Name)) - { - return true; - } - } - - return false; - } - - /// - /// Gets granted permissions for a user. - /// - /// Role - /// List of granted permissions - public virtual async Task> GetGrantedPermissionsAsync(TUser user) - { - var permissionList = new List(); - - foreach (var permission in _permissionManager.GetAllPermissions()) - { - if (await IsGrantedAsync(user, permission)) - { - permissionList.Add(permission); - } - } - - return permissionList; - } - - /// - /// Sets all granted permissions of a user at once. - /// Prohibits all other permissions. - /// - /// The user - /// Permissions - public virtual async Task SetGrantedPermissionsAsync(TUser user, IEnumerable permissions) - { - var oldPermissions = await GetGrantedPermissionsAsync(user); - var newPermissions = permissions.ToArray(); - - foreach (var permission in oldPermissions.Where(p => !newPermissions.Contains(p))) - { - await ProhibitPermissionAsync(user, permission); - } - - foreach (var permission in newPermissions.Where(p => !oldPermissions.Contains(p))) - { - await GrantPermissionAsync(user, permission); - } - } - - /// - /// Prohibits all permissions for a user. - /// - /// User - public async Task ProhibitAllPermissionsAsync(TUser user) - { - foreach (var permission in _permissionManager.GetAllPermissions()) - { - await ProhibitPermissionAsync(user, permission); - } - } - - /// - /// Resets all permission settings for a user. - /// It removes all permission settings for the user. - /// User will have permissions according to his roles. - /// This method does not prohibit all permissions. - /// For that, use . - /// - /// User - public async Task ResetAllPermissionsAsync(TUser user) - { - await UserPermissionStore.RemoveAllPermissionSettingsAsync(user); - } - - /// - /// Grants a permission for a user if not already granted. - /// - /// User - /// Permission - public virtual async Task GrantPermissionAsync(TUser user, Permission permission) - { - await UserPermissionStore.RemovePermissionAsync(user, new PermissionGrantInfo(permission.Name, false)); - - if (await IsGrantedAsync(user, permission)) - { - return; - } - - await UserPermissionStore.AddPermissionAsync(user, new PermissionGrantInfo(permission.Name, true)); - } - - /// - /// Prohibits a permission for a user if it's granted. - /// - /// User - /// Permission - public virtual async Task ProhibitPermissionAsync(TUser user, Permission permission) - { - await UserPermissionStore.RemovePermissionAsync(user, new PermissionGrantInfo(permission.Name, true)); - - if (!await IsGrantedAsync(user, permission)) - { - return; - } - - await UserPermissionStore.AddPermissionAsync(user, new PermissionGrantInfo(permission.Name, false)); - } - - public virtual async Task FindByNameOrEmailAsync(string userNameOrEmailAddress) - { - return await AbpStore.FindByNameOrEmailAsync(userNameOrEmailAddress); - } - - [UnitOfWork] - public virtual async Task LoginAsync(string userNameOrEmailAddress, string plainPassword, string tenancyName = null) - { - if (userNameOrEmailAddress.IsNullOrEmpty()) - { - throw new ArgumentNullException("userNameOrEmailAddress"); - } - - if (plainPassword.IsNullOrEmpty()) - { - throw new ArgumentNullException("plainPassword"); - } - - //Get and check tenant - TTenant tenant = null; - if (!_multiTenancyConfig.IsEnabled) - { - tenant = await GetDefaultTenantAsync(); - } - else if (!string.IsNullOrWhiteSpace(tenancyName)) - { - tenant = await _tenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenancyName); - if (tenant == null) - { - return new AbpLoginResult(AbpLoginResultType.InvalidTenancyName); - } - - if (!tenant.IsActive) - { - return new AbpLoginResult(AbpLoginResultType.TenantIsNotActive); - } - } - - using (_unitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant)) - { - TUser user; - if (await TryLoginFromExternalAuthenticationSources(userNameOrEmailAddress, plainPassword, tenant)) - { - user = await AbpStore.FindByNameOrEmailAsync(tenant == null ? (int?)null : tenant.Id, userNameOrEmailAddress); - } - else - { - user = await AbpStore.FindByNameOrEmailAsync(tenant == null ? (int?)null : tenant.Id, userNameOrEmailAddress); - if (user == null) - { - return new AbpLoginResult(AbpLoginResultType.InvalidUserNameOrEmailAddress); - } - - var verificationResult = new PasswordHasher().VerifyHashedPassword(user.Password, plainPassword); - if (verificationResult != PasswordVerificationResult.Success) - { - return new AbpLoginResult(AbpLoginResultType.InvalidPassword); - } - } - - if (!user.IsActive) - { - return new AbpLoginResult(AbpLoginResultType.UserIsNotActive); - } - - if (await IsEmailConfirmationRequiredForLoginAsync(user.TenantId) && !user.IsEmailConfirmed) - { - return new AbpLoginResult(AbpLoginResultType.UserEmailIsNotConfirmed); - } - - user.LastLoginTime = Clock.Now; - - await Store.UpdateAsync(user); - - await _unitOfWorkManager.Current.SaveChangesAsync(); - - return new AbpLoginResult(user, await CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)); - } - } - - private async Task TryLoginFromExternalAuthenticationSources(string userNameOrEmailAddress, string plainPassword, TTenant tenant) - { - if (!_userManagementConfig.ExternalAuthenticationSources.Any()) - { - return false; - } - - foreach (var sourceType in _userManagementConfig.ExternalAuthenticationSources) - { - using (var source = _iocResolver.ResolveAsDisposable>(sourceType)) - { - if (await source.Object.TryAuthenticateAsync(userNameOrEmailAddress, plainPassword, tenant)) - { - var tenantId = tenant == null ? (int?) null : tenant.Id; - - var user = await AbpStore.FindByNameOrEmailAsync(tenantId, userNameOrEmailAddress); - if (user == null) - { - user = await source.Object.CreateUserAsync(userNameOrEmailAddress, tenant); - - user.Tenant = tenant; - user.AuthenticationSource = source.Object.Name; - user.Password = new PasswordHasher().HashPassword(Guid.NewGuid().ToString("N").Left(16)); //Setting a random password since it will not be used - - user.Roles = new List(); - foreach (var defaultRole in RoleManager.Roles.Where(r => r.TenantId == tenantId && r.IsDefault).ToList()) - { - user.Roles.Add(new UserRole { RoleId = defaultRole.Id }); - } - - await Store.CreateAsync(user); - } - else - { - await source.Object.UpdateUserAsync(user, tenant); - - user.AuthenticationSource = source.Object.Name; - - await Store.UpdateAsync(user); - } - - await _unitOfWorkManager.Current.SaveChangesAsync(); - - return true; - } - } - } - - return false; - } - - /// - /// Gets a user by given id. - /// Throws exception if no user found with given id. - /// - /// User id - /// User - /// Throws exception if no user found with given id - public virtual async Task GetUserByIdAsync(long userId) - { - var user = await FindByIdAsync(userId); - if (user == null) - { - throw new AbpException("There is no user with id: " + userId); - } - - return user; - } - - public async override Task CreateIdentityAsync(TUser user, string authenticationType) - { - var identity = await base.CreateIdentityAsync(user, authenticationType); - if (user.TenantId.HasValue) - { - identity.AddClaim(new Claim(AbpClaimTypes.TenantId, user.TenantId.Value.ToString(CultureInfo.InvariantCulture))); - } - - return identity; - } - - public async override Task UpdateAsync(TUser user) - { - var result = await CheckDuplicateUsernameOrEmailAddressAsync(user.Id, user.UserName, user.EmailAddress); - if (!result.Succeeded) - { - return result; - } - - var oldUserName = (await GetUserByIdAsync(user.Id)).UserName; - if (oldUserName == AbpUser.AdminUserName && user.UserName != AbpUser.AdminUserName) - { - return AbpIdentityResult.Failed(string.Format(L("CanNotRenameAdminUser"), AbpUser.AdminUserName)); - } - - return await base.UpdateAsync(user); - } - - public async override Task DeleteAsync(TUser user) - { - if (user.UserName == AbpUser.AdminUserName) - { - return AbpIdentityResult.Failed(string.Format(L("CanNotDeleteAdminUser"), AbpUser.AdminUserName)); - } - - return await base.DeleteAsync(user); - } - - public virtual async Task ChangePasswordAsync(TUser user, string newPassword) - { - var result = await PasswordValidator.ValidateAsync(newPassword); - if (!result.Succeeded) - { - return result; - } - - await AbpStore.SetPasswordHashAsync(user, PasswordHasher.HashPassword(newPassword)); - return IdentityResult.Success; - } - - public virtual async Task CheckDuplicateUsernameOrEmailAddressAsync(long? expectedUserId, string userName, string emailAddress) - { - var user = (await FindByNameAsync(userName)); - if (user != null && user.Id != expectedUserId) - { - return AbpIdentityResult.Failed(string.Format(L("Identity.DuplicateName"), userName)); - } - - user = (await FindByEmailAsync(emailAddress)); - if (user != null && user.Id != expectedUserId) - { - return AbpIdentityResult.Failed(string.Format(L("Identity.DuplicateEmail"), emailAddress)); - } - - return IdentityResult.Success; - } - - public virtual async Task SetRoles(TUser user, string[] roleNames) - { - //Remove from removed roles - foreach (var userRole in user.Roles.ToList()) - { - var role = await RoleManager.FindByIdAsync(userRole.RoleId); - if (roleNames.All(roleName => role.Name != roleName)) - { - var result = await RemoveFromRoleAsync(user.Id, role.Name); - if (!result.Succeeded) - { - return result; - } - } - } - - //Add to added roles - foreach (var roleName in roleNames) - { - var role = await RoleManager.GetRoleByNameAsync(roleName); - if (user.Roles.All(ur => ur.RoleId != role.Id)) - { - var result = await AddToRoleAsync(user.Id, roleName); - if (!result.Succeeded) - { - return result; - } - } - } - - return IdentityResult.Success; - } - - private async Task IsEmailConfirmationRequiredForLoginAsync(int? tenantId) - { - if (tenantId.HasValue) - { - return await SettingManager.GetSettingValueForTenantAsync(AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin, tenantId.Value); - } - - return await SettingManager.GetSettingValueForApplicationAsync(AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin); - } - - private async Task GetDefaultTenantAsync() - { - var tenant = await _tenantRepository.FirstOrDefaultAsync(t => t.TenancyName == AbpTenant.DefaultTenantName); - if (tenant == null) - { - throw new AbpException("There should be a 'Default' tenant if multi-tenancy is disabled!"); - } - - return tenant; - } - - private string L(string name) - { - return LocalizationManager.GetString(AbpZeroConsts.LocalizationSourceName, name); - } - - public class AbpLoginResult - { - public AbpLoginResultType Result { get; private set; } - - public TUser User { get; private set; } - - public ClaimsIdentity Identity { get; private set; } - - public AbpLoginResult(AbpLoginResultType result) - { - Result = result; - } - - public AbpLoginResult(TUser user, ClaimsIdentity identity) - : this(AbpLoginResultType.Success) - { - User = user; - Identity = identity; - } - } - } +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Abp.Authorization.Roles; +using Abp.Configuration; +using Abp.Configuration.Startup; +using Abp.Dependency; +using Abp.Domain.Repositories; +using Abp.Domain.Uow; +using Abp.Extensions; +using Abp.IdentityFramework; +using Abp.Localization; +using Abp.MultiTenancy; +using Abp.Runtime.Security; +using Abp.Runtime.Session; +using Abp.Timing; +using Abp.Zero; +using Abp.Zero.Configuration; +using Microsoft.AspNet.Identity; + +namespace Abp.Authorization.Users +{ + /// + /// Extends of ASP.NET Identity Framework. + /// + public abstract class AbpUserManager : UserManager, ITransientDependency + where TTenant : AbpTenant + where TRole : AbpRole, new() + where TUser : AbpUser + { + private IUserPermissionStore UserPermissionStore + { + get + { + if (!(Store is IUserPermissionStore)) + { + throw new AbpException("Store is not IUserPermissionStore"); + } + + return Store as IUserPermissionStore; + } + } + + public ILocalizationManager LocalizationManager { get; set; } + + public IAbpSession AbpSession { get; set; } + + protected AbpRoleManager RoleManager { get; private set; } + + protected ISettingManager SettingManager { get; private set; } + + protected AbpUserStore AbpStore { get; private set; } + + private readonly IPermissionManager _permissionManager; + private readonly IUnitOfWorkManager _unitOfWorkManager; + private readonly IUserManagementConfig _userManagementConfig; + private readonly IIocResolver _iocResolver; + private readonly IRepository _tenantRepository; + private readonly IMultiTenancyConfig _multiTenancyConfig; + + //TODO: Non-generic parameters may be converted to property-injection + protected AbpUserManager( + AbpUserStore userStore, + AbpRoleManager roleManager, + IRepository tenantRepository, + IMultiTenancyConfig multiTenancyConfig, + IPermissionManager permissionManager, + IUnitOfWorkManager unitOfWorkManager, + ISettingManager settingManager, + IUserManagementConfig userManagementConfig, + IIocResolver iocResolver) + : base(userStore) + { + AbpStore = userStore; + RoleManager = roleManager; + SettingManager = settingManager; + _tenantRepository = tenantRepository; + _multiTenancyConfig = multiTenancyConfig; + _permissionManager = permissionManager; + _unitOfWorkManager = unitOfWorkManager; + _userManagementConfig = userManagementConfig; + _iocResolver = iocResolver; + LocalizationManager = NullLocalizationManager.Instance; + } + + public override async Task CreateAsync(TUser user) + { + var result = await CheckDuplicateUsernameOrEmailAddressAsync(user.Id, user.UserName, user.EmailAddress); + if (!result.Succeeded) + { + return result; + } + + if (AbpSession.TenantId.HasValue) + { + user.TenantId = AbpSession.TenantId.Value; + } + + return await base.CreateAsync(user); + } + + /// + /// Check whether a user is granted for a permission. + /// + /// User id + /// Permission name + public virtual async Task IsGrantedAsync(long userId, string permissionName) + { + return await IsGrantedAsync( + await GetUserByIdAsync(userId), + _permissionManager.GetPermission(permissionName) + ); + } + + /// + /// Check whether a user is granted for a permission. + /// + /// User + /// Permission + public virtual async Task IsGrantedAsync(TUser user, Permission permission) + { + //Check for multi-tenancy side + if (!permission.MultiTenancySides.HasFlag(AbpSession.MultiTenancySide)) + { + return false; + } + + //Check for user-specific value + if (await UserPermissionStore.HasPermissionAsync(user, new PermissionGrantInfo(permission.Name, true))) + { + return true; + } + + if (await UserPermissionStore.HasPermissionAsync(user, new PermissionGrantInfo(permission.Name, false))) + { + return false; + } + + //Check for roles + var roleNames = await GetRolesAsync(user.Id); + if (!roleNames.Any()) + { + return permission.IsGrantedByDefault; + } + + foreach (var roleName in roleNames) + { + if (await RoleManager.HasPermissionAsync(roleName, permission.Name)) + { + return true; + } + } + + return false; + } + + /// + /// Gets granted permissions for a user. + /// + /// Role + /// List of granted permissions + public virtual async Task> GetGrantedPermissionsAsync(TUser user) + { + var permissionList = new List(); + + foreach (var permission in _permissionManager.GetAllPermissions()) + { + if (await IsGrantedAsync(user, permission)) + { + permissionList.Add(permission); + } + } + + return permissionList; + } + + /// + /// Sets all granted permissions of a user at once. + /// Prohibits all other permissions. + /// + /// The user + /// Permissions + public virtual async Task SetGrantedPermissionsAsync(TUser user, IEnumerable permissions) + { + var oldPermissions = await GetGrantedPermissionsAsync(user); + var newPermissions = permissions.ToArray(); + + foreach (var permission in oldPermissions.Where(p => !newPermissions.Contains(p))) + { + await ProhibitPermissionAsync(user, permission); + } + + foreach (var permission in newPermissions.Where(p => !oldPermissions.Contains(p))) + { + await GrantPermissionAsync(user, permission); + } + } + + /// + /// Prohibits all permissions for a user. + /// + /// User + public async Task ProhibitAllPermissionsAsync(TUser user) + { + foreach (var permission in _permissionManager.GetAllPermissions()) + { + await ProhibitPermissionAsync(user, permission); + } + } + + /// + /// Resets all permission settings for a user. + /// It removes all permission settings for the user. + /// User will have permissions according to his roles. + /// This method does not prohibit all permissions. + /// For that, use . + /// + /// User + public async Task ResetAllPermissionsAsync(TUser user) + { + await UserPermissionStore.RemoveAllPermissionSettingsAsync(user); + } + + /// + /// Grants a permission for a user if not already granted. + /// + /// User + /// Permission + public virtual async Task GrantPermissionAsync(TUser user, Permission permission) + { + await UserPermissionStore.RemovePermissionAsync(user, new PermissionGrantInfo(permission.Name, false)); + + if (await IsGrantedAsync(user, permission)) + { + return; + } + + await UserPermissionStore.AddPermissionAsync(user, new PermissionGrantInfo(permission.Name, true)); + } + + /// + /// Prohibits a permission for a user if it's granted. + /// + /// User + /// Permission + public virtual async Task ProhibitPermissionAsync(TUser user, Permission permission) + { + await UserPermissionStore.RemovePermissionAsync(user, new PermissionGrantInfo(permission.Name, true)); + + if (!await IsGrantedAsync(user, permission)) + { + return; + } + + await UserPermissionStore.AddPermissionAsync(user, new PermissionGrantInfo(permission.Name, false)); + } + + public virtual async Task FindByNameOrEmailAsync(string userNameOrEmailAddress) + { + return await AbpStore.FindByNameOrEmailAsync(userNameOrEmailAddress); + } + + public virtual Task> FindAllAsync(UserLoginInfo login) + { + return AbpStore.FindAllAsync(login); + } + + [UnitOfWork] + public virtual async Task LoginAsync(UserLoginInfo login, string tenancyName = null) + { + if (login == null || login.LoginProvider.IsNullOrEmpty() || login.ProviderKey.IsNullOrEmpty()) + { + throw new ArgumentException("login"); + } + + //Get and check tenant + TTenant tenant = null; + if (!_multiTenancyConfig.IsEnabled) + { + tenant = await GetDefaultTenantAsync(); + } + else if (!string.IsNullOrWhiteSpace(tenancyName)) + { + tenant = await _tenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenancyName); + if (tenant == null) + { + return new AbpLoginResult(AbpLoginResultType.InvalidTenancyName); + } + + if (!tenant.IsActive) + { + return new AbpLoginResult(AbpLoginResultType.TenantIsNotActive); + } + } + + using (_unitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant)) + { + var user = await AbpStore.FindAsync(tenant == null ? (int?)null : tenant.Id, login); + if (user == null) + { + return new AbpLoginResult(AbpLoginResultType.UnknownExternalLogin); + } + + return await CreateLoginResultAsync(user); + } + } + + [UnitOfWork] + public virtual async Task LoginAsync(string userNameOrEmailAddress, string plainPassword, string tenancyName = null) + { + if (userNameOrEmailAddress.IsNullOrEmpty()) + { + throw new ArgumentNullException("userNameOrEmailAddress"); + } + + if (plainPassword.IsNullOrEmpty()) + { + throw new ArgumentNullException("plainPassword"); + } + + //Get and check tenant + TTenant tenant = null; + if (!_multiTenancyConfig.IsEnabled) + { + tenant = await GetDefaultTenantAsync(); + } + else if (!string.IsNullOrWhiteSpace(tenancyName)) + { + tenant = await _tenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenancyName); + if (tenant == null) + { + return new AbpLoginResult(AbpLoginResultType.InvalidTenancyName); + } + + if (!tenant.IsActive) + { + return new AbpLoginResult(AbpLoginResultType.TenantIsNotActive); + } + } + + using (_unitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant)) + { + var loggedInFromExternalSource = await TryLoginFromExternalAuthenticationSources(userNameOrEmailAddress, plainPassword, tenant); + + var user = await AbpStore.FindByNameOrEmailAsync(tenant == null ? (int?)null : tenant.Id, userNameOrEmailAddress); + if (user == null) + { + return new AbpLoginResult(AbpLoginResultType.InvalidUserNameOrEmailAddress); + } + + if (!loggedInFromExternalSource) + { + var verificationResult = new PasswordHasher().VerifyHashedPassword(user.Password, plainPassword); + if (verificationResult != PasswordVerificationResult.Success) + { + return new AbpLoginResult(AbpLoginResultType.InvalidPassword); + } + } + + return await CreateLoginResultAsync(user); + } + } + + private async Task CreateLoginResultAsync(TUser user) + { + if (!user.IsActive) + { + return new AbpLoginResult(AbpLoginResultType.UserIsNotActive); + } + + if (await IsEmailConfirmationRequiredForLoginAsync(user.TenantId) && !user.IsEmailConfirmed) + { + return new AbpLoginResult(AbpLoginResultType.UserEmailIsNotConfirmed); + } + + user.LastLoginTime = Clock.Now; + + await Store.UpdateAsync(user); + + await _unitOfWorkManager.Current.SaveChangesAsync(); + + return new AbpLoginResult(user, await CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)); + } + + private async Task TryLoginFromExternalAuthenticationSources(string userNameOrEmailAddress, string plainPassword, TTenant tenant) + { + if (!_userManagementConfig.ExternalAuthenticationSources.Any()) + { + return false; + } + + foreach (var sourceType in _userManagementConfig.ExternalAuthenticationSources) + { + using (var source = _iocResolver.ResolveAsDisposable>(sourceType)) + { + if (await source.Object.TryAuthenticateAsync(userNameOrEmailAddress, plainPassword, tenant)) + { + var tenantId = tenant == null ? (int?) null : tenant.Id; + + var user = await AbpStore.FindByNameOrEmailAsync(tenantId, userNameOrEmailAddress); + if (user == null) + { + user = await source.Object.CreateUserAsync(userNameOrEmailAddress, tenant); + + user.Tenant = tenant; + user.AuthenticationSource = source.Object.Name; + user.Password = new PasswordHasher().HashPassword(Guid.NewGuid().ToString("N").Left(16)); //Setting a random password since it will not be used + + user.Roles = new List(); + foreach (var defaultRole in RoleManager.Roles.Where(r => r.TenantId == tenantId && r.IsDefault).ToList()) + { + user.Roles.Add(new UserRole { RoleId = defaultRole.Id }); + } + + await Store.CreateAsync(user); + } + else + { + await source.Object.UpdateUserAsync(user, tenant); + + user.AuthenticationSource = source.Object.Name; + + await Store.UpdateAsync(user); + } + + await _unitOfWorkManager.Current.SaveChangesAsync(); + + return true; + } + } + } + + return false; + } + + /// + /// Gets a user by given id. + /// Throws exception if no user found with given id. + /// + /// User id + /// User + /// Throws exception if no user found with given id + public virtual async Task GetUserByIdAsync(long userId) + { + var user = await FindByIdAsync(userId); + if (user == null) + { + throw new AbpException("There is no user with id: " + userId); + } + + return user; + } + + public async override Task CreateIdentityAsync(TUser user, string authenticationType) + { + var identity = await base.CreateIdentityAsync(user, authenticationType); + if (user.TenantId.HasValue) + { + identity.AddClaim(new Claim(AbpClaimTypes.TenantId, user.TenantId.Value.ToString(CultureInfo.InvariantCulture))); + } + + return identity; + } + + public async override Task UpdateAsync(TUser user) + { + var result = await CheckDuplicateUsernameOrEmailAddressAsync(user.Id, user.UserName, user.EmailAddress); + if (!result.Succeeded) + { + return result; + } + + var oldUserName = (await GetUserByIdAsync(user.Id)).UserName; + if (oldUserName == AbpUser.AdminUserName && user.UserName != AbpUser.AdminUserName) + { + return AbpIdentityResult.Failed(string.Format(L("CanNotRenameAdminUser"), AbpUser.AdminUserName)); + } + + return await base.UpdateAsync(user); + } + + public async override Task DeleteAsync(TUser user) + { + if (user.UserName == AbpUser.AdminUserName) + { + return AbpIdentityResult.Failed(string.Format(L("CanNotDeleteAdminUser"), AbpUser.AdminUserName)); + } + + return await base.DeleteAsync(user); + } + + public virtual async Task ChangePasswordAsync(TUser user, string newPassword) + { + var result = await PasswordValidator.ValidateAsync(newPassword); + if (!result.Succeeded) + { + return result; + } + + await AbpStore.SetPasswordHashAsync(user, PasswordHasher.HashPassword(newPassword)); + return IdentityResult.Success; + } + + public virtual async Task CheckDuplicateUsernameOrEmailAddressAsync(long? expectedUserId, string userName, string emailAddress) + { + var user = (await FindByNameAsync(userName)); + if (user != null && user.Id != expectedUserId) + { + return AbpIdentityResult.Failed(string.Format(L("Identity.DuplicateName"), userName)); + } + + user = (await FindByEmailAsync(emailAddress)); + if (user != null && user.Id != expectedUserId) + { + return AbpIdentityResult.Failed(string.Format(L("Identity.DuplicateEmail"), emailAddress)); + } + + return IdentityResult.Success; + } + + public virtual async Task SetRoles(TUser user, string[] roleNames) + { + //Remove from removed roles + foreach (var userRole in user.Roles.ToList()) + { + var role = await RoleManager.FindByIdAsync(userRole.RoleId); + if (roleNames.All(roleName => role.Name != roleName)) + { + var result = await RemoveFromRoleAsync(user.Id, role.Name); + if (!result.Succeeded) + { + return result; + } + } + } + + //Add to added roles + foreach (var roleName in roleNames) + { + var role = await RoleManager.GetRoleByNameAsync(roleName); + if (user.Roles.All(ur => ur.RoleId != role.Id)) + { + var result = await AddToRoleAsync(user.Id, roleName); + if (!result.Succeeded) + { + return result; + } + } + } + + return IdentityResult.Success; + } + + private async Task IsEmailConfirmationRequiredForLoginAsync(int? tenantId) + { + if (tenantId.HasValue) + { + return await SettingManager.GetSettingValueForTenantAsync(AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin, tenantId.Value); + } + + return await SettingManager.GetSettingValueForApplicationAsync(AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin); + } + + private async Task GetDefaultTenantAsync() + { + var tenant = await _tenantRepository.FirstOrDefaultAsync(t => t.TenancyName == AbpTenant.DefaultTenantName); + if (tenant == null) + { + throw new AbpException("There should be a 'Default' tenant if multi-tenancy is disabled!"); + } + + return tenant; + } + + private string L(string name) + { + return LocalizationManager.GetString(AbpZeroConsts.LocalizationSourceName, name); + } + + public class AbpLoginResult + { + public AbpLoginResultType Result { get; private set; } + + public TUser User { get; private set; } + + public ClaimsIdentity Identity { get; private set; } + + public AbpLoginResult(AbpLoginResultType result) + { + Result = result; + } + + public AbpLoginResult(TUser user, ClaimsIdentity identity) + : this(AbpLoginResultType.Success) + { + User = user; + Identity = identity; + } + } + } } \ No newline at end of file diff --git a/src/Abp.Zero/Authorization/Users/AbpUserStore.cs b/src/Abp.Zero/Authorization/Users/AbpUserStore.cs index ce68ad75..6cfe24f7 100644 --- a/src/Abp.Zero/Authorization/Users/AbpUserStore.cs +++ b/src/Abp.Zero/Authorization/Users/AbpUserStore.cs @@ -1,297 +1,319 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Abp.Authorization.Roles; -using Abp.Dependency; -using Abp.Domain.Repositories; -using Abp.Domain.Uow; -using Abp.MultiTenancy; -using Abp.Runtime.Session; -using Microsoft.AspNet.Identity; - -namespace Abp.Authorization.Users -{ - /// - /// Implements 'User Store' of ASP.NET Identity Framework. - /// - public abstract class AbpUserStore : - IUserPasswordStore, - IUserEmailStore, - IUserLoginStore, - IUserRoleStore, - IQueryableUserStore, - IUserPermissionStore, - ITransientDependency - where TTenant : AbpTenant - where TRole : AbpRole - where TUser : AbpUser - { - private readonly IRepository _userRepository; - private readonly IRepository _userLoginRepository; - private readonly IRepository _userRoleRepository; - private readonly IRepository _roleRepository; - private readonly IRepository _userPermissionSettingRepository; - private readonly IAbpSession _session; - private readonly IUnitOfWorkManager _unitOfWorkManager; - - /// - /// Constructor. - /// - protected AbpUserStore( - IRepository userRepository, - IRepository userLoginRepository, - IRepository userRoleRepository, - IRepository roleRepository, - IRepository userPermissionSettingRepository, - IAbpSession session, - IUnitOfWorkManager unitOfWorkManager) - { - _userRepository = userRepository; - _userLoginRepository = userLoginRepository; - _userRoleRepository = userRoleRepository; - _roleRepository = roleRepository; - _session = session; - _unitOfWorkManager = unitOfWorkManager; - _userPermissionSettingRepository = userPermissionSettingRepository; - } - - 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 FindByIdAsync(long userId) - { - return await _userRepository.FirstOrDefaultAsync(userId); - } - - public virtual async Task FindByNameAsync(string userName) - { - return await _userRepository.FirstOrDefaultAsync( - user => user.UserName == userName - ); - } - - public virtual async Task FindByEmailAsync(string email) - { - return await _userRepository.FirstOrDefaultAsync( - user => user.EmailAddress == email - ); - } - - /// - /// Tries to find a user with user name or email address. - /// - /// User name or email address - /// User or null - public virtual async Task FindByNameOrEmailAsync(string userNameOrEmailAddress) - { - return await _userRepository.FirstOrDefaultAsync( - user => (user.UserName == userNameOrEmailAddress || user.EmailAddress == userNameOrEmailAddress) - ); - } - - /// - /// Tries to find a user with user name or email address. - /// - /// Tenant Id - /// User name or email address - /// User or null - [UnitOfWork] - public virtual async Task FindByNameOrEmailAsync(int? tenantId, string userNameOrEmailAddress) - { - using (_unitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant)) - { - return await _userRepository.FirstOrDefaultAsync( - user => - user.TenantId == tenantId && - (user.UserName == userNameOrEmailAddress || user.EmailAddress == userNameOrEmailAddress) - ); - } - } - - public virtual Task SetPasswordHashAsync(TUser user, string passwordHash) - { - user.Password = passwordHash; - return Task.FromResult(0); - } - - public virtual Task GetPasswordHashAsync(TUser user) - { - return Task.FromResult(user.Password); - } - - public virtual Task HasPasswordAsync(TUser user) - { - return Task.FromResult(!string.IsNullOrEmpty(user.Password)); - } - - public virtual Task SetEmailAsync(TUser user, string email) - { - user.EmailAddress = email; - return Task.FromResult(0); - } - - public virtual Task GetEmailAsync(TUser user) - { - return Task.FromResult(user.EmailAddress); - } - - public virtual Task GetEmailConfirmedAsync(TUser user) - { - return Task.FromResult(user.IsEmailConfirmed); - } - - public virtual Task SetEmailConfirmedAsync(TUser user, bool confirmed) - { - user.IsEmailConfirmed = confirmed; - return Task.FromResult(0); - } - - public virtual async Task AddLoginAsync(TUser user, UserLoginInfo login) - { - await _userLoginRepository.InsertAsync( - new UserLogin - { - 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> 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 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); - } - - public virtual async Task AddToRoleAsync(TUser user, string roleName) - { - var role = await _roleRepository.SingleAsync(r => r.Name == roleName); - await _userRoleRepository.InsertAsync( - new UserRole - { - UserId = user.Id, - RoleId = role.Id - }); - } - - public virtual async Task RemoveFromRoleAsync(TUser user, string roleName) - { - var role = await _roleRepository.SingleAsync(r => r.Name == roleName); - var userRole = await _userRoleRepository.FirstOrDefaultAsync(ur => ur.UserId == user.Id && ur.RoleId == role.Id); - if (userRole == null) - { - return; - } - - await _userRoleRepository.DeleteAsync(userRole); - } - - public virtual Task> GetRolesAsync(TUser user) - { - //TODO: This is not implemented as async. - var roleNames = _userRoleRepository.Query(userRoles => (from userRole in userRoles - join role in _roleRepository.GetAll() on userRole.RoleId equals role.Id - where userRole.UserId == user.Id - select role.Name).ToList()); - - return Task.FromResult>(roleNames); - } - - public virtual async Task IsInRoleAsync(TUser user, string roleName) - { - var role = await _roleRepository.SingleAsync(r => r.Name == roleName); - return await _userRoleRepository.FirstOrDefaultAsync(ur => ur.UserId == user.Id && ur.RoleId == role.Id) != null; - } - - public virtual IQueryable Users - { - get { return _userRepository.GetAll(); } - } - - public virtual async Task AddPermissionAsync(TUser user, PermissionGrantInfo permissionGrant) - { - if (await HasPermissionAsync(user, permissionGrant)) - { - return; - } - - await _userPermissionSettingRepository.InsertAsync( - new UserPermissionSetting - { - UserId = user.Id, - Name = permissionGrant.Name, - IsGranted = permissionGrant.IsGranted - }); - } - - public virtual async Task RemovePermissionAsync(TUser user, PermissionGrantInfo permissionGrant) - { - await _userPermissionSettingRepository.DeleteAsync( - permissionSetting => permissionSetting.UserId == user.Id && - permissionSetting.Name == permissionGrant.Name && - permissionSetting.IsGranted == permissionGrant.IsGranted - ); - } - - public virtual async Task> GetPermissionsAsync(TUser user) - { - return (await _userPermissionSettingRepository.GetAllListAsync(p => p.UserId == user.Id)) - .Select(p => new PermissionGrantInfo(p.Name, p.IsGranted)) - .ToList(); - } - - public virtual async Task HasPermissionAsync(TUser user, PermissionGrantInfo permissionGrant) - { - return await _userPermissionSettingRepository.FirstOrDefaultAsync( - p => p.UserId == user.Id && - p.Name == permissionGrant.Name && - p.IsGranted == permissionGrant.IsGranted - ) != null; - } - - public virtual async Task RemoveAllPermissionSettingsAsync(TUser user) - { - await _userPermissionSettingRepository.DeleteAsync(s => s.UserId == user.Id); - } - - public virtual void Dispose() - { - //No need to dispose since using IOC. - } - } -} +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Abp.Authorization.Roles; +using Abp.Dependency; +using Abp.Domain.Repositories; +using Abp.Domain.Uow; +using Abp.MultiTenancy; +using Abp.Runtime.Session; +using Microsoft.AspNet.Identity; + +namespace Abp.Authorization.Users +{ + /// + /// Implements 'User Store' of ASP.NET Identity Framework. + /// + public abstract class AbpUserStore : + IUserPasswordStore, + IUserEmailStore, + IUserLoginStore, + IUserRoleStore, + IQueryableUserStore, + IUserPermissionStore, + ITransientDependency + where TTenant : AbpTenant + where TRole : AbpRole + where TUser : AbpUser + { + private readonly IRepository _userRepository; + private readonly IRepository _userLoginRepository; + private readonly IRepository _userRoleRepository; + private readonly IRepository _roleRepository; + private readonly IRepository _userPermissionSettingRepository; + private readonly IAbpSession _session; + private readonly IUnitOfWorkManager _unitOfWorkManager; + + /// + /// Constructor. + /// + protected AbpUserStore( + IRepository userRepository, + IRepository userLoginRepository, + IRepository userRoleRepository, + IRepository roleRepository, + IRepository userPermissionSettingRepository, + IAbpSession session, + IUnitOfWorkManager unitOfWorkManager) + { + _userRepository = userRepository; + _userLoginRepository = userLoginRepository; + _userRoleRepository = userRoleRepository; + _roleRepository = roleRepository; + _session = session; + _unitOfWorkManager = unitOfWorkManager; + _userPermissionSettingRepository = userPermissionSettingRepository; + } + + 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 FindByIdAsync(long userId) + { + return await _userRepository.FirstOrDefaultAsync(userId); + } + + public virtual async Task FindByNameAsync(string userName) + { + return await _userRepository.FirstOrDefaultAsync( + user => user.UserName == userName + ); + } + + public virtual async Task FindByEmailAsync(string email) + { + return await _userRepository.FirstOrDefaultAsync( + user => user.EmailAddress == email + ); + } + + /// + /// Tries to find a user with user name or email address. + /// + /// User name or email address + /// User or null + public virtual async Task FindByNameOrEmailAsync(string userNameOrEmailAddress) + { + return await _userRepository.FirstOrDefaultAsync( + user => (user.UserName == userNameOrEmailAddress || user.EmailAddress == userNameOrEmailAddress) + ); + } + + /// + /// Tries to find a user with user name or email address. + /// + /// Tenant Id + /// User name or email address + /// User or null + [UnitOfWork] + public virtual async Task FindByNameOrEmailAsync(int? tenantId, string userNameOrEmailAddress) + { + using (_unitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant)) + { + return await _userRepository.FirstOrDefaultAsync( + user => + user.TenantId == tenantId && + (user.UserName == userNameOrEmailAddress || user.EmailAddress == userNameOrEmailAddress) + ); + } + } + + public virtual Task SetPasswordHashAsync(TUser user, string passwordHash) + { + user.Password = passwordHash; + return Task.FromResult(0); + } + + public virtual Task GetPasswordHashAsync(TUser user) + { + return Task.FromResult(user.Password); + } + + public virtual Task HasPasswordAsync(TUser user) + { + return Task.FromResult(!string.IsNullOrEmpty(user.Password)); + } + + public virtual Task SetEmailAsync(TUser user, string email) + { + user.EmailAddress = email; + return Task.FromResult(0); + } + + public virtual Task GetEmailAsync(TUser user) + { + return Task.FromResult(user.EmailAddress); + } + + public virtual Task GetEmailConfirmedAsync(TUser user) + { + return Task.FromResult(user.IsEmailConfirmed); + } + + public virtual Task SetEmailConfirmedAsync(TUser user, bool confirmed) + { + user.IsEmailConfirmed = confirmed; + return Task.FromResult(0); + } + + public virtual async Task AddLoginAsync(TUser user, UserLoginInfo login) + { + await _userLoginRepository.InsertAsync( + new UserLogin + { + 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> 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 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> 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 FindAsync(int? tenantId, UserLoginInfo login) + { + var query = from userLogin in _userLoginRepository.GetAll() + join user in _userRepository.GetAll() on userLogin.UserId equals user.Id + where user.TenantId == tenantId && userLogin.LoginProvider == login.LoginProvider && userLogin.ProviderKey == login.ProviderKey + select user; + + return Task.FromResult(query.FirstOrDefault()); + } + + public virtual async Task AddToRoleAsync(TUser user, string roleName) + { + var role = await _roleRepository.SingleAsync(r => r.Name == roleName); + await _userRoleRepository.InsertAsync( + new UserRole + { + UserId = user.Id, + RoleId = role.Id + }); + } + + public virtual async Task RemoveFromRoleAsync(TUser user, string roleName) + { + var role = await _roleRepository.SingleAsync(r => r.Name == roleName); + var userRole = await _userRoleRepository.FirstOrDefaultAsync(ur => ur.UserId == user.Id && ur.RoleId == role.Id); + if (userRole == null) + { + return; + } + + await _userRoleRepository.DeleteAsync(userRole); + } + + public virtual Task> GetRolesAsync(TUser user) + { + //TODO: This is not implemented as async. + var roleNames = _userRoleRepository.Query(userRoles => (from userRole in userRoles + join role in _roleRepository.GetAll() on userRole.RoleId equals role.Id + where userRole.UserId == user.Id + select role.Name).ToList()); + + return Task.FromResult>(roleNames); + } + + public virtual async Task IsInRoleAsync(TUser user, string roleName) + { + var role = await _roleRepository.SingleAsync(r => r.Name == roleName); + return await _userRoleRepository.FirstOrDefaultAsync(ur => ur.UserId == user.Id && ur.RoleId == role.Id) != null; + } + + public virtual IQueryable Users + { + get { return _userRepository.GetAll(); } + } + + public virtual async Task AddPermissionAsync(TUser user, PermissionGrantInfo permissionGrant) + { + if (await HasPermissionAsync(user, permissionGrant)) + { + return; + } + + await _userPermissionSettingRepository.InsertAsync( + new UserPermissionSetting + { + UserId = user.Id, + Name = permissionGrant.Name, + IsGranted = permissionGrant.IsGranted + }); + } + + public virtual async Task RemovePermissionAsync(TUser user, PermissionGrantInfo permissionGrant) + { + await _userPermissionSettingRepository.DeleteAsync( + permissionSetting => permissionSetting.UserId == user.Id && + permissionSetting.Name == permissionGrant.Name && + permissionSetting.IsGranted == permissionGrant.IsGranted + ); + } + + public virtual async Task> GetPermissionsAsync(TUser user) + { + return (await _userPermissionSettingRepository.GetAllListAsync(p => p.UserId == user.Id)) + .Select(p => new PermissionGrantInfo(p.Name, p.IsGranted)) + .ToList(); + } + + public virtual async Task HasPermissionAsync(TUser user, PermissionGrantInfo permissionGrant) + { + return await _userPermissionSettingRepository.FirstOrDefaultAsync( + p => p.UserId == user.Id && + p.Name == permissionGrant.Name && + p.IsGranted == permissionGrant.IsGranted + ) != null; + } + + public virtual async Task RemoveAllPermissionSettingsAsync(TUser user) + { + await _userPermissionSettingRepository.DeleteAsync(s => s.UserId == user.Id); + } + + public virtual void Dispose() + { + //No need to dispose since using IOC. + } + } +} diff --git a/src/Abp.Zero/Zero/AbpZeroCoreModule.cs b/src/Abp.Zero/Zero/AbpZeroCoreModule.cs index 34078984..2226dda1 100644 --- a/src/Abp.Zero/Zero/AbpZeroCoreModule.cs +++ b/src/Abp.Zero/Zero/AbpZeroCoreModule.cs @@ -1,40 +1,40 @@ -using System.Reflection; -using Abp.Localization.Sources; -using Abp.Localization.Sources.Xml; -using Abp.Modules; -using Abp.Zero.Configuration; - -namespace Abp.Zero -{ - /// - /// ABP zero core module. - /// - public class AbpZeroCoreModule : AbpModule - { - /// - /// Current version of the zero module. - /// - public const string CurrentVersion = "0.6.4.0"; - - public override void PreInitialize() - { - IocManager.Register(); - IocManager.Register(); - IocManager.Register(); - - Configuration.Settings.Providers.Add(); - - Configuration.Localization.Sources.Add( - new DictionaryBasedLocalizationSource( - AbpZeroConsts.LocalizationSourceName, - new XmlEmbeddedFileLocalizationDictionaryProvider( - Assembly.GetExecutingAssembly(), "Abp.Zero.Localization.Source" - ))); - } - - public override void Initialize() - { - IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); - } - } -} +using System.Reflection; +using Abp.Localization.Sources; +using Abp.Localization.Sources.Xml; +using Abp.Modules; +using Abp.Zero.Configuration; + +namespace Abp.Zero +{ + /// + /// ABP zero core module. + /// + public class AbpZeroCoreModule : AbpModule + { + /// + /// Current version of the zero module. + /// + public const string CurrentVersion = "0.6.4.1"; + + public override void PreInitialize() + { + IocManager.Register(); + IocManager.Register(); + IocManager.Register(); + + Configuration.Settings.Providers.Add(); + + Configuration.Localization.Sources.Add( + new DictionaryBasedLocalizationSource( + AbpZeroConsts.LocalizationSourceName, + new XmlEmbeddedFileLocalizationDictionaryProvider( + Assembly.GetExecutingAssembly(), "Abp.Zero.Localization.Source" + ))); + } + + public override void Initialize() + { + IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); + } + } +}