mirror of https://github.com/abpframework/abp.git
201 changed files with 8559 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||
# abp-account |
|||
Account module for ABP framework. |
|||
@ -0,0 +1,37 @@ |
|||
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00 |
|||
# Visual Studio 15 |
|||
VisualStudioVersion = 15.0.27428.1 |
|||
MinimumVisualStudioVersion = 10.0.40219.1 |
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B5881429-EFF7-4F30-8C0B-0AC41E36B74E}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Account.Web", "src\Volo.Abp.Account.Web\Volo.Abp.Account.Web.csproj", "{FCAC4354-7B13-4A91-A2F4-04D00F253C91}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Account.Web.IdentityServer", "src\Volo.Abp.Account.Web.IdentityServer\Volo.Abp.Account.Web.IdentityServer.csproj", "{A65A6E45-8FF7-4B78-AEA6-EAA0CDAA47E8}" |
|||
EndProject |
|||
Global |
|||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|||
Debug|Any CPU = Debug|Any CPU |
|||
Release|Any CPU = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|||
{FCAC4354-7B13-4A91-A2F4-04D00F253C91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{FCAC4354-7B13-4A91-A2F4-04D00F253C91}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{FCAC4354-7B13-4A91-A2F4-04D00F253C91}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{FCAC4354-7B13-4A91-A2F4-04D00F253C91}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{A65A6E45-8FF7-4B78-AEA6-EAA0CDAA47E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{A65A6E45-8FF7-4B78-AEA6-EAA0CDAA47E8}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{A65A6E45-8FF7-4B78-AEA6-EAA0CDAA47E8}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{A65A6E45-8FF7-4B78-AEA6-EAA0CDAA47E8}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(SolutionProperties) = preSolution |
|||
HideSolutionNode = FALSE |
|||
EndGlobalSection |
|||
GlobalSection(NestedProjects) = preSolution |
|||
{FCAC4354-7B13-4A91-A2F4-04D00F253C91} = {B5881429-EFF7-4F30-8C0B-0AC41E36B74E} |
|||
{A65A6E45-8FF7-4B78-AEA6-EAA0CDAA47E8} = {B5881429-EFF7-4F30-8C0B-0AC41E36B74E} |
|||
EndGlobalSection |
|||
GlobalSection(ExtensibilityGlobals) = postSolution |
|||
SolutionGuid = {2B054393-D2B2-4EA8-8A15-D60CBCF3E7A9} |
|||
EndGlobalSection |
|||
EndGlobal |
|||
@ -0,0 +1,16 @@ |
|||
<Project> |
|||
<PropertyGroup> |
|||
<LangVersion>latest</LangVersion> |
|||
<Version>0.3.0</Version> |
|||
<NoWarn>$(NoWarn);CS1591</NoWarn> |
|||
<PackageIconUrl>http://www.aspnetboilerplate.com/images/abp_nupkg.png</PackageIconUrl> |
|||
<PackageProjectUrl>http://abp.io</PackageProjectUrl> |
|||
<RepositoryType>git</RepositoryType> |
|||
<RepositoryUrl>https://github.com/volosoft/abp/</RepositoryUrl> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.1" PrivateAssets="All" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,16 @@ |
|||
namespace Volo.Abp.Account.Web |
|||
{ |
|||
public class AbpAccountOptions |
|||
{ |
|||
/// <summary>
|
|||
/// Default value: "Windows".
|
|||
/// </summary>
|
|||
public string WindowsAuthenticationSchemeName { get; set; } |
|||
|
|||
public AbpAccountOptions() |
|||
{ |
|||
//TODO: This makes us depend on the Microsoft.AspNetCore.Server.IISIntegration package.
|
|||
WindowsAuthenticationSchemeName = "Windows"; //Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme;
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using System.Threading.Tasks; |
|||
using Localization.Resources.AbpUi; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Localization; |
|||
using Volo.Abp.UI.Navigation; |
|||
|
|||
namespace Volo.Abp.Account.Web |
|||
{ |
|||
public class AbpAccountUserMenuContributor : IMenuContributor |
|||
{ |
|||
public AbpAccountUserMenuContributor() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public Task ConfigureMenuAsync(MenuConfigurationContext context) |
|||
{ |
|||
if (context.Menu.Name != StandardMenus.User) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
var l = context.ServiceProvider.GetRequiredService<IStringLocalizer<AbpUiResource>>(); |
|||
|
|||
context.Menu.AddItem(new ApplicationMenuItem("Account.Logout", l["Logout"], url: "/Account/Logout", icon: "fa fa-power-off", order: int.MaxValue - 1000)); |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,57 @@ |
|||
using Localization.Resources.AbpUi; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Account.Web.Localization; |
|||
using Volo.Abp.Account.Web.Settings; |
|||
using Volo.Abp.AspNetCore.Mvc.Localization; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Localization.Resources.AbpValidation; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Settings; |
|||
using Volo.Abp.UI.Navigation; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace Volo.Abp.Account.Web |
|||
{ |
|||
[DependsOn(typeof(AbpIdentityDomainModule))] |
|||
[DependsOn(typeof(AbpAspNetCoreMvcUiBootstrapModule))] |
|||
public class AbpAccountWebModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options => |
|||
{ |
|||
options.AddAssemblyResource(typeof(AccountResource), typeof(AbpAccountWebModule).Assembly); |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.Configure<SettingOptions>(options => |
|||
{ |
|||
options.DefinitionProviders.Add<AccountSettingDefinitionProvider>(); |
|||
}); |
|||
|
|||
services.Configure<VirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpAccountWebModule>("Volo.Abp.Account.Web"); |
|||
}); |
|||
|
|||
services.Configure<NavigationOptions>(options => |
|||
{ |
|||
options.MenuContributors.Add(new AbpAccountUserMenuContributor()); |
|||
}); |
|||
|
|||
services.Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Add<AccountResource>("en") |
|||
.AddVirtualJson("/Localization/Resources/AbpAccount/Web") |
|||
.AddBaseTypes(typeof(AbpUiResource), typeof(AbpValidationResource)); |
|||
}); |
|||
|
|||
services.AddAssemblyOf<AbpAccountWebModule>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace Volo.Abp.Account.Web.Areas.Account.Controllers |
|||
{ |
|||
[Area("Account")] |
|||
public class LogoutController : AbpController |
|||
{ |
|||
private readonly SignInManager<IdentityUser> _signInManager; |
|||
|
|||
public LogoutController(SignInManager<IdentityUser> signInManager) |
|||
{ |
|||
_signInManager = signInManager; |
|||
} |
|||
|
|||
public async Task<IActionResult> Index() |
|||
{ |
|||
await _signInManager.SignOutAsync(); |
|||
|
|||
return RedirectToPage("/Account/Login"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Volo.Abp.Account.Web.Localization |
|||
{ |
|||
[LocalizationResourceName("AbpAccount")] |
|||
public class AccountResource |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"UserName": "User name", |
|||
"EmailAddress": "Email address", |
|||
"UserNameOrEmailAddress": "User name or email address", |
|||
"Password": "Password", |
|||
"RememberMe": "Remember me", |
|||
"UseAnotherServiceToLogin": "Use another service to log in", |
|||
"UserLockedOutMessage": "The user account has been locked out due to invalid login attempts. Please wait a while and try again.", |
|||
"InvalidUserNameOrPassword": "Invalid username or password!", |
|||
"LoginIsNotAllowed": "You are not allowed to login! You need to confirm your email/phone number.", |
|||
"SelfRegistrationDisabledMessage": "Self user registration is disabled for this application. Contact to the application administrator to register a new user." |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
{ |
|||
"culture": "tr", |
|||
"texts": { |
|||
"UserName": "Kullanıcı adı", |
|||
"EmailAddress": "E-posta adresi", |
|||
"UserNameOrEmailAddress": "Kullanıcı adı veya e-posta", |
|||
"Password": "Şifre", |
|||
"RememberMe": "Beni hatırla", |
|||
"UseAnotherServiceToLogin": "Başka bir servisle giriş yap", |
|||
"UserLockedOutMessage": "Kullanıcı hesabı hatalı giriş denemeleri nedeniyle kilitlenmiştir. Lütfen bir süre bekleyip tekrar deneyin.", |
|||
"InvalidUserNameOrPassword": "Kullanıcı adı ya da şifre geçersiz!", |
|||
"LoginIsNotAllowed": "You are not allowed to login! E-posta adresinizi ya da telefon numaranızı doğrulamanız gerekiyor.", |
|||
"SelfRegistrationDisabledMessage": "Bu uygulama için kullanıcıların kendi kendilerine kaydolmaları engellenmiştir. Yeni bir kullanıcı kaydetmek için lütfen uygulama yöneticisi ile iletişime geçin." |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using Microsoft.AspNetCore.Mvc.Localization; |
|||
using Microsoft.AspNetCore.Mvc.Razor.Internal; |
|||
using Volo.Abp.Account.Web.Localization; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; |
|||
|
|||
namespace Volo.Abp.Account.Web.Pages.Account |
|||
{ |
|||
public abstract class AccountPage : AbpPage |
|||
{ |
|||
[RazorInject] |
|||
public IHtmlLocalizer<AccountResource> L { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,75 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.Extensions.Localization; |
|||
using Volo.Abp.Account.Web.Localization; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.UI; |
|||
|
|||
namespace Volo.Abp.Account.Web.Pages.Account |
|||
{ |
|||
public abstract class AccountPageModel : AbpPageModel |
|||
{ |
|||
public SignInManager<IdentityUser> SignInManager { get; set; } |
|||
public IdentityUserManager UserManager { get; set; } |
|||
public IStringLocalizer<AccountResource> L { get; set; } |
|||
|
|||
protected RedirectResult RedirectSafely(string returnUrl, string returnUrlHash = null) |
|||
{ |
|||
return Redirect(GetRedirectUrl(returnUrl, returnUrlHash)); |
|||
} |
|||
|
|||
protected void CheckIdentityErrors(IdentityResult identityResult) |
|||
{ |
|||
if (!identityResult.Succeeded) |
|||
{ |
|||
throw new UserFriendlyException("Operation failed: " + identityResult.Errors.Select(e => $"[{e.Code}] {e.Description}").JoinAsString(", ")); |
|||
} |
|||
|
|||
//identityResult.CheckErrors(LocalizationManager); //TODO: Get from old Abp
|
|||
} |
|||
|
|||
private string GetRedirectUrl(string returnUrl, string returnUrlHash = null) |
|||
{ |
|||
returnUrl = NormalizeReturnUrl(returnUrl); |
|||
|
|||
if (!returnUrlHash.IsNullOrWhiteSpace()) |
|||
{ |
|||
returnUrl = returnUrl + returnUrlHash; |
|||
} |
|||
|
|||
return returnUrl; |
|||
} |
|||
|
|||
private string NormalizeReturnUrl(string returnUrl) |
|||
{ |
|||
if (returnUrl.IsNullOrEmpty()) |
|||
{ |
|||
return GetAppHomeUrl(); |
|||
} |
|||
|
|||
if (Url.IsLocalUrl(returnUrl)) |
|||
{ |
|||
return returnUrl; |
|||
} |
|||
|
|||
return GetAppHomeUrl(); |
|||
} |
|||
|
|||
protected virtual void CheckCurrentTenant(Guid? tenantId) |
|||
{ |
|||
if (CurrentTenant.Id != tenantId) |
|||
{ |
|||
throw new ApplicationException($"Current tenant is different than given tenant. CurrentTenant.Id: {CurrentTenant.Id}, given tenantId: {tenantId}"); |
|||
} |
|||
} |
|||
|
|||
protected virtual string GetAppHomeUrl() |
|||
{ |
|||
return "/"; //TODO: ???
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
@page |
|||
@model Volo.Abp.Account.Web.Pages.Account.LoginModel |
|||
@using Volo.Abp.Account.Web.Settings |
|||
@inherits Volo.Abp.Account.Web.Pages.Account.AccountPage |
|||
@inject Volo.Abp.Settings.ISettingManager SettingManager |
|||
<h2>@L["Login"]</h2> |
|||
<abp-row> |
|||
<abp-column size-md="_3"> |
|||
<form method="post"> |
|||
<abp-input asp-for="Input.UserNameOrEmailAddress" auto-focus="true" /> |
|||
<abp-input asp-for="Input.Password" /> |
|||
<abp-input asp-for="Input.RememberMe" class="mb-3" /> |
|||
<abp-button button-type="Primary" type="submit">@L["Login"]</abp-button> |
|||
@if (string.Equals(await SettingManager.GetOrNullAsync(AccountSettingNames.IsSelfRegistrationEnabled), "true", StringComparison.OrdinalIgnoreCase)) |
|||
{ |
|||
<a abp-button="Secondary" href="@Url.Page("./Register", new {returnUrl = Model.ReturnUrl, returnUrlHash = Model.ReturnUrlHash})">@L["Register"]</a> |
|||
} |
|||
</form> |
|||
</abp-column> |
|||
|
|||
@if (Model.ExternalLogins.Any()) |
|||
{ |
|||
<abp-column size-md="_3"> |
|||
<h4>Use another service to log in.</h4> |
|||
<form asp-page="./Login" asp-page-handler="ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" asp-route-returnUrlHash="@Model.ReturnUrlHash" method="post"> |
|||
<div> |
|||
@foreach (var provider in Model.ExternalLogins) |
|||
{ |
|||
<abp-button button-type="Primary" type="submit" name="provider" value="@provider.Name">@provider.DisplayName</abp-button> |
|||
} |
|||
</div> |
|||
</form> |
|||
</abp-column> |
|||
} |
|||
|
|||
</abp-row> |
|||
@ -0,0 +1,163 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Linq; |
|||
using System.Security.Claims; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.Extensions.Logging; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Security.Claims; |
|||
using Volo.Abp.UI; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace Volo.Abp.Account.Web.Pages.Account |
|||
{ |
|||
public class LoginModel : AccountPageModel |
|||
{ |
|||
[BindProperty(SupportsGet = true)] |
|||
public string ReturnUrl { get; set; } |
|||
|
|||
[BindProperty(SupportsGet = true)] |
|||
public string ReturnUrlHash { get; set; } |
|||
|
|||
[BindProperty] |
|||
public PostInput Input { get; set; } |
|||
|
|||
public IList<AuthenticationScheme> ExternalLogins { get; set; } |
|||
|
|||
public async Task OnGetAsync() |
|||
{ |
|||
ExternalLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).ToList(); |
|||
} |
|||
|
|||
[UnitOfWork] //TODO: Will be removed when we implement action filter
|
|||
public virtual async Task<IActionResult> OnPostAsync() |
|||
{ |
|||
ValidateModel(); |
|||
|
|||
var result = await SignInManager.PasswordSignInAsync( |
|||
Input.UserNameOrEmailAddress, |
|||
Input.Password, |
|||
Input.RememberMe, |
|||
true |
|||
); |
|||
|
|||
if (result.IsLockedOut) |
|||
{ |
|||
Alerts.Warning(L["UserLockedOutMessage"]); |
|||
return Page(); |
|||
} |
|||
|
|||
if (result.RequiresTwoFactor) |
|||
{ |
|||
return RedirectToPage("./SendSecurityCode"); |
|||
} |
|||
|
|||
if (result.IsNotAllowed) |
|||
{ |
|||
Alerts.Warning(L["LoginIsNotAllowed"]); |
|||
return Page(); |
|||
} |
|||
|
|||
if (!result.Succeeded) |
|||
{ |
|||
Alerts.Danger(L["InvalidUserNameOrPassword"]); |
|||
return Page(); |
|||
} |
|||
|
|||
return RedirectSafely(ReturnUrl, ReturnUrlHash); |
|||
} |
|||
|
|||
[UnitOfWork] //TODO: Will be removed when we implement action filter
|
|||
public virtual IActionResult OnPostExternalLogin(string provider, string returnUrl = "", string returnUrlHash = "") |
|||
{ |
|||
var redirectUrl = Url.Page("./Login", pageHandler: "ExternalLoginCallback", values: new { returnUrl, returnUrlHash }); |
|||
|
|||
var properties = SignInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl); |
|||
|
|||
return new ChallengeResult(provider, properties); |
|||
} |
|||
|
|||
[UnitOfWork] //TODO: Will be removed when we implement action filter
|
|||
public virtual async Task<IActionResult> OnGetExternalLoginCallbackAsync(string returnUrl = "", string returnUrlHash = "", string remoteError = null) |
|||
{ |
|||
if (remoteError != null) |
|||
{ |
|||
Logger.LogWarning($"External login callback error: {remoteError}"); |
|||
return RedirectToPage("./Login"); |
|||
} |
|||
|
|||
var loginInfo = await SignInManager.GetExternalLoginInfoAsync(); |
|||
if (loginInfo == null) |
|||
{ |
|||
Logger.LogWarning("External login info is not available"); |
|||
return RedirectToPage("./Login"); |
|||
} |
|||
|
|||
var result = await SignInManager.ExternalLoginSignInAsync( |
|||
loginInfo.LoginProvider, |
|||
loginInfo.ProviderKey, |
|||
isPersistent: false, |
|||
bypassTwoFactor: true |
|||
); |
|||
|
|||
if (result.IsLockedOut) |
|||
{ |
|||
throw new UserFriendlyException("Cannot proceed because user is locked out!"); |
|||
} |
|||
|
|||
//TODO: Handle other cases
|
|||
|
|||
if (result.Succeeded) |
|||
{ |
|||
return RedirectSafely(returnUrl, returnUrlHash); |
|||
} |
|||
|
|||
// Get the information about the user from the external login provider
|
|||
var info = await SignInManager.GetExternalLoginInfoAsync(); |
|||
if (info == null) |
|||
{ |
|||
throw new ApplicationException("Error loading external login information during confirmation."); |
|||
} |
|||
|
|||
var user = await CreateExternalUserAsync(info); |
|||
|
|||
await SignInManager.SignInAsync(user, false); |
|||
return RedirectSafely(returnUrl, returnUrlHash); |
|||
} |
|||
|
|||
private async Task<IdentityUser> CreateExternalUserAsync(ExternalLoginInfo info) |
|||
{ |
|||
var emailAddress = info.Principal.FindFirstValue(AbpClaimTypes.Email); |
|||
|
|||
var user = new IdentityUser(GuidGenerator.Create(), emailAddress, emailAddress, CurrentTenant.Id); |
|||
|
|||
CheckIdentityErrors(await UserManager.CreateAsync(user)); |
|||
CheckIdentityErrors(await UserManager.SetEmailAsync(user, emailAddress)); |
|||
CheckIdentityErrors(await UserManager.AddLoginAsync(user, info)); |
|||
|
|||
return user; |
|||
} |
|||
|
|||
public class PostInput |
|||
{ |
|||
[Required] |
|||
[StringLength(255)] |
|||
[DisplayName(nameof(UserNameOrEmailAddress))] |
|||
public string UserNameOrEmailAddress { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(32)] |
|||
[DataType(DataType.Password)] |
|||
[DisplayName(nameof(Password))] |
|||
public string Password { get; set; } |
|||
|
|||
[DisplayName(nameof(RememberMe))] |
|||
public bool RememberMe { get; set; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
@page |
|||
@model Volo.Abp.Account.Web.Pages.Account.RegisterModel |
|||
@inherits Volo.Abp.Account.Web.Pages.Account.AccountPage |
|||
<h2>@L["Register"]</h2> |
|||
<abp-row> |
|||
<abp-column size-md="_3"> |
|||
<form method="post"> |
|||
<abp-input asp-for="Input.UserName" auto-focus="true" /> |
|||
<abp-input asp-for="Input.EmailAddress" /> |
|||
<abp-input asp-for="Input.Password" /> |
|||
<abp-button button-type="Primary" type="submit">@L["Register"]</abp-button> |
|||
</form> |
|||
</abp-column> |
|||
</abp-row> |
|||
@ -0,0 +1,81 @@ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.Account.Web.Settings; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Settings; |
|||
using Volo.Abp.UI; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace Volo.Abp.Account.Web.Pages.Account |
|||
{ |
|||
public class RegisterModel : AccountPageModel |
|||
{ |
|||
[BindProperty(SupportsGet = true)] |
|||
public string ReturnUrl { get; set; } |
|||
|
|||
[BindProperty(SupportsGet = true)] |
|||
public string ReturnUrlHash { get; set; } |
|||
|
|||
[BindProperty] |
|||
public PostInput Input { get; set; } |
|||
|
|||
public virtual async Task OnGet() |
|||
{ |
|||
await CheckSelfRegistrationAsync(); |
|||
} |
|||
|
|||
[UnitOfWork] //TODO: Will be removed when we implement action filter
|
|||
public virtual async Task<IActionResult> OnPostAsync() |
|||
{ |
|||
ValidateModel(); |
|||
|
|||
await CheckSelfRegistrationAsync(); |
|||
|
|||
var user = new IdentityUser(GuidGenerator.Create(), Input.UserName, Input.EmailAddress, CurrentTenant.Id); |
|||
|
|||
var result = await UserManager.CreateAsync(user, Input.Password); |
|||
|
|||
if (!result.Succeeded) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
await UserManager.SetEmailAsync(user, Input.EmailAddress); |
|||
|
|||
await SignInManager.SignInAsync(user, isPersistent: false); |
|||
|
|||
return Redirect(ReturnUrl ?? "/"); //TODO: How to ensure safety? IdentityServer requires it however it should be checked somehow!
|
|||
} |
|||
|
|||
protected virtual async Task CheckSelfRegistrationAsync() |
|||
{ |
|||
if (!await SettingManager.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled)) |
|||
{ |
|||
throw new UserFriendlyException(L["SelfRegistrationDisabledMessage"]); |
|||
} |
|||
} |
|||
|
|||
public class PostInput |
|||
{ |
|||
[Required] |
|||
[StringLength(32)] |
|||
[DisplayName(nameof(UserName))] |
|||
public string UserName { get; set; } |
|||
|
|||
[Required] |
|||
[EmailAddress] |
|||
[StringLength(255)] |
|||
[DisplayName(nameof(EmailAddress))] |
|||
public string EmailAddress { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(32)] |
|||
[DataType(DataType.Password)] |
|||
[DisplayName(nameof(Password))] |
|||
public string Password { get; set; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
@page |
|||
@using Volo.Abp.Account.Web.Pages.Account |
|||
@inherits AccountPage |
|||
@model SendSecurityCodeModel |
|||
<h2>Send security code!</h2> |
|||
<p>TODO: This page is under construction.</p> |
|||
@ -0,0 +1,45 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.Rendering; |
|||
|
|||
namespace Volo.Abp.Account.Web.Pages.Account |
|||
{ |
|||
public class SendSecurityCodeModel : AccountPageModel |
|||
{ |
|||
public List<SelectListItem> Providers { get; set; } |
|||
|
|||
public async Task<IActionResult> OnGetAsync() |
|||
{ |
|||
var user = await SignInManager.GetTwoFactorAuthenticationUserAsync(); |
|||
if (user == null) |
|||
{ |
|||
return RedirectToPage("./Login"); |
|||
} |
|||
|
|||
return Page(); |
|||
|
|||
//CheckCurrentTenant(await SignInManager.GetVerifiedTenantIdAsync());
|
|||
|
|||
//Providers = (await UserManager.GetValidTwoFactorProvidersAsync(user))
|
|||
// .Select(userProvider =>
|
|||
// new SelectListItem
|
|||
// {
|
|||
// Text = userProvider,
|
|||
// Value = userProvider
|
|||
// }).ToList();
|
|||
|
|||
//return View(
|
|||
// new SendSecurityCodeViewModel
|
|||
// {
|
|||
// ReturnUrl = returnUrl,
|
|||
// RememberMe = rememberMe
|
|||
// }
|
|||
//);
|
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,2 @@ |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
@ -0,0 +1,27 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "http://localhost:56009/", |
|||
"sslPort": 0 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"Volo.Abp.Account.Web": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
}, |
|||
"applicationUrl": "http://localhost:56013/" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace Volo.Abp.Account.Web.Settings |
|||
{ |
|||
public class AccountSettingDefinitionProvider : SettingDefinitionProvider |
|||
{ |
|||
public override void Define(ISettingDefinitionContext context) |
|||
{ |
|||
context.Add( |
|||
new SettingDefinition(AccountSettingNames.IsSelfRegistrationEnabled, "true") |
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace Volo.Abp.Account.Web.Settings |
|||
{ |
|||
public class AccountSettingNames |
|||
{ |
|||
public const string IsSelfRegistrationEnabled = "Abp.Account.IsSelfRegistrationEnabled"; |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Account.Web</AssemblyName> |
|||
<PackageId>Volo.Abp.Account.Web</PackageId> |
|||
<IsPackable>true</IsPackable> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace>Volo.Abp.Account.Web</RootNamespace> |
|||
<OutputType>Library</OutputType> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="Pages\**\*.*" Exclude="*.cs" /> |
|||
<EmbeddedResource Include="Localization\Resources\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\abp-identity\src\Volo.Abp.Identity.Domain\Volo.Abp.Identity.Domain.csproj" /> |
|||
|
|||
<ProjectReference Include="..\..\..\abp\src\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,2 @@ |
|||
# abp-identity |
|||
Microsoft ASP.NET Core Identity integration & management module |
|||
@ -0,0 +1,123 @@ |
|||
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00 |
|||
# Visual Studio 15 |
|||
VisualStudioVersion = 15.0.27428.1 |
|||
MinimumVisualStudioVersion = 10.0.40219.1 |
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AADC5A0A-F100-4511-87DE-B74E55F5B69B}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.Domain.Shared", "src\Volo.Abp.Identity.Domain.Shared\Volo.Abp.Identity.Domain.Shared.csproj", "{0A023ED6-1476-4145-B1FB-A87427D1F601}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.Domain", "src\Volo.Abp.Identity.Domain\Volo.Abp.Identity.Domain.csproj", "{762003A8-46D0-48B7-8529-8B78433662C3}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.Application.Contracts", "src\Volo.Abp.Identity.Application.Contracts\Volo.Abp.Identity.Application.Contracts.csproj", "{B8A5EBD5-0D41-46B0-8E09-96503A7F2FF9}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.Application", "src\Volo.Abp.Identity.Application\Volo.Abp.Identity.Application.csproj", "{A4EEB11B-C94A-4039-B5B5-FE5E4D6877ED}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.EntityFrameworkCore", "src\Volo.Abp.Identity.EntityFrameworkCore\Volo.Abp.Identity.EntityFrameworkCore.csproj", "{8932D139-42B5-435F-8E54-A0283034EF0C}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.HttpApi", "src\Volo.Abp.Identity.HttpApi\Volo.Abp.Identity.HttpApi.csproj", "{8AAE1E26-9804-4691-B308-68FC4940A2CF}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.HttpApi.Client", "src\Volo.Abp.Identity.HttpApi.Client\Volo.Abp.Identity.HttpApi.Client.csproj", "{281365DF-9F93-4734-9F37-0EDAA58DF6B5}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.Web", "src\Volo.Abp.Identity.Web\Volo.Abp.Identity.Web.csproj", "{9BA53D0D-C68D-4BEB-B1C0-51ED8B1162EB}" |
|||
EndProject |
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{9FACAF96-A681-4B36-A938-A37DCA0B7EC1}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.Application.Tests", "test\Volo.Abp.Identity.Application.Tests\Volo.Abp.Identity.Application.Tests.csproj", "{16D87575-35A5-4AEE-840B-C1EC74C3E22C}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.MongoDB", "src\Volo.Abp.Identity.MongoDB\Volo.Abp.Identity.MongoDB.csproj", "{F33E45A6-22E6-4F6E-947F-7E82E5171D4F}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.MongoDB.Tests", "test\Volo.Abp.Identity.MongoDB.Tests\Volo.Abp.Identity.MongoDB.Tests.csproj", "{B5891082-0799-474E-8A62-8685935D88C3}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.EntityFrameworkCore.Tests", "test\Volo.Abp.Identity.EntityFrameworkCore.Tests\Volo.Abp.Identity.EntityFrameworkCore.Tests.csproj", "{7291DCF0-7AA2-41A6-9AA7-98C2E9D13222}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.TestBase", "test\Volo.Abp.Identity.TestBase\Volo.Abp.Identity.TestBase.csproj", "{D7F61598-E7CE-4DAB-99EA-C266F0423606}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.Domain.Tests", "test\Volo.Abp.Identity.Domain.Tests\Volo.Abp.Identity.Domain.Tests.csproj", "{588B6E38-323B-4251-AC21-5F67C815A44E}" |
|||
EndProject |
|||
Global |
|||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|||
Debug|Any CPU = Debug|Any CPU |
|||
Release|Any CPU = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|||
{0A023ED6-1476-4145-B1FB-A87427D1F601}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{0A023ED6-1476-4145-B1FB-A87427D1F601}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{0A023ED6-1476-4145-B1FB-A87427D1F601}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{0A023ED6-1476-4145-B1FB-A87427D1F601}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{762003A8-46D0-48B7-8529-8B78433662C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{762003A8-46D0-48B7-8529-8B78433662C3}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{762003A8-46D0-48B7-8529-8B78433662C3}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{762003A8-46D0-48B7-8529-8B78433662C3}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{B8A5EBD5-0D41-46B0-8E09-96503A7F2FF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{B8A5EBD5-0D41-46B0-8E09-96503A7F2FF9}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{B8A5EBD5-0D41-46B0-8E09-96503A7F2FF9}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{B8A5EBD5-0D41-46B0-8E09-96503A7F2FF9}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{A4EEB11B-C94A-4039-B5B5-FE5E4D6877ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{A4EEB11B-C94A-4039-B5B5-FE5E4D6877ED}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{A4EEB11B-C94A-4039-B5B5-FE5E4D6877ED}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{A4EEB11B-C94A-4039-B5B5-FE5E4D6877ED}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{8932D139-42B5-435F-8E54-A0283034EF0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{8932D139-42B5-435F-8E54-A0283034EF0C}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{8932D139-42B5-435F-8E54-A0283034EF0C}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{8932D139-42B5-435F-8E54-A0283034EF0C}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{8AAE1E26-9804-4691-B308-68FC4940A2CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{8AAE1E26-9804-4691-B308-68FC4940A2CF}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{8AAE1E26-9804-4691-B308-68FC4940A2CF}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{8AAE1E26-9804-4691-B308-68FC4940A2CF}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{281365DF-9F93-4734-9F37-0EDAA58DF6B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{281365DF-9F93-4734-9F37-0EDAA58DF6B5}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{281365DF-9F93-4734-9F37-0EDAA58DF6B5}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{281365DF-9F93-4734-9F37-0EDAA58DF6B5}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{9BA53D0D-C68D-4BEB-B1C0-51ED8B1162EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{9BA53D0D-C68D-4BEB-B1C0-51ED8B1162EB}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{9BA53D0D-C68D-4BEB-B1C0-51ED8B1162EB}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{9BA53D0D-C68D-4BEB-B1C0-51ED8B1162EB}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{16D87575-35A5-4AEE-840B-C1EC74C3E22C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{16D87575-35A5-4AEE-840B-C1EC74C3E22C}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{16D87575-35A5-4AEE-840B-C1EC74C3E22C}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{16D87575-35A5-4AEE-840B-C1EC74C3E22C}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{F33E45A6-22E6-4F6E-947F-7E82E5171D4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{F33E45A6-22E6-4F6E-947F-7E82E5171D4F}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{F33E45A6-22E6-4F6E-947F-7E82E5171D4F}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{F33E45A6-22E6-4F6E-947F-7E82E5171D4F}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{B5891082-0799-474E-8A62-8685935D88C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{B5891082-0799-474E-8A62-8685935D88C3}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{B5891082-0799-474E-8A62-8685935D88C3}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{B5891082-0799-474E-8A62-8685935D88C3}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{7291DCF0-7AA2-41A6-9AA7-98C2E9D13222}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{7291DCF0-7AA2-41A6-9AA7-98C2E9D13222}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{7291DCF0-7AA2-41A6-9AA7-98C2E9D13222}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{7291DCF0-7AA2-41A6-9AA7-98C2E9D13222}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{D7F61598-E7CE-4DAB-99EA-C266F0423606}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{D7F61598-E7CE-4DAB-99EA-C266F0423606}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{D7F61598-E7CE-4DAB-99EA-C266F0423606}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{D7F61598-E7CE-4DAB-99EA-C266F0423606}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{588B6E38-323B-4251-AC21-5F67C815A44E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{588B6E38-323B-4251-AC21-5F67C815A44E}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{588B6E38-323B-4251-AC21-5F67C815A44E}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{588B6E38-323B-4251-AC21-5F67C815A44E}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(SolutionProperties) = preSolution |
|||
HideSolutionNode = FALSE |
|||
EndGlobalSection |
|||
GlobalSection(NestedProjects) = preSolution |
|||
{0A023ED6-1476-4145-B1FB-A87427D1F601} = {AADC5A0A-F100-4511-87DE-B74E55F5B69B} |
|||
{762003A8-46D0-48B7-8529-8B78433662C3} = {AADC5A0A-F100-4511-87DE-B74E55F5B69B} |
|||
{B8A5EBD5-0D41-46B0-8E09-96503A7F2FF9} = {AADC5A0A-F100-4511-87DE-B74E55F5B69B} |
|||
{A4EEB11B-C94A-4039-B5B5-FE5E4D6877ED} = {AADC5A0A-F100-4511-87DE-B74E55F5B69B} |
|||
{8932D139-42B5-435F-8E54-A0283034EF0C} = {AADC5A0A-F100-4511-87DE-B74E55F5B69B} |
|||
{8AAE1E26-9804-4691-B308-68FC4940A2CF} = {AADC5A0A-F100-4511-87DE-B74E55F5B69B} |
|||
{281365DF-9F93-4734-9F37-0EDAA58DF6B5} = {AADC5A0A-F100-4511-87DE-B74E55F5B69B} |
|||
{9BA53D0D-C68D-4BEB-B1C0-51ED8B1162EB} = {AADC5A0A-F100-4511-87DE-B74E55F5B69B} |
|||
{16D87575-35A5-4AEE-840B-C1EC74C3E22C} = {9FACAF96-A681-4B36-A938-A37DCA0B7EC1} |
|||
{F33E45A6-22E6-4F6E-947F-7E82E5171D4F} = {AADC5A0A-F100-4511-87DE-B74E55F5B69B} |
|||
{B5891082-0799-474E-8A62-8685935D88C3} = {9FACAF96-A681-4B36-A938-A37DCA0B7EC1} |
|||
{7291DCF0-7AA2-41A6-9AA7-98C2E9D13222} = {9FACAF96-A681-4B36-A938-A37DCA0B7EC1} |
|||
{D7F61598-E7CE-4DAB-99EA-C266F0423606} = {9FACAF96-A681-4B36-A938-A37DCA0B7EC1} |
|||
{588B6E38-323B-4251-AC21-5F67C815A44E} = {9FACAF96-A681-4B36-A938-A37DCA0B7EC1} |
|||
EndGlobalSection |
|||
GlobalSection(ExtensibilityGlobals) = postSolution |
|||
SolutionGuid = {05740D37-83CF-4041-9C2A-D89F1B3DB5A4} |
|||
EndGlobalSection |
|||
EndGlobal |
|||
@ -0,0 +1,16 @@ |
|||
<Project> |
|||
<PropertyGroup> |
|||
<LangVersion>latest</LangVersion> |
|||
<Version>0.3.0</Version> |
|||
<NoWarn>$(NoWarn);CS1591</NoWarn> |
|||
<PackageIconUrl>http://www.aspnetboilerplate.com/images/abp_nupkg.png</PackageIconUrl> |
|||
<PackageProjectUrl>http://abp.io</PackageProjectUrl> |
|||
<RepositoryType>git</RepositoryType> |
|||
<RepositoryUrl>https://github.com/volosoft/abp/</RepositoryUrl> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.1" PrivateAssets="All" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,18 @@ |
|||
using System.Reflection; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
// General Information about an assembly is controlled through the following
|
|||
// set of attributes. Change these attribute values to modify the information
|
|||
// associated with an assembly.
|
|||
[assembly: AssemblyConfiguration("")] |
|||
[assembly: AssemblyCompany("")] |
|||
[assembly: AssemblyProduct("Volo.Abp.Identity.Application.Contracts")] |
|||
[assembly: AssemblyTrademark("")] |
|||
|
|||
// Setting ComVisible to false makes the types in this assembly not visible
|
|||
// to COM components. If you need to access a type in this assembly from
|
|||
// COM, set the ComVisible attribute to true on that type.
|
|||
[assembly: ComVisible(false)] |
|||
|
|||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|||
[assembly: Guid("c714a3ab-8402-4dc2-b120-accb2e29bd8f")] |
|||
@ -0,0 +1,29 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Identity.Application.Contracts</AssemblyName> |
|||
<PackageId>Volo.Abp.Identity.Application.Contracts</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="Volo\Abp\Identity\Localization\ApplicationContracts\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.Identity.Domain.Shared\Volo.Abp.Identity.Domain.Shared.csproj" /> |
|||
|
|||
<ProjectReference Include="..\..\..\abp-permissionmanagement\src\Volo.Abp.PermissionManagement.Application.Contracts\Volo.Abp.PermissionManagement.Application.Contracts.csproj" /> |
|||
|
|||
<ProjectReference Include="..\..\..\abp\src\Volo.Abp.Authorization\Volo.Abp.Authorization.csproj" /> |
|||
<ProjectReference Include="..\..\..\abp\src\Volo.Abp.Ddd.Application\Volo.Abp.Ddd.Application.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,39 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Application; |
|||
using Volo.Abp.Authorization; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Identity.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.PermissionManagement; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
[DependsOn(typeof(AbpIdentityDomainSharedModule))] |
|||
[DependsOn(typeof(AbpAuthorizationModule))] |
|||
[DependsOn(typeof(AbpDddApplicationModule))] |
|||
[DependsOn(typeof(AbpPermissionManagementApplicationContractsModule))] |
|||
public class AbpIdentityApplicationContractsModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.Configure<PermissionOptions>(options => |
|||
{ |
|||
options.DefinitionProviders.Add<IdentityPermissionDefinitionProvider>(); |
|||
}); |
|||
|
|||
services.Configure<VirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpIdentityApplicationContractsModule>(); |
|||
}); |
|||
|
|||
services.Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources.Get<IdentityResource>().AddVirtualJson("/Volo/Abp/Identity/Localization/ApplicationContracts"); |
|||
}); |
|||
|
|||
services.AddAssemblyOf<AbpIdentityApplicationContractsModule>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class GetIdentityRolesInput : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class GetIdentityUsersInput : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.PermissionManagement; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public interface IIdentityRoleAppService : IAsyncCrudAppService<IdentityRoleDto, Guid, GetIdentityRolesInput, IdentityRoleCreateDto, IdentityRoleUpdateDto> |
|||
{ |
|||
//TODO: remove after a better design
|
|||
Task<List<IdentityRoleDto>> GetAllListAsync(); |
|||
|
|||
Task<GetPermissionListResultDto> GetPermissionsAsync(Guid id); |
|||
|
|||
Task UpdatePermissionsAsync(Guid id, UpdatePermissionsDto input); |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.PermissionManagement; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public interface IIdentityUserAppService : IAsyncCrudAppService<IdentityUserDto, Guid, GetIdentityUsersInput, IdentityUserCreateDto, IdentityUserUpdateDto> |
|||
{ |
|||
Task<ListResultDto<IdentityRoleDto>> GetRolesAsync(Guid id); |
|||
|
|||
Task UpdateRolesAsync(Guid id, IdentityUserUpdateRolesDto input); |
|||
|
|||
Task<GetPermissionListResultDto> GetPermissionsAsync(Guid id); |
|||
|
|||
Task UpdatePermissionsAsync(Guid id, UpdatePermissionsDto input); |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Identity.Localization; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityPermissionDefinitionProvider : PermissionDefinitionProvider |
|||
{ |
|||
public override void Define(IPermissionDefinitionContext context) |
|||
{ |
|||
var identityGroup = context.AddGroup(IdentityPermissions.GroupName, L("Permission:IdentityManagement")); |
|||
|
|||
var rolesPermission = identityGroup.AddPermission(IdentityPermissions.Roles.Default, L("Permission:RoleManagement")); |
|||
rolesPermission.AddChild(IdentityPermissions.Roles.Create, L("Permission:Create")); |
|||
rolesPermission.AddChild(IdentityPermissions.Roles.Update, L("Permission:Edit")); |
|||
rolesPermission.AddChild(IdentityPermissions.Roles.Delete, L("Permission:Delete")); |
|||
rolesPermission.AddChild(IdentityPermissions.Roles.ManagePermissions, L("Permission:ChangePermissions")); |
|||
|
|||
var usersPermission = identityGroup.AddPermission(IdentityPermissions.Users.Default, L("Permission:UserManagement")); |
|||
usersPermission.AddChild(IdentityPermissions.Users.Create, L("Permission:Create")); |
|||
usersPermission.AddChild(IdentityPermissions.Users.Update, L("Permission:Edit")); |
|||
usersPermission.AddChild(IdentityPermissions.Users.Delete, L("Permission:Delete")); |
|||
usersPermission.AddChild(IdentityPermissions.Users.ManagePermissions, L("Permission:ChangePermissions")); |
|||
} |
|||
|
|||
private static LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<IdentityResource>(name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class IdentityPermissions |
|||
{ |
|||
public const string GroupName = "AbpIdentity"; |
|||
|
|||
public static class Roles |
|||
{ |
|||
public const string Default = GroupName + ".Roles"; |
|||
public const string Create = Default + ".Create"; |
|||
public const string Update = Default + ".Update"; |
|||
public const string Delete = Default + ".Delete"; |
|||
public const string ManagePermissions = Default + ".ManagePermissions"; |
|||
} |
|||
|
|||
public static class Users |
|||
{ |
|||
public const string Default = GroupName + ".Users"; |
|||
public const string Create = Default + ".Create"; |
|||
public const string Update = Default + ".Update"; |
|||
public const string Delete = Default + ".Delete"; |
|||
public const string ManagePermissions = Default + ".ManagePermissions"; |
|||
} |
|||
|
|||
public static string[] GetAll() |
|||
{ |
|||
return new[] |
|||
{ |
|||
GroupName, |
|||
Roles.Default, |
|||
Roles.Create, |
|||
Roles.Update, |
|||
Roles.Delete, |
|||
Roles.ManagePermissions, |
|||
Users.Default, |
|||
Users.Create, |
|||
Users.Update, |
|||
Users.Delete, |
|||
Users.ManagePermissions |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityRoleCreateDto : IdentityRoleCreateOrUpdateDtoBase |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityRoleCreateOrUpdateDtoBase |
|||
{ |
|||
[Required] |
|||
[StringLength(IdentityRoleConsts.MaxNameLength)] |
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityRoleDto : EntityDto<Guid> |
|||
{ |
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityRoleUpdateDto : IdentityRoleCreateOrUpdateDtoBase |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityUserCreateDto : IdentityUserCreateOrUpdateDtoBase |
|||
{ |
|||
[Required] |
|||
[StringLength(IdentityUserConsts.MaxPasswordLength)] |
|||
public string Password { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public abstract class IdentityUserCreateOrUpdateDtoBase |
|||
{ |
|||
[Required] |
|||
[StringLength(IdentityUserConsts.MaxUserNameLength)] |
|||
public string UserName { get; set; } |
|||
|
|||
[Required] |
|||
[EmailAddress] |
|||
[StringLength(IdentityUserConsts.MaxEmailLength)] |
|||
public string Email { get; set; } |
|||
|
|||
[StringLength(IdentityUserConsts.MaxPhoneNumberLength)] |
|||
public string PhoneNumber { get; set; } |
|||
|
|||
public bool TwoFactorEnabled { get; set; } |
|||
|
|||
public bool LockoutEnabled { get; set; } |
|||
|
|||
[CanBeNull] |
|||
public string[] RoleNames { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityUserDto : EntityDto<Guid>, IMultiTenant |
|||
{ |
|||
public Guid? TenantId { get; set; } |
|||
|
|||
public string UserName { get; set; } |
|||
|
|||
public string Email { get; set; } |
|||
|
|||
public bool EmailConfirmed { get; set; } |
|||
|
|||
public string PhoneNumber { get; set; } |
|||
|
|||
public bool PhoneNumberConfirmed { get; set; } |
|||
|
|||
public bool TwoFactorEnabled { get; set; } |
|||
|
|||
public bool LockoutEnabled { get; set; } |
|||
|
|||
public DateTimeOffset? LockoutEnd { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityUserUpdateDto : IdentityUserCreateOrUpdateDtoBase |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityUserUpdateRolesDto |
|||
{ |
|||
[Required] |
|||
public string[] RoleNames { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"Permission:IdentityManagement": "Idetity management", |
|||
"Permission:RoleManagement": "Role management", |
|||
"Permission:Create": "Create", |
|||
"Permission:Edit": "Edit", |
|||
"Permission:Delete": "Delete", |
|||
"Permission:ChangePermissions": "Change permissions", |
|||
"Permission:UserManagement": "User management" |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"culture": "tr", |
|||
"texts": { |
|||
"Permission:IdentityManagement": "Kimlik yönetimi", |
|||
"Permission:RoleManagement": "Rol yönetimi", |
|||
"Permission:Create": "Oluşturma", |
|||
"Permission:Edit": "Düzenleme", |
|||
"Permission:Delete": "Silme", |
|||
"Permission:ChangePermissions": "İzinleri değiştirme", |
|||
"Permission:UserManagement": "Kullanıcı yönetimi" |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System.Reflection; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
// General Information about an assembly is controlled through the following
|
|||
// set of attributes. Change these attribute values to modify the information
|
|||
// associated with an assembly.
|
|||
[assembly: AssemblyConfiguration("")] |
|||
[assembly: AssemblyCompany("")] |
|||
[assembly: AssemblyProduct("Volo.Abp.Identity.Application")] |
|||
[assembly: AssemblyTrademark("")] |
|||
|
|||
// Setting ComVisible to false makes the types in this assembly not visible
|
|||
// to COM components. If you need to access a type in this assembly from
|
|||
// COM, set the ComVisible attribute to true on that type.
|
|||
[assembly: ComVisible(false)] |
|||
|
|||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|||
[assembly: Guid("54592671-9cb6-48ae-9ae0-84cd016e87ff")] |
|||
@ -0,0 +1,25 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Identity.Application</AssemblyName> |
|||
<PackageId>Volo.Abp.Identity.Application</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.Identity.Application.Contracts\Volo.Abp.Identity.Application.Contracts.csproj" /> |
|||
<ProjectReference Include="..\Volo.Abp.Identity.Domain\Volo.Abp.Identity.Domain.csproj" /> |
|||
|
|||
<ProjectReference Include="..\..\..\abp-permissionmanagement\src\Volo.Abp.PermissionManagement.Application\Volo.Abp.PermissionManagement.Application.csproj" /> |
|||
|
|||
<ProjectReference Include="..\..\..\abp\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,26 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.PermissionManagement; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpIdentityDomainModule), |
|||
typeof(AbpIdentityApplicationContractsModule), |
|||
typeof(AbpAutoMapperModule), |
|||
typeof(AbpPermissionManagementApplicationModule) |
|||
)] |
|||
public class AbpIdentityApplicationModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddProfile<AbpIdentityApplicationModuleAutoMapperProfile>(); |
|||
}); |
|||
|
|||
services.AddAssemblyOf<AbpIdentityApplicationModule>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using AutoMapper; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class AbpIdentityApplicationModuleAutoMapperProfile : Profile |
|||
{ |
|||
public AbpIdentityApplicationModuleAutoMapperProfile() |
|||
{ |
|||
CreateMap<IdentityUser, IdentityUserDto>(); |
|||
CreateMap<IdentityRole, IdentityRoleDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public abstract class IdentityAppServiceBase : ApplicationService |
|||
{ |
|||
protected void CheckIdentityErrors(IdentityResult identityResult) |
|||
{ |
|||
if (!identityResult.Succeeded) |
|||
{ |
|||
//TODO: A better exception that can be shown on UI as localized?
|
|||
throw new AbpException("Operation failed: " + identityResult.Errors.Select(e => $"[{e.Code}] {e.Description}").JoinAsString(", ")); |
|||
} |
|||
|
|||
//identityResult.CheckErrors(LocalizationManager); //TODO: Get from old Abp
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,104 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.PermissionManagement; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
[Authorize(IdentityPermissions.Roles.Default)] |
|||
public class IdentityRoleAppService : ApplicationService, IIdentityRoleAppService |
|||
{ |
|||
private readonly IdentityRoleManager _roleManager; |
|||
private readonly IIdentityRoleRepository _roleRepository; |
|||
private readonly IPermissionAppServiceHelper _permissionAppServiceHelper; |
|||
|
|||
public IdentityRoleAppService( |
|||
IdentityRoleManager roleManager, |
|||
IIdentityRoleRepository roleRepository, |
|||
IPermissionAppServiceHelper permissionAppServiceHelper) |
|||
{ |
|||
_roleManager = roleManager; |
|||
_roleRepository = roleRepository; |
|||
_permissionAppServiceHelper = permissionAppServiceHelper; |
|||
} |
|||
|
|||
public async Task<IdentityRoleDto> GetAsync(Guid id) |
|||
{ |
|||
return ObjectMapper.Map<IdentityRole, IdentityRoleDto>( |
|||
await _roleManager.GetByIdAsync(id) |
|||
); |
|||
} |
|||
|
|||
public async Task<PagedResultDto<IdentityRoleDto>> GetListAsync(GetIdentityRolesInput input) //TODO: Remove this method since it's not used
|
|||
{ |
|||
var count = (int) await _roleRepository.GetCountAsync(); |
|||
var list = await _roleRepository.GetListAsync(); |
|||
|
|||
return new PagedResultDto<IdentityRoleDto>( |
|||
count, |
|||
ObjectMapper.Map<List<IdentityRole>, List<IdentityRoleDto>>(list) |
|||
); |
|||
} |
|||
|
|||
public async Task<List<IdentityRoleDto>> GetAllListAsync() //TODO: Rename to GetList (however it's not possible because of the design of the IAsyncCrudAppService)
|
|||
{ |
|||
var list = await _roleRepository.GetListAsync(); |
|||
|
|||
return ObjectMapper.Map<List<IdentityRole>, List<IdentityRoleDto>>(list); |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.Roles.ManagePermissions)] |
|||
public async Task<GetPermissionListResultDto> GetPermissionsAsync(Guid id) |
|||
{ |
|||
var role = await _roleRepository.GetAsync(id); |
|||
return await _permissionAppServiceHelper.GetAsync(RolePermissionValueProvider.ProviderName, role.Name); //TODO: User normalized role name instad of name?
|
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.Roles.ManagePermissions)] |
|||
public async Task UpdatePermissionsAsync(Guid id, UpdatePermissionsDto input) |
|||
{ |
|||
var role = await _roleRepository.GetAsync(id); |
|||
await _permissionAppServiceHelper.UpdateAsync(RolePermissionValueProvider.ProviderName, role.Name, input); |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.Roles.Create)] |
|||
public async Task<IdentityRoleDto> CreateAsync(IdentityRoleCreateDto input) |
|||
{ |
|||
var role = new IdentityRole(GuidGenerator.Create(), input.Name, CurrentTenant.Id); |
|||
|
|||
await _roleManager.CreateAsync(role); |
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<IdentityRole, IdentityRoleDto>(role); |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.Roles.Update)] |
|||
public async Task<IdentityRoleDto> UpdateAsync(Guid id, IdentityRoleUpdateDto input) |
|||
{ |
|||
var role = await _roleManager.GetByIdAsync(id); |
|||
|
|||
await _roleManager.SetRoleNameAsync(role, input.Name); |
|||
|
|||
await _roleManager.UpdateAsync(role); |
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<IdentityRole, IdentityRoleDto>(role); |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.Roles.Delete)] |
|||
public async Task DeleteAsync(Guid id) |
|||
{ |
|||
var role = await _roleManager.FindByIdAsync(id.ToString()); |
|||
if (role == null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
await _roleManager.DeleteAsync(role); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,128 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.PermissionManagement; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
[Authorize(IdentityPermissions.Users.Default)] |
|||
public class IdentityUserAppService : IdentityAppServiceBase, IIdentityUserAppService |
|||
{ |
|||
private readonly IdentityUserManager _userManager; |
|||
private readonly IIdentityUserRepository _userRepository; |
|||
private readonly IPermissionAppServiceHelper _permissionAppServiceHelper; |
|||
|
|||
public IdentityUserAppService( |
|||
IdentityUserManager userManager, |
|||
IIdentityUserRepository userRepository, |
|||
IPermissionAppServiceHelper permissionAppServiceHelper) |
|||
{ |
|||
_userManager = userManager; |
|||
_userRepository = userRepository; |
|||
_permissionAppServiceHelper = permissionAppServiceHelper; |
|||
} |
|||
|
|||
public async Task<IdentityUserDto> GetAsync(Guid id) |
|||
{ |
|||
return ObjectMapper.Map<IdentityUser, IdentityUserDto>( |
|||
await _userManager.GetByIdAsync(id) |
|||
); |
|||
} |
|||
|
|||
public async Task<PagedResultDto<IdentityUserDto>> GetListAsync(GetIdentityUsersInput input) |
|||
{ |
|||
var count = await _userRepository.GetCountAsync(); //TODO:
|
|||
var list = await _userRepository.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount, input.Filter); |
|||
|
|||
return new PagedResultDto<IdentityUserDto>( |
|||
count, |
|||
ObjectMapper.Map<List<IdentityUser>, List<IdentityUserDto>>(list) |
|||
); |
|||
} |
|||
|
|||
public async Task<ListResultDto<IdentityRoleDto>> GetRolesAsync(Guid id) |
|||
{ |
|||
var roles = await _userRepository.GetRolesAsync(id); |
|||
return new ListResultDto<IdentityRoleDto>( |
|||
ObjectMapper.Map<List<IdentityRole>, List<IdentityRoleDto>>(roles) |
|||
); |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.Users.Create)] |
|||
public async Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input) |
|||
{ |
|||
var user = new IdentityUser(GuidGenerator.Create(), input.UserName, input.Email, CurrentTenant.Id); |
|||
|
|||
CheckIdentityErrors(await _userManager.CreateAsync(user, input.Password)); |
|||
await UpdateUserByInput(user, input); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<IdentityUser, IdentityUserDto>(user); |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.Users.Update)] |
|||
public async Task<IdentityUserDto> UpdateAsync(Guid id, IdentityUserUpdateDto input) |
|||
{ |
|||
var user = await _userManager.GetByIdAsync(id); |
|||
|
|||
CheckIdentityErrors(await _userManager.SetUserNameAsync(user, input.UserName)); |
|||
await UpdateUserByInput(user, input); |
|||
CheckIdentityErrors(await _userManager.UpdateAsync(user)); |
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<IdentityUser, IdentityUserDto>(user); |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.Users.Delete)] |
|||
public async Task DeleteAsync(Guid id) |
|||
{ |
|||
var user = await _userManager.FindByIdAsync(id.ToString()); |
|||
if (user == null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
CheckIdentityErrors(await _userManager.DeleteAsync(user)); |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.Users.Update)] |
|||
public async Task UpdateRolesAsync(Guid id, IdentityUserUpdateRolesDto input) |
|||
{ |
|||
var user = await _userManager.GetByIdAsync(id); |
|||
CheckIdentityErrors(await _userManager.SetRolesAsync(user, input.RoleNames)); |
|||
await _userRepository.UpdateAsync(user); |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.Users.ManagePermissions)] |
|||
public async Task<GetPermissionListResultDto> GetPermissionsAsync(Guid id) |
|||
{ |
|||
var user = await _userManager.GetByIdAsync(id); |
|||
var result = await _permissionAppServiceHelper.GetAsync(UserPermissionValueProvider.ProviderName, id.ToString()); |
|||
result.EntityDisplayName = user.UserName; |
|||
return result; |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.Users.ManagePermissions)] |
|||
public async Task UpdatePermissionsAsync(Guid id, UpdatePermissionsDto input) |
|||
{ |
|||
await _permissionAppServiceHelper.UpdateAsync(UserPermissionValueProvider.ProviderName, id.ToString(), input); |
|||
} |
|||
|
|||
private async Task UpdateUserByInput(IdentityUser user, IdentityUserCreateOrUpdateDtoBase input) |
|||
{ |
|||
CheckIdentityErrors(await _userManager.SetEmailAsync(user, input.Email)); |
|||
CheckIdentityErrors(await _userManager.SetPhoneNumberAsync(user, input.PhoneNumber)); |
|||
CheckIdentityErrors(await _userManager.SetTwoFactorEnabledAsync(user, input.TwoFactorEnabled)); |
|||
CheckIdentityErrors(await _userManager.SetLockoutEnabledAsync(user, input.LockoutEnabled)); |
|||
|
|||
if (input.RoleNames != null) |
|||
{ |
|||
CheckIdentityErrors(await _userManager.SetRolesAsync(user, input.RoleNames)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Identity.Domain.Shared</AssemblyName> |
|||
<PackageId>Volo.Abp.Identity.Domain.Shared</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\abp-users\src\Volo.Abp.Users.Domain.Shared\Volo.Abp.Users.Domain.Shared.csproj" /> |
|||
|
|||
<ProjectReference Include="..\..\..\abp\src\Volo.Abp.Localization\Volo.Abp.Localization.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,23 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Identity.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
[DependsOn(typeof(AbpUsersDomainSharedModule))] |
|||
[DependsOn(typeof(AbpLocalizationModule))] |
|||
public class AbpIdentityDomainSharedModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources.Add<IdentityResource>("en"); |
|||
}); |
|||
|
|||
services.AddAssemblyOf<AbpIdentityDomainSharedModule>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class IdentityRoleClaimConsts |
|||
{ |
|||
public const int MaxClaimTypeLength = IdentityUserClaimConsts.MaxClaimTypeLength; |
|||
|
|||
public const int MaxClaimValueLength = IdentityUserClaimConsts.MaxClaimValueLength; |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class IdentityRoleConsts |
|||
{ |
|||
public const int MaxNameLength = 256; |
|||
public const int MaxNormalizedNameLength = MaxNameLength; |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class IdentityUserClaimConsts |
|||
{ |
|||
public const int MaxClaimTypeLength = 256; |
|||
|
|||
public const int MaxClaimValueLength = 1024; |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class IdentityUserConsts |
|||
{ |
|||
public const int MaxUserNameLength = AbpUserConsts.MaxUserNameLength; |
|||
|
|||
public const int MaxNormalizedUserNameLength = MaxUserNameLength; |
|||
|
|||
public const int MaxEmailLength = AbpUserConsts.MaxEmailLength; |
|||
|
|||
public const int MaxNormalizedEmailLength = MaxEmailLength; |
|||
|
|||
public const int MaxPhoneNumberLength = AbpUserConsts.MaxPhoneNumberLength; |
|||
|
|||
public const int MaxPasswordLength = 32; |
|||
|
|||
public const int MaxPasswordHashLength = 256; |
|||
|
|||
public const int MaxSecurityStampLength = 256; |
|||
|
|||
public const int MaxConcurrencyStampLength = 256; |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class IdentityUserLoginConsts |
|||
{ |
|||
public const int MaxLoginProviderLength = 64; |
|||
public const int MaxProviderKeyLength = 196; |
|||
public const int MaxProviderDisplayNameLength = 128; |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class IdentityUserTokenConsts |
|||
{ |
|||
public const int MaxLoginProviderLength = 64; |
|||
|
|||
public const int MaxNameLength = 128; |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Volo.Abp.Identity.Localization |
|||
{ |
|||
[LocalizationResourceName("AbpIdentity")] |
|||
public class IdentityResource //TODO: Rename to AbpIdentityResource
|
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
using System; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public static class AbpIdentityServiceCollectionExtensions |
|||
{ |
|||
public static IdentityBuilder AddAbpIdentity(this IServiceCollection services) |
|||
{ |
|||
return services.AddAbpIdentity(setupAction: null); |
|||
} |
|||
|
|||
public static IdentityBuilder AddAbpIdentity(this IServiceCollection services, Action<IdentityOptions> setupAction) |
|||
{ |
|||
//AbpRoleManager
|
|||
services.TryAddScoped<IdentityRoleManager>(); |
|||
services.TryAddScoped(typeof(RoleManager<IdentityRole>), provider => provider.GetService(typeof(IdentityRoleManager))); |
|||
|
|||
//AbpUserManager
|
|||
services.TryAddScoped<IdentityUserManager>(); |
|||
services.TryAddScoped(typeof(UserManager<IdentityUser>), provider => provider.GetService(typeof(IdentityUserManager))); |
|||
|
|||
//AbpSecurityStampValidator
|
|||
services.TryAddScoped<AbpSecurityStampValidator>(); |
|||
services.TryAddScoped(typeof(SecurityStampValidator<IdentityUser>), provider => provider.GetService(typeof(AbpSecurityStampValidator))); |
|||
services.TryAddScoped(typeof(ISecurityStampValidator), provider => provider.GetService(typeof(AbpSecurityStampValidator))); |
|||
|
|||
//AbpUserStore
|
|||
services.TryAddScoped<IdentityUserStore>(); |
|||
services.TryAddScoped(typeof(IUserStore<IdentityUser>), provider => provider.GetService(typeof(IdentityUserStore))); |
|||
|
|||
//AbpRoleStore
|
|||
services.TryAddScoped<IdentityRoleStore>(); |
|||
services.TryAddScoped(typeof(IRoleStore<IdentityRole>), provider => provider.GetService(typeof(IdentityRoleStore))); |
|||
|
|||
return services.AddIdentity<IdentityUser, IdentityRole>(setupAction) |
|||
.AddDefaultTokenProviders() |
|||
.AddClaimsPrincipalFactory<AbpUserClaimsPrincipalFactory>(); |
|||
//return services.AddIdentityCore<IdentityUser>(setupAction);
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System.Reflection; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
// General Information about an assembly is controlled through the following
|
|||
// set of attributes. Change these attribute values to modify the information
|
|||
// associated with an assembly.
|
|||
[assembly: AssemblyConfiguration("")] |
|||
[assembly: AssemblyCompany("")] |
|||
[assembly: AssemblyProduct("Volo.Abp.Identity")] |
|||
[assembly: AssemblyTrademark("")] |
|||
[assembly: InternalsVisibleTo("Volo.Abp.Identity.Application.Tests")] |
|||
[assembly: InternalsVisibleTo("Volo.Abp.Identity.TestBase.Orm")] |
|||
[assembly: InternalsVisibleTo("Volo.Abp.Identity.TestBase")] |
|||
|
|||
// Setting ComVisible to false makes the types in this assembly not visible
|
|||
// to COM components. If you need to access a type in this assembly from
|
|||
// COM, set the ComVisible attribute to true on that type.
|
|||
[assembly: ComVisible(false)] |
|||
|
|||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|||
[assembly: Guid("17dbb40a-243e-41f7-a672-fa316ecb1e33")] |
|||
@ -0,0 +1,29 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Identity.Domain</AssemblyName> |
|||
<PackageId>Volo.Abp.Identity.Domain</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.Identity.Domain.Shared\Volo.Abp.Identity.Domain.Shared.csproj" /> |
|||
|
|||
<ProjectReference Include="..\..\..\abp-users\src\Volo.Abp.Users.Domain\Volo.Abp.Users.Domain.csproj" /> |
|||
<ProjectReference Include="..\..\..\abp-permissionmanagement\src\Volo.Abp.PermissionManagement.Domain\Volo.Abp.PermissionManagement.Domain.csproj" /> |
|||
|
|||
<ProjectReference Include="..\..\..\abp\src\Volo.Abp.Ddd.Domain\Volo.Abp.Ddd.Domain.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.1.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,2 @@ |
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> |
|||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp71</s:String></wpf:ResourceDictionary> |
|||
@ -0,0 +1,9 @@ |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class AbpIdentityConsts |
|||
{ |
|||
public const string DefaultDbTablePrefix = "Abp"; |
|||
|
|||
public const string DefaultDbSchema = null; |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Domain; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.PermissionManagement; |
|||
using Volo.Abp.Settings; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
[DependsOn(typeof(AbpPermissionManagementDomainModule))] |
|||
[DependsOn(typeof(AbpDddDomainModule))] |
|||
[DependsOn(typeof(AbpIdentityDomainSharedModule))] |
|||
[DependsOn(typeof(AbpUsersDomainModule))] |
|||
public class AbpIdentityDomainModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.Configure<PermissionManagementOptions>(options => |
|||
{ |
|||
options.ManagementProviders.Add<UserPermissionManagementProvider>(); |
|||
options.ManagementProviders.Add<RolePermissionManagementProvider>(); |
|||
}); |
|||
|
|||
services.Configure<SettingOptions>(options => |
|||
{ |
|||
options.DefinitionProviders.Add<AbpIdentitySettingDefinitionProvider>(); |
|||
}); |
|||
|
|||
var identityBuilder = services.AddAbpIdentity(options => |
|||
{ |
|||
options.User.RequireUniqueEmail = true; |
|||
}); |
|||
|
|||
services.ExecutePreConfiguredActions(identityBuilder); |
|||
|
|||
AddAbpIdentityOptionsFactory(services); |
|||
|
|||
services.AddAssemblyOf<AbpIdentityDomainModule>(); |
|||
} |
|||
|
|||
private static void AddAbpIdentityOptionsFactory(IServiceCollection services) |
|||
{ |
|||
services.Replace(ServiceDescriptor.Transient<IOptionsFactory<IdentityOptions>, AbpIdentityOptionsFactory>()); |
|||
services.Replace(ServiceDescriptor.Scoped<IOptions<IdentityOptions>, OptionsManager<IdentityOptions>>()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Json; |
|||
using Volo.Abp.Options; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class AbpIdentityOptionsFactory : AbpOptionsFactory<IdentityOptions> |
|||
{ |
|||
private readonly ISettingManager _settingManager; |
|||
private readonly IJsonSerializer _jsonSerializer; |
|||
|
|||
public AbpIdentityOptionsFactory( |
|||
IEnumerable<IConfigureOptions<IdentityOptions>> setups, |
|||
IEnumerable<IPostConfigureOptions<IdentityOptions>> postConfigures, |
|||
ISettingManager settingManager, |
|||
IJsonSerializer jsonSerializer) |
|||
: base(setups, postConfigures) |
|||
{ |
|||
_settingManager = settingManager; |
|||
_jsonSerializer = jsonSerializer; |
|||
} |
|||
|
|||
public override IdentityOptions Create(string name) |
|||
{ |
|||
var options = base.Create(name); |
|||
|
|||
SetPasswordOptions(options); |
|||
|
|||
return options; |
|||
} |
|||
|
|||
protected virtual void SetPasswordOptions(IdentityOptions options) |
|||
{ |
|||
options.Password.RequiredLength = _settingManager.Get(IdentitySettingNames.Password.RequiredLength, options.Password.RequiredLength); |
|||
options.Password.RequiredUniqueChars = _settingManager.Get(IdentitySettingNames.Password.RequiredUniqueChars, options.Password.RequiredUniqueChars); |
|||
options.Password.RequireNonAlphanumeric = _settingManager.Get(IdentitySettingNames.Password.RequireNonAlphanumeric, options.Password.RequireNonAlphanumeric); |
|||
options.Password.RequireLowercase = _settingManager.Get(IdentitySettingNames.Password.RequireLowercase, options.Password.RequireLowercase); |
|||
options.Password.RequireUppercase = _settingManager.Get(IdentitySettingNames.Password.RequireUppercase, options.Password.RequireUppercase); |
|||
options.Password.RequireDigit = _settingManager.Get(IdentitySettingNames.Password.RequireDigit, options.Password.RequireDigit); |
|||
|
|||
options.Lockout.AllowedForNewUsers = _settingManager.Get(IdentitySettingNames.Lockout.AllowedForNewUsers, options.Lockout.AllowedForNewUsers); |
|||
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromSeconds(_settingManager.Get(IdentitySettingNames.Lockout.LockoutDuration, options.Lockout.DefaultLockoutTimeSpan.TotalSeconds.To<int>())); |
|||
options.Lockout.MaxFailedAccessAttempts = _settingManager.Get(IdentitySettingNames.Lockout.MaxFailedAccessAttempts, options.Lockout.MaxFailedAccessAttempts); |
|||
|
|||
options.SignIn.RequireConfirmedEmail = _settingManager.Get(IdentitySettingNames.SignIn.RequireConfirmedEmail, options.SignIn.RequireConfirmedEmail); |
|||
options.SignIn.RequireConfirmedPhoneNumber = _settingManager.Get(IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber, options.SignIn.RequireConfirmedPhoneNumber); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class AbpIdentitySettingDefinitionProvider : SettingDefinitionProvider |
|||
{ |
|||
public override void Define(ISettingDefinitionContext context) |
|||
{ |
|||
context.Add( |
|||
|
|||
new SettingDefinition(IdentitySettingNames.Password.RequiredLength), |
|||
new SettingDefinition(IdentitySettingNames.Password.RequiredUniqueChars), |
|||
new SettingDefinition(IdentitySettingNames.Password.RequireNonAlphanumeric), |
|||
new SettingDefinition(IdentitySettingNames.Password.RequireLowercase), |
|||
new SettingDefinition(IdentitySettingNames.Password.RequireUppercase), |
|||
new SettingDefinition(IdentitySettingNames.Password.RequireDigit), |
|||
|
|||
new SettingDefinition(IdentitySettingNames.Lockout.AllowedForNewUsers), |
|||
new SettingDefinition(IdentitySettingNames.Lockout.LockoutDuration), |
|||
new SettingDefinition(IdentitySettingNames.Lockout.MaxFailedAccessAttempts), |
|||
|
|||
new SettingDefinition(IdentitySettingNames.SignIn.RequireConfirmedEmail), |
|||
new SettingDefinition(IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber) |
|||
|
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.AspNetCore.Authentication.Cookies; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class AbpSecurityStampValidator : SecurityStampValidator<IdentityUser> |
|||
{ |
|||
public AbpSecurityStampValidator( |
|||
IOptions<SecurityStampValidatorOptions> options, |
|||
SignInManager<IdentityUser> signInManager, |
|||
ISystemClock systemClock) |
|||
: base( |
|||
options, |
|||
signInManager, |
|||
systemClock) |
|||
{ |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public override Task ValidateAsync(CookieValidatePrincipalContext context) |
|||
{ |
|||
return base.ValidateAsync(context); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
using System.Linq; |
|||
using System.Security.Claims; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Security.Claims; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class AbpUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<IdentityUser, IdentityRole>, ITransientDependency |
|||
{ |
|||
public AbpUserClaimsPrincipalFactory( |
|||
UserManager<IdentityUser> userManager, |
|||
RoleManager<IdentityRole> roleManager, |
|||
IOptions<IdentityOptions> options) |
|||
: base( |
|||
userManager, |
|||
roleManager, |
|||
options) |
|||
{ |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public override async Task<ClaimsPrincipal> CreateAsync(IdentityUser user) |
|||
{ |
|||
var principal = await base.CreateAsync(user); |
|||
|
|||
if (user.TenantId.HasValue) |
|||
{ |
|||
principal.Identities |
|||
.First() |
|||
.AddClaim(new Claim(AbpClaimTypes.TenantId, user.TenantId.ToString())); |
|||
} |
|||
|
|||
return principal; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public interface IIdentityDataSeeder |
|||
{ |
|||
Task SeedAsync( |
|||
string adminUserPassword, |
|||
IEnumerable<string> adminRolePermissions = null, |
|||
Guid? tenantId = null); |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public interface IIdentityRoleRepository : IBasicRepository<IdentityRole, Guid> |
|||
{ |
|||
Task<IdentityRole> FindByNormalizedNameAsync( |
|||
string normalizedRoleName, |
|||
bool includeDetails = true, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<List<IdentityRole>> GetListAsync( |
|||
string sorting = null, |
|||
int maxResultCount = int.MaxValue, |
|||
int skipCount = 0, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<long> GetCountAsync( |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,69 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Security.Claims; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public interface IIdentityUserRepository : IBasicRepository<IdentityUser, Guid> |
|||
{ |
|||
Task<IdentityUser> FindByNormalizedUserNameAsync( |
|||
[NotNull] string normalizedUserName, |
|||
bool includeDetails = true, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<List<string>> GetRoleNamesAsync( |
|||
Guid id, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<IdentityUser> FindByLoginAsync( |
|||
[NotNull] string loginProvider, |
|||
[NotNull] string providerKey, |
|||
bool includeDetails = true, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<IdentityUser> FindByNormalizedEmailAsync( |
|||
[NotNull] string normalizedEmail, |
|||
bool includeDetails = true, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<List<IdentityUser>> GetListByClaimAsync( |
|||
Claim claim, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<List<IdentityUser>> GetListByNormalizedRoleNameAsync( |
|||
string normalizedRoleName, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<List<IdentityUser>> GetListAsync( |
|||
string sorting = null, |
|||
int maxResultCount = int.MaxValue, |
|||
int skipCount = 0, |
|||
string filter = null, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<List<IdentityRole>> GetRolesAsync( |
|||
Guid id, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<long> GetCountAsync( |
|||
string filter = null, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
using System; |
|||
using System.Security.Claims; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public abstract class IdentityClaim : Entity<Guid>, IMultiTenant |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the claim type for this claim.
|
|||
/// </summary>
|
|||
public virtual string ClaimType { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the claim value for this claim.
|
|||
/// </summary>
|
|||
public virtual string ClaimValue { get; protected set; } |
|||
|
|||
protected IdentityClaim() |
|||
{ |
|||
|
|||
} |
|||
|
|||
protected internal IdentityClaim(Guid id, [NotNull] Claim claim, Guid? tenantId) |
|||
: this(id, claim.Type, claim.Value, tenantId) |
|||
{ |
|||
|
|||
} |
|||
|
|||
protected internal IdentityClaim(Guid id, [NotNull] string claimType, string claimValue, Guid? tenantId) |
|||
{ |
|||
Check.NotNull(claimType, nameof(claimType)); |
|||
|
|||
Id = id; |
|||
ClaimType = claimType; |
|||
ClaimValue = claimValue; |
|||
TenantId = tenantId; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a Claim instance from this entity.
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
public virtual Claim ToClaim() |
|||
{ |
|||
return new Claim(ClaimType, ClaimValue); |
|||
} |
|||
|
|||
public virtual void SetClaim([NotNull] Claim claim) |
|||
{ |
|||
Check.NotNull(claim, nameof(claim)); |
|||
|
|||
ClaimType = claim.Type; |
|||
ClaimValue = claim.Value; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,109 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.PermissionManagement; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityDataSeeder : ITransientDependency, IIdentityDataSeeder |
|||
{ |
|||
private readonly IGuidGenerator _guidGenerator; |
|||
private readonly IPermissionGrantRepository _permissionGrantRepository; |
|||
private readonly IIdentityRoleRepository _roleRepository; |
|||
private readonly IIdentityUserRepository _userRepository; |
|||
private readonly ILookupNormalizer _lookupNormalizer; |
|||
private readonly IdentityUserManager _userManager; |
|||
private readonly IdentityRoleManager _roleManager; |
|||
|
|||
public IdentityDataSeeder( |
|||
IGuidGenerator guidGenerator, |
|||
IPermissionGrantRepository permissionGrantRepository, |
|||
IIdentityRoleRepository roleRepository, |
|||
IIdentityUserRepository userRepository, |
|||
ILookupNormalizer lookupNormalizer, |
|||
IdentityUserManager userManager, |
|||
IdentityRoleManager roleManager) |
|||
{ |
|||
_guidGenerator = guidGenerator; |
|||
_permissionGrantRepository = permissionGrantRepository; |
|||
_roleRepository = roleRepository; |
|||
_userRepository = userRepository; |
|||
_lookupNormalizer = lookupNormalizer; |
|||
_userManager = userManager; |
|||
_roleManager = roleManager; |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public virtual async Task SeedAsync( |
|||
string adminUserPassword, |
|||
IEnumerable<string> adminRolePermissions = null, |
|||
Guid? tenantId = null) |
|||
{ |
|||
const string adminUserName = "admin"; |
|||
const string adminRoleName = "admin"; |
|||
|
|||
//"admin" user
|
|||
var adminUser = await _userRepository.FindByNormalizedUserNameAsync(_lookupNormalizer.Normalize(adminUserName)); |
|||
if (adminUser != null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
adminUser = new IdentityUser(_guidGenerator.Create(), adminUserName, "admin@abp.io", tenantId); |
|||
CheckIdentityErrors(await _userManager.CreateAsync(adminUser, adminUserPassword)); |
|||
|
|||
//"admin" role
|
|||
var adminRole = await _roleRepository.FindByNormalizedNameAsync(_lookupNormalizer.Normalize(adminRoleName)); |
|||
if (adminRole == null) |
|||
{ |
|||
adminRole = new IdentityRole(_guidGenerator.Create(), adminRoleName, tenantId); |
|||
CheckIdentityErrors(await _roleManager.CreateAsync(adminRole)); |
|||
|
|||
if (adminRolePermissions != null) |
|||
{ |
|||
await AddRolePermissionsAsync(adminRole, adminRolePermissions); |
|||
} |
|||
} |
|||
|
|||
CheckIdentityErrors(await _userManager.AddToRoleAsync(adminUser, adminRoleName)); |
|||
} |
|||
|
|||
protected virtual async Task AddRolePermissionsAsync(IdentityRole role, IEnumerable<string> permissionNames) |
|||
{ |
|||
foreach (var permissionName in permissionNames) |
|||
{ |
|||
await AddPermissionAsync(permissionName, RolePermissionValueProvider.ProviderName, role.Name, role.TenantId); |
|||
} |
|||
} |
|||
|
|||
protected virtual Task AddPermissionAsync(string permissionName, string providerName, string providerKey, Guid? tenantId) |
|||
{ |
|||
return _permissionGrantRepository.InsertAsync( |
|||
new PermissionGrant( |
|||
_guidGenerator.Create(), |
|||
permissionName, |
|||
providerName, |
|||
providerKey, |
|||
tenantId |
|||
) |
|||
); |
|||
} |
|||
|
|||
protected void CheckIdentityErrors(IdentityResult identityResult) //TODO: This is temporary and duplicate code!
|
|||
{ |
|||
if (!identityResult.Succeeded) |
|||
{ |
|||
//TODO: A better exception that can be shown on UI as localized?
|
|||
throw new AbpException("Operation failed: " + identityResult.Errors.Select(e => $"[{e.Code}] {e.Description}").JoinAsString(", ")); |
|||
} |
|||
|
|||
//identityResult.CheckErrors(LocalizationManager); //TODO: Get from old Abp
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,88 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Security.Claims; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a role in the identity system
|
|||
/// </summary>
|
|||
public class IdentityRole : AggregateRoot<Guid>, IHasConcurrencyStamp, IMultiTenant |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the name for this role.
|
|||
/// </summary>
|
|||
public virtual string Name { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the normalized name for this role.
|
|||
/// </summary>
|
|||
public virtual string NormalizedName { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Navigation property for claims in this role.
|
|||
/// </summary>
|
|||
public virtual ICollection<IdentityRoleClaim> Claims { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// A random value that should change whenever a role is persisted to the store
|
|||
/// </summary>
|
|||
public virtual string ConcurrencyStamp { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of <see cref="IdentityRole"/>.
|
|||
/// </summary>
|
|||
protected IdentityRole() { } |
|||
|
|||
public IdentityRole(Guid id, [NotNull] string name, Guid? tenantId = null) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
Id = id; |
|||
Name = name; |
|||
TenantId = tenantId; |
|||
NormalizedName = name.ToUpperInvariant(); |
|||
ConcurrencyStamp = Guid.NewGuid().ToString(); |
|||
|
|||
Claims = new Collection<IdentityRoleClaim>(); |
|||
} |
|||
|
|||
public virtual void AddClaim([NotNull] IGuidGenerator guidGenerator, [NotNull] Claim claim) |
|||
{ |
|||
Check.NotNull(guidGenerator, nameof(guidGenerator)); |
|||
Check.NotNull(claim, nameof(claim)); |
|||
|
|||
Claims.Add(new IdentityRoleClaim(guidGenerator.Create(), Id, claim, TenantId)); |
|||
} |
|||
|
|||
public virtual void AddClaims([NotNull] IGuidGenerator guidGenerator, [NotNull] IEnumerable<Claim> claims) |
|||
{ |
|||
Check.NotNull(guidGenerator, nameof(guidGenerator)); |
|||
Check.NotNull(claims, nameof(claims)); |
|||
|
|||
foreach (var claim in claims) |
|||
{ |
|||
AddClaim(guidGenerator, claim); |
|||
} |
|||
} |
|||
|
|||
public virtual void RemoveClaim([NotNull] Claim claim) |
|||
{ |
|||
Check.NotNull(claim, nameof(claim)); |
|||
|
|||
Claims.RemoveAll(c => c.ClaimType == claim.Type && c.ClaimValue == claim.Value); |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return $"{base.ToString()}, Name = {Name}"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
using System; |
|||
using System.Security.Claims; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a claim that is granted to all users within a role.
|
|||
/// </summary>
|
|||
public class IdentityRoleClaim : IdentityClaim |
|||
{ |
|||
/// <summary>
|
|||
/// Gets or sets the of the primary key of the role associated with this claim.
|
|||
/// </summary>
|
|||
public virtual Guid RoleId { get; protected set; } |
|||
|
|||
protected IdentityRoleClaim() |
|||
{ |
|||
|
|||
} |
|||
|
|||
protected internal IdentityRoleClaim( |
|||
Guid id, |
|||
Guid roleId, |
|||
[NotNull] Claim claim, |
|||
Guid? tenantId) |
|||
: base( |
|||
id, |
|||
claim, |
|||
tenantId) |
|||
{ |
|||
RoleId = roleId; |
|||
} |
|||
|
|||
protected internal IdentityRoleClaim( |
|||
Guid id, |
|||
Guid roleId, |
|||
[NotNull] string claimType, |
|||
string claimValue, |
|||
Guid? tenantId) |
|||
: base( |
|||
id, |
|||
claimType, |
|||
claimValue, |
|||
tenantId) |
|||
{ |
|||
RoleId = roleId; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.Logging; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Domain.Services; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityRoleManager : RoleManager<IdentityRole>, IDomainService |
|||
{ |
|||
protected override CancellationToken CancellationToken => _cancellationTokenProvider.Token; |
|||
|
|||
private readonly ICancellationTokenProvider _cancellationTokenProvider; |
|||
|
|||
public IdentityRoleManager( |
|||
IdentityRoleStore store, |
|||
IEnumerable<IRoleValidator<IdentityRole>> roleValidators, |
|||
ILookupNormalizer keyNormalizer, |
|||
IdentityErrorDescriber errors, |
|||
ILogger<IdentityRoleManager> logger, |
|||
ICancellationTokenProvider cancellationTokenProvider) |
|||
: base( |
|||
store, |
|||
roleValidators, |
|||
keyNormalizer, |
|||
errors, |
|||
logger) |
|||
{ |
|||
_cancellationTokenProvider = cancellationTokenProvider; |
|||
} |
|||
|
|||
public async Task<IdentityRole> GetByIdAsync(Guid id) |
|||
{ |
|||
var role = await Store.FindByIdAsync(id.ToString(), CancellationToken); |
|||
if (role == null) |
|||
{ |
|||
throw new EntityNotFoundException(typeof(IdentityRole), id); |
|||
} |
|||
|
|||
return role; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class IdentityRoleRepositoryExtensions |
|||
{ |
|||
public static IdentityRole FindByNormalizedName(this IIdentityRoleRepository roleRepository, string normalizedRoleName) |
|||
{ |
|||
return AsyncHelper.RunSync(() => roleRepository.FindByNormalizedNameAsync(normalizedRoleName)); |
|||
} |
|||
|
|||
//TODO: Other sync extension methods
|
|||
} |
|||
} |
|||
@ -0,0 +1,293 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Security.Claims; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.Logging; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Guids; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
/// <summary>
|
|||
/// Creates a new instance of a persistence store for roles.
|
|||
/// </summary>
|
|||
public class IdentityRoleStore : |
|||
IRoleStore<IdentityRole>, |
|||
IRoleClaimStore<IdentityRole>, |
|||
ITransientDependency |
|||
{ |
|||
private readonly IIdentityRoleRepository _roleRepository; |
|||
private readonly ILogger<IdentityRoleStore> _logger; |
|||
private readonly IGuidGenerator _guidGenerator; |
|||
|
|||
/// <summary>
|
|||
/// Constructs a new instance of <see cref="IdentityRoleStore"/>.
|
|||
/// </summary>
|
|||
public IdentityRoleStore( |
|||
IIdentityRoleRepository roleRepository, |
|||
ILogger<IdentityRoleStore> logger, |
|||
IGuidGenerator guidGenerator, |
|||
IdentityErrorDescriber describer = null) |
|||
{ |
|||
_roleRepository = roleRepository; |
|||
_logger = logger; |
|||
_guidGenerator = guidGenerator; |
|||
|
|||
ErrorDescriber = describer ?? new IdentityErrorDescriber(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the <see cref="IdentityErrorDescriber"/> for any error that occurred with the current operation.
|
|||
/// </summary>
|
|||
public IdentityErrorDescriber ErrorDescriber { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a flag indicating if changes should be persisted after CreateAsync, UpdateAsync and DeleteAsync are called.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// True if changes should be automatically persisted, otherwise false.
|
|||
/// </value>
|
|||
public bool AutoSaveChanges { get; set; } = true; |
|||
|
|||
/// <summary>
|
|||
/// Creates a new role in a store as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role to create in the store.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="IdentityResult"/> of the asynchronous query.</returns>
|
|||
public virtual async Task<IdentityResult> CreateAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
await _roleRepository.InsertAsync(role, AutoSaveChanges, cancellationToken); |
|||
|
|||
return IdentityResult.Success; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Updates a role in a store as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role to update in the store.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="IdentityResult"/> of the asynchronous query.</returns>
|
|||
public virtual async Task<IdentityResult> UpdateAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
try |
|||
{ |
|||
await _roleRepository.UpdateAsync(role, AutoSaveChanges, cancellationToken); |
|||
} |
|||
catch (AbpDbConcurrencyException ex) |
|||
{ |
|||
_logger.LogWarning(ex.ToString()); //Trigger some AbpHandledException event
|
|||
return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure()); |
|||
} |
|||
|
|||
return IdentityResult.Success; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Deletes a role from the store as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role to delete from the store.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="IdentityResult"/> of the asynchronous query.</returns>
|
|||
public virtual async Task<IdentityResult> DeleteAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
try |
|||
{ |
|||
await _roleRepository.DeleteAsync(role, AutoSaveChanges, cancellationToken); |
|||
} |
|||
catch (AbpDbConcurrencyException ex) |
|||
{ |
|||
_logger.LogWarning(ex.ToString()); //Trigger some AbpHandledException event
|
|||
return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure()); |
|||
} |
|||
|
|||
return IdentityResult.Success; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the ID for a role from the store as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role whose ID should be returned.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that contains the ID of the role.</returns>
|
|||
public Task<string> GetRoleIdAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
return Task.FromResult(role.Id.ToString()); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the name of a role from the store as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role whose name should be returned.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that contains the name of the role.</returns>
|
|||
public Task<string> GetRoleNameAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
return Task.FromResult(role.Name); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Sets the name of a role in the store as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role whose name should be set.</param>
|
|||
/// <param name="roleName">The name of the role.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
|
|||
public Task SetRoleNameAsync([NotNull] IdentityRole role, string roleName, CancellationToken cancellationToken = default) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
role.Name = roleName; |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Finds the role who has the specified ID as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="id">The role ID to look for.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that result of the look up.</returns>
|
|||
public virtual Task<IdentityRole> FindByIdAsync(string id, CancellationToken cancellationToken = default) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
return _roleRepository.FindAsync(Guid.Parse(id), cancellationToken: cancellationToken); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Finds the role who has the specified normalized name as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="normalizedName">The normalized role name to look for.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that result of the look up.</returns>
|
|||
public virtual Task<IdentityRole> FindByNameAsync([NotNull] string normalizedName, CancellationToken cancellationToken = default) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
Check.NotNull(normalizedName, nameof(normalizedName)); |
|||
|
|||
return _roleRepository.FindByNormalizedNameAsync(normalizedName, cancellationToken: cancellationToken); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Get a role's normalized name as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role whose normalized name should be retrieved.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that contains the name of the role.</returns>
|
|||
public virtual Task<string> GetNormalizedRoleNameAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
return Task.FromResult(role.NormalizedName); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Set a role's normalized name as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role whose normalized name should be set.</param>
|
|||
/// <param name="normalizedName">The normalized name to set</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
|
|||
public virtual Task SetNormalizedRoleNameAsync([NotNull] IdentityRole role, string normalizedName, CancellationToken cancellationToken = default) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
role.NormalizedName = normalizedName; |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Dispose the stores
|
|||
/// </summary>
|
|||
public void Dispose() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Get the claims associated with the specified <paramref name="role"/> as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role whose claims should be retrieved.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that contains the claims granted to a role.</returns>
|
|||
public async Task<IList<Claim>> GetClaimsAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
await _roleRepository.EnsureCollectionLoadedAsync(role, r => r.Claims, cancellationToken); |
|||
|
|||
return role.Claims.Select(c => c.ToClaim()).ToList(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds the <paramref name="claim"/> given to the specified <paramref name="role"/>.
|
|||
/// </summary>
|
|||
/// <param name="role">The role to add the claim to.</param>
|
|||
/// <param name="claim">The claim to add to the role.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
|
|||
public async Task AddClaimAsync([NotNull] IdentityRole role, [NotNull] Claim claim, CancellationToken cancellationToken = default) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
Check.NotNull(claim, nameof(claim)); |
|||
|
|||
await _roleRepository.EnsureCollectionLoadedAsync(role, r => r.Claims, cancellationToken); |
|||
|
|||
role.AddClaim(_guidGenerator, claim); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Removes the <paramref name="claim"/> given from the specified <paramref name="role"/>.
|
|||
/// </summary>
|
|||
/// <param name="role">The role to remove the claim from.</param>
|
|||
/// <param name="claim">The claim to remove from the role.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
|
|||
public async Task RemoveClaimAsync([NotNull] IdentityRole role, [NotNull] Claim claim, CancellationToken cancellationToken = default) |
|||
{ |
|||
Check.NotNull(role, nameof(role)); |
|||
Check.NotNull(claim, nameof(claim)); |
|||
|
|||
await _roleRepository.EnsureCollectionLoadedAsync(role, r => r.Claims, cancellationToken); |
|||
|
|||
role.RemoveClaim(claim); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class IdentitySettingNames |
|||
{ |
|||
private const string Prefix = "Abp.Identity"; |
|||
|
|||
public static class Password |
|||
{ |
|||
private const string PasswordPrefix = Prefix + ".Password"; |
|||
|
|||
public const string RequiredLength = PasswordPrefix + ".RequiredLength"; |
|||
public const string RequiredUniqueChars = PasswordPrefix + ".RequiredUniqueChars"; |
|||
public const string RequireNonAlphanumeric = PasswordPrefix + ".RequireNonAlphanumeric"; |
|||
public const string RequireLowercase = PasswordPrefix + ".RequireLowercase"; |
|||
public const string RequireUppercase = PasswordPrefix + ".RequireUppercase"; |
|||
public const string RequireDigit = PasswordPrefix + ".RequireDigit"; |
|||
} |
|||
|
|||
public static class Lockout |
|||
{ |
|||
private const string LockoutPrefix = Prefix + ".Lockout"; |
|||
|
|||
public const string AllowedForNewUsers = LockoutPrefix + ".AllowedForNewUsers"; |
|||
public const string LockoutDuration = LockoutPrefix + ".LockoutDuration"; |
|||
public const string MaxFailedAccessAttempts = LockoutPrefix + ".MaxFailedAccessAttempts"; |
|||
} |
|||
|
|||
public static class SignIn |
|||
{ |
|||
private const string SignInPrefix = Prefix + ".SignIn"; |
|||
|
|||
public const string RequireConfirmedEmail = SignInPrefix + ".RequireConfirmedEmail"; |
|||
public const string RequireConfirmedPhoneNumber = SignInPrefix + ".RequireConfirmedPhoneNumber"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,269 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Linq; |
|||
using System.Security.Claims; |
|||
using JetBrains.Annotations; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityUser : AggregateRoot<Guid>, IHasConcurrencyStamp, IUser, IHasExtraProperties |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the user name for this user.
|
|||
/// </summary>
|
|||
public virtual string UserName { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the normalized user name for this user.
|
|||
/// </summary>
|
|||
public virtual string NormalizedUserName { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the email address for this user.
|
|||
/// </summary>
|
|||
public virtual string Email { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the normalized email address for this user.
|
|||
/// </summary>
|
|||
public virtual string NormalizedEmail { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a flag indicating if a user has confirmed their email address.
|
|||
/// </summary>
|
|||
/// <value>True if the email address has been confirmed, otherwise false.</value>
|
|||
public virtual bool EmailConfirmed { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a salted and hashed representation of the password for this user.
|
|||
/// </summary>
|
|||
public virtual string PasswordHash { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// A random value that must change whenever a users credentials change (password changed, login removed)
|
|||
/// </summary>
|
|||
public virtual string SecurityStamp { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// A random value that must change whenever a user is persisted to the store
|
|||
/// </summary>
|
|||
public virtual string ConcurrencyStamp { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a telephone number for the user.
|
|||
/// </summary>
|
|||
public virtual string PhoneNumber { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a flag indicating if a user has confirmed their telephone address.
|
|||
/// </summary>
|
|||
/// <value>True if the telephone number has been confirmed, otherwise false.</value>
|
|||
public virtual bool PhoneNumberConfirmed { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a flag indicating if two factor authentication is enabled for this user.
|
|||
/// </summary>
|
|||
/// <value>True if 2fa is enabled, otherwise false.</value>
|
|||
public virtual bool TwoFactorEnabled { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the date and time, in UTC, when any user lockout ends.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// A value in the past means the user is not locked out.
|
|||
/// </remarks>
|
|||
public virtual DateTimeOffset? LockoutEnd { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a flag indicating if the user could be locked out.
|
|||
/// </summary>
|
|||
/// <value>True if the user could be locked out, otherwise false.</value>
|
|||
public virtual bool LockoutEnabled { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the number of failed login attempts for the current user.
|
|||
/// </summary>
|
|||
public virtual int AccessFailedCount { get; protected internal set; } |
|||
|
|||
//TODO: Can we make collections readonly collection, which will provide encapsulation. But... can work for all ORMs?
|
|||
|
|||
/// <summary>
|
|||
/// Navigation property for the roles this user belongs to.
|
|||
/// </summary>
|
|||
public virtual ICollection<IdentityUserRole> Roles { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Navigation property for the claims this user possesses.
|
|||
/// </summary>
|
|||
public virtual ICollection<IdentityUserClaim> Claims { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Navigation property for this users login accounts.
|
|||
/// </summary>
|
|||
public virtual ICollection<IdentityUserLogin> Logins { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Navigation property for this users tokens.
|
|||
/// </summary>
|
|||
public virtual ICollection<IdentityUserToken> Tokens { get; protected set; } |
|||
|
|||
public Dictionary<string, object> ExtraProperties { get; protected set; } |
|||
|
|||
protected IdentityUser() |
|||
{ |
|||
ExtraProperties = new Dictionary<string, object>(); |
|||
} |
|||
|
|||
public IdentityUser(Guid id, [NotNull] string userName, [NotNull] string email, Guid? tenantId = null) |
|||
{ |
|||
Check.NotNull(userName, nameof(userName)); |
|||
|
|||
Id = id; |
|||
TenantId = tenantId; |
|||
UserName = userName; |
|||
NormalizedUserName = userName.ToUpperInvariant(); |
|||
Email = email; |
|||
NormalizedEmail = email.ToUpperInvariant(); |
|||
ConcurrencyStamp = Guid.NewGuid().ToString(); |
|||
SecurityStamp = Guid.NewGuid().ToString(); |
|||
|
|||
Roles = new Collection<IdentityUserRole>(); |
|||
Claims = new Collection<IdentityUserClaim>(); |
|||
Logins = new Collection<IdentityUserLogin>(); |
|||
Tokens = new Collection<IdentityUserToken>(); |
|||
|
|||
ExtraProperties = new Dictionary<string, object>(); |
|||
} |
|||
|
|||
public virtual void AddRole(Guid roleId) |
|||
{ |
|||
Check.NotNull(roleId, nameof(roleId)); |
|||
|
|||
if (IsInRole(roleId)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
Roles.Add(new IdentityUserRole(Id, roleId, TenantId)); |
|||
} |
|||
|
|||
public virtual void RemoveRole(Guid roleId) |
|||
{ |
|||
Check.NotNull(roleId, nameof(roleId)); |
|||
|
|||
if (!IsInRole(roleId)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
Roles.RemoveAll(r => r.RoleId == roleId); |
|||
} |
|||
|
|||
public virtual bool IsInRole(Guid roleId) |
|||
{ |
|||
Check.NotNull(roleId, nameof(roleId)); |
|||
|
|||
return Roles.Any(r => r.RoleId == roleId); |
|||
} |
|||
|
|||
public virtual void AddClaim([NotNull] IGuidGenerator guidGenerator, [NotNull] Claim claim) |
|||
{ |
|||
Check.NotNull(guidGenerator, nameof(guidGenerator)); |
|||
Check.NotNull(claim, nameof(claim)); |
|||
|
|||
Claims.Add(new IdentityUserClaim(guidGenerator.Create(), Id, claim, TenantId)); |
|||
} |
|||
|
|||
public virtual void AddClaims([NotNull] IGuidGenerator guidGenerator, [NotNull] IEnumerable<Claim> claims) |
|||
{ |
|||
Check.NotNull(guidGenerator, nameof(guidGenerator)); |
|||
Check.NotNull(claims, nameof(claims)); |
|||
|
|||
foreach (var claim in claims) |
|||
{ |
|||
AddClaim(guidGenerator, claim); |
|||
} |
|||
} |
|||
|
|||
public virtual void ReplaceClaim([NotNull] Claim claim, [NotNull] Claim newClaim) |
|||
{ |
|||
Check.NotNull(claim, nameof(claim)); |
|||
Check.NotNull(newClaim, nameof(newClaim)); |
|||
|
|||
var userClaims = Claims.Where(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type); |
|||
foreach (var userClaim in userClaims) |
|||
{ |
|||
userClaim.SetClaim(newClaim); |
|||
} |
|||
} |
|||
|
|||
public virtual void RemoveClaims([NotNull] IEnumerable<Claim> claims) |
|||
{ |
|||
Check.NotNull(claims, nameof(claims)); |
|||
|
|||
foreach (var claim in claims) |
|||
{ |
|||
RemoveClaim(claim); |
|||
} |
|||
} |
|||
|
|||
public virtual void RemoveClaim([NotNull] Claim claim) |
|||
{ |
|||
Check.NotNull(claim, nameof(claim)); |
|||
|
|||
Claims.RemoveAll(c => c.ClaimValue == claim.Value && c.ClaimType == claim.Type); |
|||
} |
|||
|
|||
public virtual void AddLogin([NotNull] UserLoginInfo login) |
|||
{ |
|||
Check.NotNull(login, nameof(login)); |
|||
|
|||
Logins.Add(new IdentityUserLogin(Id, login, TenantId)); |
|||
} |
|||
|
|||
public virtual void RemoveLogin([NotNull] string loginProvider, [NotNull] string providerKey) |
|||
{ |
|||
Check.NotNull(loginProvider, nameof(loginProvider)); |
|||
Check.NotNull(providerKey, nameof(providerKey)); |
|||
|
|||
Logins.RemoveAll(userLogin => userLogin.LoginProvider == loginProvider && userLogin.ProviderKey == providerKey); |
|||
} |
|||
|
|||
[CanBeNull] |
|||
public virtual IdentityUserToken FindToken(string loginProvider, string name) |
|||
{ |
|||
return Tokens.FirstOrDefault(t => t.LoginProvider == loginProvider && t.Name == name); |
|||
} |
|||
|
|||
public virtual void SetToken(string loginProvider, string name, string value) |
|||
{ |
|||
var token = FindToken(loginProvider, name); |
|||
if (token == null) |
|||
{ |
|||
Tokens.Add(new IdentityUserToken(Id, loginProvider, name, value, TenantId)); |
|||
} |
|||
else |
|||
{ |
|||
token.Value = value; |
|||
} |
|||
} |
|||
|
|||
public virtual void RemoveToken(string loginProvider, string name) |
|||
{ |
|||
Tokens.RemoveAll(t => t.LoginProvider == loginProvider && t.Name == name); |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return $"{base.ToString()}, UserName = {UserName}"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using System; |
|||
using System.Security.Claims; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a claim that a user possesses.
|
|||
/// </summary>
|
|||
public class IdentityUserClaim : IdentityClaim |
|||
{ |
|||
/// <summary>
|
|||
/// Gets or sets the primary key of the user associated with this claim.
|
|||
/// </summary>
|
|||
public virtual Guid UserId { get; protected set; } |
|||
|
|||
protected IdentityUserClaim() |
|||
{ |
|||
|
|||
} |
|||
|
|||
protected internal IdentityUserClaim(Guid id, Guid userId, [NotNull] Claim claim, Guid? tenantId) |
|||
: base(id, claim, tenantId) |
|||
{ |
|||
UserId = userId; |
|||
} |
|||
|
|||
protected internal IdentityUserClaim(Guid id, Guid userId, [NotNull] string claimType, string claimValue, Guid? tenantId) |
|||
: base(id, claimType, claimValue, tenantId) |
|||
{ |
|||
UserId = userId; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,76 @@ |
|||
using System; |
|||
using JetBrains.Annotations; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a login and its associated provider for a user.
|
|||
/// </summary>
|
|||
public class IdentityUserLogin : Entity, IMultiTenant |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the of the primary key of the user associated with this login.
|
|||
/// </summary>
|
|||
public virtual Guid UserId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the login provider for the login (e.g. facebook, google)
|
|||
/// </summary>
|
|||
public virtual string LoginProvider { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the unique provider identifier for this login.
|
|||
/// </summary>
|
|||
public virtual string ProviderKey { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the friendly name used in a UI for this login.
|
|||
/// </summary>
|
|||
public virtual string ProviderDisplayName { get; protected set; } |
|||
|
|||
protected IdentityUserLogin() |
|||
{ |
|||
|
|||
} |
|||
|
|||
protected internal IdentityUserLogin( |
|||
Guid userId, |
|||
[NotNull] string loginProvider, |
|||
[NotNull] string providerKey, |
|||
string providerDisplayName, |
|||
Guid? tenantId) |
|||
{ |
|||
Check.NotNull(loginProvider, nameof(loginProvider)); |
|||
Check.NotNull(providerKey, nameof(providerKey)); |
|||
|
|||
UserId = userId; |
|||
LoginProvider = loginProvider; |
|||
ProviderKey = providerKey; |
|||
ProviderDisplayName = providerDisplayName; |
|||
TenantId = tenantId; |
|||
} |
|||
|
|||
protected internal IdentityUserLogin( |
|||
Guid userId, |
|||
[NotNull] UserLoginInfo login, |
|||
Guid? tenantId) |
|||
: this( |
|||
userId, |
|||
login.LoginProvider, |
|||
login.ProviderKey, |
|||
login.ProviderDisplayName, |
|||
tenantId) |
|||
{ |
|||
} |
|||
|
|||
public UserLoginInfo ToUserLoginInfo() |
|||
{ |
|||
return new UserLoginInfo(LoginProvider, ProviderKey, ProviderDisplayName); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Domain.Services; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityUserManager : UserManager<IdentityUser>, IDomainService |
|||
{ |
|||
protected override CancellationToken CancellationToken => _cancellationTokenProvider.Token; |
|||
|
|||
private readonly ICancellationTokenProvider _cancellationTokenProvider; |
|||
|
|||
public IdentityUserManager( |
|||
IdentityUserStore store, |
|||
IOptions<IdentityOptions> optionsAccessor, |
|||
IPasswordHasher<IdentityUser> passwordHasher, |
|||
IEnumerable<IUserValidator<IdentityUser>> userValidators, |
|||
IEnumerable<IPasswordValidator<IdentityUser>> passwordValidators, |
|||
ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, |
|||
IServiceProvider services, |
|||
ILogger<IdentityUserManager> logger, |
|||
ICancellationTokenProvider cancellationTokenProvider) |
|||
: base( |
|||
store, |
|||
optionsAccessor, |
|||
passwordHasher, |
|||
userValidators, |
|||
passwordValidators, |
|||
keyNormalizer, |
|||
errors, |
|||
services, |
|||
logger) |
|||
{ |
|||
_cancellationTokenProvider = cancellationTokenProvider; |
|||
} |
|||
|
|||
public async Task<IdentityUser> GetByIdAsync(Guid id) |
|||
{ |
|||
var user = await Store.FindByIdAsync(id.ToString(), CancellationToken); |
|||
if (user == null) |
|||
{ |
|||
throw new EntityNotFoundException(typeof(IdentityUser), id); |
|||
} |
|||
|
|||
return user; |
|||
} |
|||
|
|||
public async Task<IdentityResult> SetRolesAsync([NotNull] IdentityUser user, [NotNull] IEnumerable<string> roleNames) |
|||
{ |
|||
Check.NotNull(user, nameof(user)); |
|||
Check.NotNull(roleNames, nameof(roleNames)); |
|||
|
|||
var currentRoleNames = await GetRolesAsync(user); |
|||
|
|||
var result = await RemoveFromRolesAsync(user, currentRoleNames.Except(roleNames).Distinct()); |
|||
if (!result.Succeeded) |
|||
{ |
|||
return result; |
|||
} |
|||
|
|||
result = await AddToRolesAsync(user, roleNames.Except(currentRoleNames).Distinct()); |
|||
if (!result.Succeeded) |
|||
{ |
|||
return result; |
|||
} |
|||
|
|||
return IdentityResult.Success; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class IdentityUserRepositoryExtensions |
|||
{ |
|||
public static IdentityUser FindByNormalizedUserName(this IIdentityUserRepository repository, [NotNull] string normalizedUserName) |
|||
{ |
|||
return AsyncHelper.RunSync(() => repository.FindByNormalizedUserNameAsync(normalizedUserName)); |
|||
} |
|||
|
|||
//TODO: Other sync extension methods
|
|||
} |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityUserRepositoryExternalUserLookupServiceProvider : IExternalUserLookupServiceProvider, ITransientDependency |
|||
{ |
|||
private readonly IIdentityUserRepository _userRepository; |
|||
private readonly ILookupNormalizer _lookupNormalizer; |
|||
|
|||
public IdentityUserRepositoryExternalUserLookupServiceProvider( |
|||
IIdentityUserRepository userRepository, |
|||
ILookupNormalizer lookupNormalizer) |
|||
{ |
|||
_userRepository = userRepository; |
|||
_lookupNormalizer = lookupNormalizer; |
|||
} |
|||
|
|||
public async Task<IUserData> FindByIdAsync( |
|||
Guid id, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return ( |
|||
await _userRepository.FindAsync( |
|||
id, |
|||
includeDetails: false, |
|||
cancellationToken: cancellationToken |
|||
) |
|||
).ToAbpUserData(); |
|||
} |
|||
|
|||
public async Task<IUserData> FindByUserNameAsync( |
|||
string userName, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return ( |
|||
await _userRepository.FindByNormalizedUserNameAsync( |
|||
_lookupNormalizer.Normalize(userName), |
|||
includeDetails: false, |
|||
cancellationToken: cancellationToken |
|||
) |
|||
).ToAbpUserData(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
/// <summary>
|
|||
/// Represents the link between a user and a role.
|
|||
/// </summary>
|
|||
public class IdentityUserRole : Entity, IMultiTenant |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the primary key of the user that is linked to a role.
|
|||
/// </summary>
|
|||
public virtual Guid UserId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the primary key of the role that is linked to the user.
|
|||
/// </summary>
|
|||
public virtual Guid RoleId { get; protected set; } |
|||
|
|||
protected IdentityUserRole() |
|||
{ |
|||
|
|||
} |
|||
|
|||
protected internal IdentityUserRole(Guid userId, Guid roleId, Guid? tenantId) |
|||
{ |
|||
UserId = userId; |
|||
RoleId = roleId; |
|||
TenantId = tenantId; |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,57 @@ |
|||
using System; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
/// <summary>
|
|||
/// Represents an authentication token for a user.
|
|||
/// </summary>
|
|||
public class IdentityUserToken : Entity, IMultiTenant |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the primary key of the user that the token belongs to.
|
|||
/// </summary>
|
|||
public virtual Guid UserId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the LoginProvider this token is from.
|
|||
/// </summary>
|
|||
public virtual string LoginProvider { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the name of the token.
|
|||
/// </summary>
|
|||
public virtual string Name { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the token value.
|
|||
/// </summary>
|
|||
public virtual string Value { get; set; } |
|||
|
|||
protected IdentityUserToken() |
|||
{ |
|||
|
|||
} |
|||
|
|||
protected internal IdentityUserToken( |
|||
Guid userId, |
|||
[NotNull] string loginProvider, |
|||
[NotNull] string name, |
|||
string value, |
|||
Guid? tenantId) |
|||
{ |
|||
Check.NotNull(loginProvider, nameof(loginProvider)); |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
UserId = userId; |
|||
LoginProvider = loginProvider; |
|||
Name = name; |
|||
Value = value; |
|||
TenantId = tenantId; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,57 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.PermissionManagement; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class RolePermissionManagementProvider : PermissionManagementProvider |
|||
{ |
|||
public override string Name => RolePermissionValueProvider.ProviderName; |
|||
|
|||
private readonly IIdentityUserRepository _identityUserRepository; |
|||
|
|||
public RolePermissionManagementProvider( |
|||
IPermissionGrantRepository permissionGrantRepository, |
|||
IGuidGenerator guidGenerator, |
|||
IIdentityUserRepository identityUserRepository, |
|||
ICurrentTenant currentTenant) |
|||
: base( |
|||
permissionGrantRepository, |
|||
guidGenerator, |
|||
currentTenant) |
|||
{ |
|||
_identityUserRepository = identityUserRepository; |
|||
} |
|||
|
|||
public override async Task<PermissionValueProviderGrantInfo> CheckAsync(string name, string providerName, string providerKey) |
|||
{ |
|||
if (providerName == Name) |
|||
{ |
|||
return new PermissionValueProviderGrantInfo( |
|||
await PermissionGrantRepository.FindAsync(name, providerName, providerKey) != null, |
|||
providerKey |
|||
); |
|||
} |
|||
|
|||
if (providerName == "User") |
|||
{ |
|||
var userId = Guid.Parse(providerKey); |
|||
var roleNames = await _identityUserRepository.GetRoleNamesAsync(userId); |
|||
|
|||
foreach (var roleName in roleNames) |
|||
{ |
|||
var permissionGrant = await PermissionGrantRepository.FindAsync(name, Name, roleName); |
|||
if (permissionGrant != null) |
|||
{ |
|||
return new PermissionValueProviderGrantInfo(true, roleName); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return PermissionValueProviderGrantInfo.NonGranted; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.PermissionManagement; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class UserPermissionManagementProvider : PermissionManagementProvider |
|||
{ |
|||
public override string Name => UserPermissionValueProvider.ProviderName; |
|||
|
|||
public UserPermissionManagementProvider(IPermissionGrantRepository |
|||
permissionGrantRepository, |
|||
IGuidGenerator guidGenerator, |
|||
ICurrentTenant currentTenant) |
|||
: base( |
|||
permissionGrantRepository, |
|||
guidGenerator, |
|||
currentTenant) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.PermissionManagement; |
|||
|
|||
namespace Volo.Abp.Permissions |
|||
{ |
|||
public static class RolePermissionManagerExtensions |
|||
{ |
|||
public static Task<PermissionWithGrantedProviders> GetForRoleAsync([NotNull] this IPermissionManager permissionManager, string roleName, string permissionName) |
|||
{ |
|||
Check.NotNull(permissionManager, nameof(permissionManager)); |
|||
|
|||
return permissionManager.GetAsync(permissionName, RolePermissionValueProvider.ProviderName, roleName); |
|||
} |
|||
|
|||
public static Task<List<PermissionWithGrantedProviders>> GetAllForRoleAsync([NotNull] this IPermissionManager permissionManager, string roleName) |
|||
{ |
|||
Check.NotNull(permissionManager, nameof(permissionManager)); |
|||
|
|||
return permissionManager.GetAllAsync(RolePermissionValueProvider.ProviderName, roleName); |
|||
} |
|||
|
|||
public static Task SetForRoleAsync([NotNull] this IPermissionManager permissionManager, string roleName, [NotNull] string permissionName, bool isGranted) |
|||
{ |
|||
Check.NotNull(permissionManager, nameof(permissionManager)); |
|||
|
|||
return permissionManager.SetAsync(permissionName, RolePermissionValueProvider.ProviderName, roleName, isGranted); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.PermissionManagement; |
|||
|
|||
namespace Volo.Abp.Permissions |
|||
{ |
|||
public static class UserPermissionManagerExtensions |
|||
{ |
|||
public static Task<List<PermissionWithGrantedProviders>> GetAllForUserAsync([NotNull] this IPermissionManager permissionManager, Guid userId) |
|||
{ |
|||
Check.NotNull(permissionManager, nameof(permissionManager)); |
|||
|
|||
return permissionManager.GetAllAsync(UserPermissionValueProvider.ProviderName, userId.ToString()); |
|||
} |
|||
|
|||
public static Task SetForUserAsync([NotNull] this IPermissionManager permissionManager, Guid userId, [NotNull] string name, bool isGranted) |
|||
{ |
|||
Check.NotNull(permissionManager, nameof(permissionManager)); |
|||
|
|||
return permissionManager.SetAsync(name, UserPermissionValueProvider.ProviderName, userId.ToString(), isGranted); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System.Reflection; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
// General Information about an assembly is controlled through the following
|
|||
// set of attributes. Change these attribute values to modify the information
|
|||
// associated with an assembly.
|
|||
[assembly: AssemblyConfiguration("")] |
|||
[assembly: AssemblyCompany("")] |
|||
[assembly: AssemblyProduct("Volo.Abp.Identity.EntityFrameworkCore")] |
|||
[assembly: AssemblyTrademark("")] |
|||
|
|||
// Setting ComVisible to false makes the types in this assembly not visible
|
|||
// to COM components. If you need to access a type in this assembly from
|
|||
// COM, set the ComVisible attribute to true on that type.
|
|||
[assembly: ComVisible(false)] |
|||
|
|||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|||
[assembly: Guid("439dfc0f-1ba2-464f-900e-ea7e18c08975")] |
|||
@ -0,0 +1,22 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Identity.EntityFrameworkCore</AssemblyName> |
|||
<PackageId>Volo.Abp.Identity.EntityFrameworkCore</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.Identity.Domain\Volo.Abp.Identity.Domain.csproj" /> |
|||
|
|||
<ProjectReference Include="..\..\..\abp-users\src\Volo.Abp.Users.EntityFrameworkCore\Volo.Abp.Users.EntityFrameworkCore.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,2 @@ |
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> |
|||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp71</s:String></wpf:ResourceDictionary> |
|||
@ -0,0 +1,23 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Users.EntityFrameworkCore; |
|||
|
|||
namespace Volo.Abp.Identity.EntityFrameworkCore |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpIdentityDomainModule), |
|||
typeof(AbpUsersEntityFrameworkCoreModule))] |
|||
public class AbpIdentityEntityFrameworkCoreModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.AddAbpDbContext<IdentityDbContext>(options => |
|||
{ |
|||
options.AddRepository<IdentityUser, EfCoreIdentityUserRepository>(); |
|||
options.AddRepository<IdentityRole, EfCoreIdentityRoleRepository>(); |
|||
}); |
|||
|
|||
services.AddAssemblyOf<AbpIdentityEntityFrameworkCoreModule>(); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue