public void SetUp() { var services = new ServiceCollection(); services.AddServiceInjection(); ServiceInjection.Register(new List <Assembly>() { Assembly.GetAssembly(typeof(WebApi.Startup)) }); services.AddScoped <UsersController>(); // mocks _validModel = new AuthorizationGrantModel { username = "******", password = "******", }; _invalidModel = new AuthorizationGrantModel { username = "******", password = DateTime.Now.ToString(), }; _anonymous = new ClaimsPrincipal(); var identityServiceMock = new Mock <IIdentityService>(); identityServiceMock.Setup(o => o.ValidateLogin(It.IsAny <ClaimsPrincipal>(), It.IsAny <AuthorizationGrantModel>())) .Returns(new ValidationData()); identityServiceMock.Setup(o => o.AuthenticateAsync( It.Is <string>(u => u == _validModel.username), It.Is <string>(p => p == _validModel.password))) .Returns(Task.FromResult(new AppUser())); identityServiceMock.Setup(o => o.GetIdentityAsync(It.IsAny <AppUser>(), It.IsAny <string>())) .Returns(Task.FromResult(new ClaimsIdentity())); identityServiceMock.Setup(o => o.GenerateTokenResponse(It.IsAny <ClaimsPrincipal>(), It.IsAny <AuthenticationProperties>(), It.IsAny <string>())) .Returns(new TokenResponseModel()); var dbContextMock = Mock.Of <DbContext>(); services.AddScoped(p => identityServiceMock.Object); services.AddScoped(p => dbContextMock); _provider = services.BuildServiceProvider(); }
public async Task <IActionResult> LogIn([FromForm] AuthorizationGrantModel model) { var validationData = _service.ValidateLogin(User, model); if (!validationData.IsValid) { return(BadRequest(AppResult.FailValidation(data: validationData))); } AppUser entity = null; switch (model.grant_type) { case "password": case null: { entity = await _service.AuthenticateAsync(model.username, model.password); if (entity == null) { return(Unauthorized(AppResult .Unauthorized(mess: "Invalid username or password"))); } } break; case "refresh_token": { var validResult = _service.ValidateRefreshToken(model.refresh_token); if (validResult == null) { return(Unauthorized(AppResult .Unauthorized(mess: "Invalid refresh token"))); } entity = await _service.GetUserByIdAsync(validResult.Identity.Name); if (entity == null) { return(Unauthorized(AppResult .Unauthorized(mess: "Invalid user identity"))); } } break; default: return(BadRequest(AppResult .Unsupported("Unsupported grant type"))); } var identity = await _service.GetIdentityAsync(entity, JwtBearerDefaults.AuthenticationScheme); var principal = new ClaimsPrincipal(identity); var utcNow = DateTime.UtcNow; var props = new AuthenticationProperties() { IssuedUtc = utcNow, ExpiresUtc = utcNow.AddHours(WebApi.Settings.Instance.TokenValidHours) }; props.Parameters["refresh_expires"] = utcNow.AddHours( WebApi.Settings.Instance.RefreshTokenValidHours); var resp = _service.GenerateTokenResponse(principal, props, model.scope); _logger.CustomProperties(entity).Info("Login user"); return(Ok(resp)); }
public ValidationData ValidateLogin( ClaimsPrincipal principal, AuthorizationGrantModel model) { return(new ValidationData()); }
public async Task <IActionResult> LogIn(AuthorizationGrantModel model) { var validationData = _service.ValidateLogin(User, model); if (!validationData.IsValid) { return(BadRequest(AppResult.FailValidation(data: validationData))); } AppUser entity; switch (model.grant_type) { case "password": case null: { entity = await _service.AuthenticateAsync(model.username, model.password); if (entity == null) { return(Unauthorized(AppResult .Unauthorized(mess: "Invalid username or password"))); } } break; case "refresh_token": { var validResult = _service.ValidateRefreshToken(model.refresh_token); if (validResult == null) { return(Unauthorized(AppResult .Unauthorized(mess: "Invalid refresh token"))); } entity = await _service.GetUserByIdAsync(validResult.Identity.Name); if (entity == null) { return(Unauthorized(AppResult .Unauthorized(mess: "Invalid user identity"))); } } break; case "firebase_token": { FirebaseToken validResult = await _service.ValidateFirebaseToken(model.firebase_token); if (validResult == null) { return(Unauthorized(AppResult .Unauthorized(mess: "Invalid Firebase token"))); } UserRecord userRecord = await FirebaseAuth.DefaultInstance.GetUserAsync(validResult.Uid); bool checkEmailDomain = _service.ValidateEmailDomain(userRecord.Email); if (!checkEmailDomain) { return(Unauthorized(AppResult.InvalidEmailDomain())); } entity = await _service.GetUserByEmailAsync(userRecord.Email); var userExisted = entity != null; if (!userExisted || !entity.LoggedIn) { using (var transaction = context.Database.BeginTransaction()) { Member memberEntity; if (!userExisted) { var emailInfo = userRecord.Email.GetEmailInfo(); entity = _service.ConvertToUser(userRecord, emailInfo.Item3); var result = await _service .CreateUserWithoutPassAsync(entity); if (!result.Succeeded) { foreach (var err in result.Errors) { ModelState.AddModelError(err.Code, err.Description); } var builder = ResultHelper.MakeInvalidAccountRegistrationResults(ModelState); return(BadRequest(builder)); } _logger.CustomProperties(entity).Info("Register new user"); memberEntity = _memberService.ConvertToMember(entity, entity.MemberCode); memberEntity = _memberService.CreateMember(memberEntity); } else { entity = _service.UpdateUser(entity, userRecord); var result = await _service.UpdateUserAsync(entity); if (!result.Succeeded) { foreach (var err in result.Errors) { ModelState.AddModelError(err.Code, err.Description); } var builder = ResultHelper.MakeInvalidAccountRegistrationResults(ModelState); return(BadRequest(builder)); } memberEntity = _memberService.Members.Id(entity.Id).FirstOrDefault(); memberEntity = _memberService.UpdateMember(memberEntity, entity); } //log event var ev = _sysService.GetEventForNewUser( $"{memberEntity.Email} has logged into system for the first time", memberEntity.UserId); _sysService.CreateAppEvent(ev); //end log event context.SaveChanges(); transaction.Commit(); } } } break; default: return(BadRequest(AppResult.Unsupported("Unsupported grant type"))); } var identity = await _service.GetIdentityAsync(entity, JwtBearerDefaults.AuthenticationScheme); var principal = new ClaimsPrincipal(identity); var utcNow = DateTime.UtcNow; var props = new AuthenticationProperties() { IssuedUtc = utcNow, ExpiresUtc = utcNow.AddHours(WebApi.Settings.Instance.TokenValidHours) }; props.Parameters["refresh_expires"] = utcNow.AddHours( WebApi.Settings.Instance.RefreshTokenValidHours); var resp = _service.GenerateTokenResponse(principal, props, model.scope ?? AppOAuthScope.ROLES); _logger.CustomProperties(entity).Info("Login user"); return(Ok(resp)); }
public ValidationResult ValidateLogin( ClaimsPrincipal principal, AuthorizationGrantModel model) { return(ValidationResult.Pass()); }
public async Task <IActionResult> LogIn([FromForm] AuthorizationGrantModel model) { var validationResult = _service.ValidateLogin(User, model); if (!validationResult.Valid) { return(BadRequest(validationResult.Result)); } AppUser entity = null; switch (model.grant_type) { case "password": case null: { entity = await _service.AuthenticateAsync(model.username, model.password); if (entity == null) { return(Unauthorized(new AppResultBuilder() .Unauthorized(mess: "Invalid username or password"))); } } break; case "refresh_token": { var validResult = _service.ValidateRefreshToken(model.refresh_token); if (validResult == null) { return(Unauthorized(new AppResultBuilder() .Unauthorized(mess: "Invalid refresh token"))); } entity = await _service.GetUserByIdAsync(validResult.Identity.Name); if (entity == null) { return(Unauthorized(new AppResultBuilder() .Unauthorized(mess: "Invalid user identity"))); } } break; default: return(BadRequest(new AppResultBuilder() .Unsupported("Unsupported grant type"))); } var identity = await _service.GetIdentityAsync(entity, JwtBearerDefaults.AuthenticationScheme); var principal = new ClaimsPrincipal(identity); var utcNow = DateTime.UtcNow; var props = new AuthenticationProperties() { IssuedUtc = utcNow, ExpiresUtc = utcNow.AddHours(WebApi.Settings.Instance.TokenValidHours) }; props.Parameters["refresh_expires"] = utcNow.AddHours( WebApi.Settings.Instance.RefreshTokenValidHours); var resp = _service.GenerateTokenResponse(principal, props, model.scope); _logger.CustomProperties(entity).Info("Login user"); if (principal.IsInRole(RoleName.Device)) { if (model.fcm_token == null) { return(BadRequest(new AppResultBuilder() .FailValidation(mess: "FCM Token is required for device login"))); } using (var trans = context.Database.BeginTransaction()) { var device = _deviceService.Devices.Id(entity.Id).FirstOrDefault(); var oldFcmToken = device.CurrentFcmToken; _deviceService.ChangeDeviceToken(device, model.fcm_token, resp.access_token); context.SaveChanges(); _service.LoginDevice(device, oldFcmToken, model.fcm_token); trans.Commit(); } } return(Ok(resp)); }
public JsonResult Index(AuthorizationGrantModel model) { try { if (model.grant_type == "authorization_code") { //Validate the code is used only once var client = clientRepo.GetClient(model.client_id); if (client == null) { return(Json(new { error = "invalid_request" }, JsonRequestBehavior.AllowGet)); } if (!client.ClientSecret.Equals(model.client_secret)) { return(Json(new { error = "invalid_client" }, JsonRequestBehavior.AllowGet)); } var code = codeRepo.GetAuthorizationCode(model.code); if (code == null) { return(Json(new { error = "invalid_grant" }, JsonRequestBehavior.AllowGet)); } if (!code.ClientID.Equals(client.ClientID)) { return(Json(new { error = "unauthorized_client" }, JsonRequestBehavior.AllowGet)); } //Validate Uri match the client url registered if (!string.IsNullOrEmpty(code.Redirect_Uri) && !code.Redirect_Uri.Equals(model.redirect_uri)) { return(Json(new { error = "invalid_request" }, JsonRequestBehavior.AllowGet)); } //Valid var key = Convert.FromBase64String(client.ClientSecret); var provider = new System.Security.Cryptography.HMACSHA256(key); var UserID = code.UserID; var rawTokenInfo = string.Concat(code.Code, client.ClientSecret, UserID, DateTime.UtcNow.ToString("hhmmss")); var rawTokenByte = Encoding.UTF8.GetBytes(rawTokenInfo); var token = provider.ComputeHash(rawTokenByte); var rawRefreeshInfo = string.Concat(code.Code, client.ClientSecret, DateTime.UtcNow.ToString("hhmmss")); var rawRefreshByte = Encoding.UTF8.GetBytes(rawRefreeshInfo); var refresh = provider.ComputeHash(rawRefreshByte); var accessToken = new AccessToken() { ClientID = model.client_id, UserID = UserID, Token = Convert.ToBase64String(token), Type = "bearer", Expiration = DateTime.Now.AddDays(1), RefreshToken = Convert.ToBase64String(refresh), Scope = string.Empty }; if (tokenRepo.Save(accessToken)) { return(Json(new AccessTokenModel(accessToken), JsonRequestBehavior.AllowGet)); } } if (model.grant_type == "refresh_token" && !string.IsNullOrEmpty(model.refresh_token)) { //Validate the code is used only once var client = clientRepo.GetClient(model.client_id); if (client == null) { return(Json(new { error = "invalid_request" }, JsonRequestBehavior.AllowGet)); } if (!client.ClientSecret.Equals(model.client_secret)) { return(Json(new { error = "invalid_client" }, JsonRequestBehavior.AllowGet)); } var oldToken = tokenRepo.GetRefreshToken(model.refresh_token); if (oldToken == null) { return(Json(new { error = "invalid_grant" }, JsonRequestBehavior.AllowGet)); } if (!oldToken.ClientID.Equals(client.ClientID)) { return(Json(new { error = "unauthorized_client" }, JsonRequestBehavior.AllowGet)); } //Valid var key = Convert.FromBase64String(client.ClientSecret); var provider = new System.Security.Cryptography.HMACSHA256(key); var UserID = oldToken.UserID; var rawTokenInfo = string.Concat(oldToken.Token, client.ClientSecret, DateTime.UtcNow.ToString("hhmmss")); var rawTokenByte = Encoding.UTF8.GetBytes(rawTokenInfo); var token = provider.ComputeHash(rawTokenByte); var accessToken = new AccessToken() { ClientID = model.client_id, UserID = UserID, Token = Convert.ToBase64String(token), Type = "bearer", Expiration = DateTime.Now.AddDays(1), RefreshToken = string.Empty, Scope = string.Empty }; if (tokenRepo.Save(accessToken)) { return(Json(new AccessTokenModel(accessToken), JsonRequestBehavior.AllowGet)); } } } catch { return(Json(new { error = "invalid_request" }, JsonRequestBehavior.AllowGet)); } return(Json(new { error = "invalid_request" }, JsonRequestBehavior.AllowGet)); }