mirror of https://github.com/abpframework/abp.git
30 changed files with 557 additions and 54 deletions
@ -0,0 +1,20 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Account.Application.Contracts</AssemblyName> |
|||
<PackageId>Volo.Abp.Account.Application.Contracts</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\Volo.Abp.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,13 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.Account |
|||
{ |
|||
public class AbpAccountApplicationContractsModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.AddAssemblyOf<AbpAccountApplicationContractsModule>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace Volo.Abp.Account |
|||
{ |
|||
public interface ILoginAppService : IApplicationService |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Account.Application</AssemblyName> |
|||
<PackageId>Volo.Abp.Account.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.Account.Application.Contracts\Volo.Abp.Account.Application.Contracts.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,14 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.Account |
|||
{ |
|||
[DependsOn(typeof(AbpAccountApplicationContractsModule))] |
|||
public class AbpAccountApplicationModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.AddAssemblyOf<AbpAccountApplicationModule>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace Volo.Abp.Account |
|||
{ |
|||
public class LoginAppService : ILoginAppService |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
using System.Reflection; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; |
|||
using Volo.Abp.EmbeddedFiles; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.Account.Web |
|||
{ |
|||
[DependsOn(typeof(AbpIdentityDomainModule))] |
|||
[DependsOn(typeof(AbpAspNetCoreMvcUiBootstrapModule))] |
|||
[DependsOn(typeof(AbpAccountApplicationContractsModule))] |
|||
public class AbpAccountWebModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.AddAssemblyOf<AbpAccountWebModule>(); |
|||
|
|||
services.Configure<EmbeddedFileOptions>(options => |
|||
{ |
|||
options.Sources.Add( |
|||
new EmbeddedFileSet( |
|||
"/Areas/", |
|||
GetType().GetTypeInfo().Assembly, |
|||
"Volo.Abp.Account.Web.Areas" |
|||
) |
|||
); |
|||
|
|||
options.Sources.Add( |
|||
new EmbeddedFileSet( |
|||
"/", |
|||
GetType().GetTypeInfo().Assembly, |
|||
"Volo.Abp.Account.Web.wwwroot" |
|||
) |
|||
); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,58 @@ |
|||
using System; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Ui; |
|||
|
|||
namespace Volo.Abp.Account.Web.Areas.Account.Controllers |
|||
{ |
|||
public abstract class AccountControllerBase : AbpController |
|||
{ |
|||
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.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(); |
|||
} |
|||
|
|||
private string GetAppHomeUrl() |
|||
{ |
|||
return "/"; //TODO: ???
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.Account.Web.Areas.Account.Models.Login; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Ui; |
|||
|
|||
namespace Volo.Abp.Account.Web.Areas.Account.Controllers |
|||
{ |
|||
[Area("Account")] |
|||
public class LoginController : AccountControllerBase |
|||
{ |
|||
private readonly SignInManager<IdentityUser> _signInManager; |
|||
|
|||
public LoginController(SignInManager<IdentityUser> signInManager) |
|||
{ |
|||
_signInManager = signInManager; |
|||
} |
|||
|
|||
public IActionResult Index() |
|||
{ |
|||
return View(); |
|||
} |
|||
|
|||
[HttpPost] |
|||
public async Task<IActionResult> Index(LoginModel loginModel, string returnUrl = "", string returnUrlHash = "") |
|||
{ |
|||
if (!ModelState.IsValid) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
var result = await _signInManager.PasswordSignInAsync( |
|||
loginModel.UserNameOrEmailAddress, |
|||
loginModel.Password, |
|||
loginModel.RememberMe, |
|||
true |
|||
); |
|||
|
|||
if (!result.Succeeded) |
|||
{ |
|||
throw new UserFriendlyException("Login failed!"); //TODO: Handle other cases, do not throw exception
|
|||
} |
|||
|
|||
return RedirectSafely(returnUrl, returnUrlHash); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace Volo.Abp.Account.Web.Areas.Account.Controllers |
|||
{ |
|||
[Area("Account")] |
|||
public class LogoutController : AccountControllerBase |
|||
{ |
|||
private readonly SignInManager<IdentityUser> _signInManager; |
|||
|
|||
public LogoutController(SignInManager<IdentityUser> signInManager) |
|||
{ |
|||
_signInManager = signInManager; |
|||
} |
|||
|
|||
public async Task<IActionResult> Index() |
|||
{ |
|||
await _signInManager.SignOutAsync(); |
|||
|
|||
return RedirectToAction("Index", "Login"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.Account.Web.Areas.Account.Models.Register; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace Volo.Abp.Account.Web.Areas.Account.Controllers |
|||
{ |
|||
[Area("Account")] |
|||
public class RegisterController : AccountControllerBase |
|||
{ |
|||
private readonly IdentityUserManager _userManager; |
|||
private readonly SignInManager<IdentityUser> _signInManager; |
|||
|
|||
public RegisterController(IdentityUserManager userManager, SignInManager<IdentityUser> signInManager) |
|||
{ |
|||
_userManager = userManager; |
|||
_signInManager = signInManager; |
|||
} |
|||
|
|||
public IActionResult Index() |
|||
{ |
|||
return View(); |
|||
} |
|||
|
|||
[HttpPost] |
|||
//TODO: [ValidateAntiForgeryToken]
|
|||
public async Task<IActionResult> Index(RegisterModel registerModel, string returnUrl = "", string returnUrlHash = "") |
|||
{ |
|||
if (!ModelState.IsValid) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
var user = new IdentityUser(GuidGenerator.Create(), registerModel.UserName); |
|||
|
|||
var result = await _userManager.CreateAsync(user, registerModel.Password); |
|||
|
|||
if (!result.Succeeded) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
await _userManager.SetEmailAsync(user, registerModel.EmailAddress); |
|||
|
|||
await _signInManager.SignInAsync(user, isPersistent: false); |
|||
|
|||
return RedirectSafely(returnUrl, returnUrlHash); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Volo.Abp.Account.Web.Areas.Account.Models.Login |
|||
{ |
|||
public class LoginModel |
|||
{ |
|||
[Required] |
|||
[MaxLength(255)] |
|||
public string UserNameOrEmailAddress { get; set; } |
|||
|
|||
[Required] |
|||
[MaxLength(32)] |
|||
public string Password { get; set; } |
|||
|
|||
public bool RememberMe { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Volo.Abp.Account.Web.Areas.Account.Models.Register |
|||
{ |
|||
public class RegisterModel |
|||
{ |
|||
[Required] |
|||
[MaxLength(32)] |
|||
public string UserName { get; set; } |
|||
|
|||
[Required] |
|||
[EmailAddress] |
|||
[MaxLength(255)] |
|||
public string EmailAddress { get; set; } |
|||
|
|||
[Required] |
|||
[MaxLength(32)] |
|||
public string Password { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
<div class="row"> |
|||
<div class="col-md-3"> |
|||
<form asp-action="Index" method="post"> |
|||
<div class="form-group"> |
|||
<label for="UsernameOrEmailAddress">Username or email address</label> |
|||
<input type="text" class="form-control" id="UsernameOrEmailAddress" name="UsernameOrEmailAddress"> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label for="Password">Password</label> |
|||
<input type="password" class="form-control" id="Password" name="Password"> |
|||
</div> |
|||
<div class="form-check"> |
|||
<label class="form-check-label"> |
|||
<input type="checkbox" name="RememberMe" value="true" checked="checked"> |
|||
Remember me |
|||
</label> |
|||
</div> |
|||
<button type="submit" class="btn btn-primary">Login</button> |
|||
</form> |
|||
|
|||
<div> |
|||
<a href="@Url.Action("Index", "Register", new { returnUrl = Context.Request.Query["returnUrl"], returnUrlHash = Context.Request.Query["returnUrlHash"] })">Register</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
@ -0,0 +1,19 @@ |
|||
<div class="row"> |
|||
<div class="col-md-3"> |
|||
<form asp-action="Index" method="post"> |
|||
<div class="form-group"> |
|||
<label for="UserName">Username</label> |
|||
<input type="text" class="form-control" id="UserName" name="UserName" required> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label for="EmailAddress">Email address</label> |
|||
<input type="email" class="form-control" id="EmailAddress" name="EmailAddress" required> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label for="Password">Password</label> |
|||
<input type="password" class="form-control" id="Password" name="Password" required> |
|||
</div> |
|||
<button type="submit" class="btn btn-primary">Register</button> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
@ -0,0 +1,30 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Account.Web</AssemblyName> |
|||
<PackageId>Volo.Abp.Account.Web</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace>Volo.Abp.Account.Web</RootNamespace> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="Areas\**\*.*" Exclude="bin\**;obj\**;**\*.xproj;packages\**;@(EmbeddedResource)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.Account.Application.Contracts\Volo.Abp.Account.Application.Contracts.csproj" /> |
|||
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.csproj" /> |
|||
<ProjectReference Include="..\Volo.Abp.Identity.Domain\Volo.Abp.Identity.Domain.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Folder Include="wwwroot\" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,44 @@ |
|||
using System; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
//TODO: AspNetUserManager overrides CancellationToken so we can make same functionality available!
|
|||
|
|||
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 TODO: We may need to add this in order to ValidateAsync principal!
|
|||
//services.TryAddScoped<AbpSecurityStampValidator<TTenant, TRole, TUser>>();
|
|||
//services.TryAddScoped(typeof(SecurityStampValidator<TUser>), provider => provider.GetService(typeof(AbpSecurityStampValidator<TTenant, TRole, TUser>)));
|
|||
//services.TryAddScoped(typeof(ISecurityStampValidator), provider => provider.GetService(typeof(AbpSecurityStampValidator<TTenant, TRole, TUser>)));
|
|||
|
|||
//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); |
|||
//return services.AddIdentityCore<IdentityUser>(setupAction);
|
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue