using System; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using System.Web.Http; using Abp.UI; using Abp.Web.Models; using Abp.WebApi.Controllers; using IwbZero.Authorization; using Microsoft.Extensions.Internal; using Microsoft.Owin.Security; using Microsoft.Owin.Security.OAuth; using ShwasherSys.Authorization; using ShwasherSys.Authorization.Users; namespace ShwasherSys.Api.Controllers { public class AccountController : AbpApiController { public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; } private readonly LogInManager _logInManager; static AccountController() { OAuthBearerOptions = new OAuthBearerAuthenticationOptions(); } public AccountController(LogInManager logInManager) { _logInManager = logInManager; LocalizationSourceName = ShwasherConsts.LocalizationSourceName; } [HttpPost] public async Task Authenticate(LoginModel loginModel) { CheckModelState(); var loginResult = await GetLoginResultAsync( loginModel.UsernameOrEmailAddress, loginModel.Password ); var ticket = new AuthenticationTicket(loginResult.Identity, new AuthenticationProperties()); var currentUtc = new SystemClock().UtcNow; ticket.Properties.IssuedUtc = currentUtc; ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30)); return new AjaxResponse(OAuthBearerOptions.AccessTokenFormat.Protect(ticket)); } private async Task> GetLoginResultAsync(string usernameOrEmailAddress, string password) { var loginResult = await _logInManager.LoginAsync(usernameOrEmailAddress, password); switch (loginResult.Result) { case AbpLoginResultType.Success: return loginResult; default: throw CreateExceptionForFailedLoginAttempt(loginResult.Result, usernameOrEmailAddress); } } private Exception CreateExceptionForFailedLoginAttempt(AbpLoginResultType result, string usernameOrEmailAddress) { switch (result) { case AbpLoginResultType.Success: return new ApplicationException("Don't call this method with a success result!"); case AbpLoginResultType.InvalidUserNameOrEmailAddress: case AbpLoginResultType.InvalidPassword: return new UserFriendlyException(L("LoginFailed"), L("InvalidUserNameOrPassword")); // case AbpLoginResultType.InvalidTenancyName: // return new UserFriendlyException(L("LoginFailed"), L("ThereIsNoTenantDefinedWithName{0}", tenancyName)); // case AbpLoginResultType.TenantIsNotActive: // return new UserFriendlyException(L("LoginFailed"), L("TenantIsNotActive", tenancyName)); case AbpLoginResultType.UserIsNotActive: return new UserFriendlyException(L("LoginFailed"), L("UserIsNotActiveAndCanNotLogin", usernameOrEmailAddress)); case AbpLoginResultType.UserEmailIsNotConfirmed: return new UserFriendlyException(L("LoginFailed"), "Your email address is not confirmed. You can not login"); //TODO: localize message default: //Can not fall to default actually. But other result types can be added in the future and we may forget to handle it Logger.Warn("Unhandled login fail reason: " + result); return new UserFriendlyException(L("LoginFailed")); } } protected virtual void CheckModelState() { if (!ModelState.IsValid) { throw new UserFriendlyException("Invalid request!"); } } } } namespace ShwasherSys { public class LoginModel { [Required] public string UsernameOrEmailAddress { get; set; } [Required] public string Password { get; set; } // public bool RememberMe { get; set; } //public string TenancyName { get; set; } } }