[AllowAnonymous] // need to allow login from an unathenticated state public virtual async Task <IActionResult> AdminLogin([FromBody] AdminLoginEvent model) { // The eventual user var validatedUser = _context.Admins.OfType <WebAdmin>().FirstOrDefault(x => x.Email.ToLower() == model.Email.ToLower()); if (validatedUser == null) { // Our response is vague to avoid leaking information return(ResponseShell.Error("Invalid")); } var passCheck = validatedUser.VerifyPassowrd(model.Password); if (passCheck != PasswordVerificationResult.Success) { // Our response is vague to avoid leaking information return(ResponseShell.Error("Invalid")); } // Get our token var token = await _tokenService.GetToken(validatedUser); return(ResponseShell.Ok(token)); // return Redirect($"{_config.Urls.Frontend}/{_config.Pages.AdminPage}?user={token.UserId}&token={token.Token}"); }
public override void OnActionExecuting(ActionExecutingContext context) { if (!context.ModelState.IsValid) { context.Result = ResponseShell.Error(Constants.StatusCodes.ModelErrorStatusCode, Constants.Messages.InvalidModelMsg, context.ModelState); } }
public virtual async Task <IActionResult> ResendValidation([FromBody] ResendValidateUser tempUser) { var user = _context.Users.FirstOrDefault(u => u.Id == tempUser.Id); if (user == null) { // Our response is vague to avoid leaking information return(ResponseShell.Error("Could not find an account with that information")); } if (!string.IsNullOrWhiteSpace(tempUser.Email) && !user.ValidatedEmail) { Log.Information("Sending Email Validation to {user}", tempUser.Email); var temp = new TempUser(user); await _validation.SendValidationToEmail(temp); _memoryCache.SetForChallenge(temp); } if (!string.IsNullOrWhiteSpace(tempUser.PhoneNumber) && !user.ValidatedSms) { tempUser.PhoneNumber = tempUser.PhoneNumber.CleanPhone(); Log.Information("Sending SMS Validation to {user}", tempUser.PhoneNumber); var temp = new TempUser(user); await _validation.SendValidationToSms(temp); _memoryCache.SetForChallenge(temp); } return(ResponseShell.Ok()); }
public virtual async Task <IActionResult> UserLogin([FromBody] UserLoginEvent model) { // The eventual user var validatedUser = _context.AllUsers.Where(u => u.Enabled).FirstOrDefault(x => x.Email == model.ContactInfo || x.PhoneNumber == model.ContactInfo.CleanPhone()); if (validatedUser == null) { // Our response is vague to avoid leaking information return(ResponseShell.Error("Could not find an account with that information")); } var passCheck = validatedUser.VerifyPassowrd(model.Password); if (passCheck != PasswordVerificationResult.Success) { return(ResponseShell.Error("Could not find an account with that information")); } // Get our token var token = await _tokenService.GetToken(validatedUser); // overloading the login for webadmins too if (validatedUser is WebAdmin) { return(ResponseShell.Ok($"{_config.Urls.Frontend}/{_config.Pages.AdminPage}?user={token.UserId}&token={token.Token}")); } return(ResponseShell.Ok($"{_config.Urls.Frontend}/{_config.Pages.AccountPage}?user={token.UserId}&token={token.Token}")); }
public virtual async Task <IActionResult> GetAll([FromQuery] Pagination pagination) { var users = _context.Users.OfType <GenericUser>(); var fetchedUsers = await pagination.SkipAndTake(users).ToListAsync(); return(ResponseShell.Ok(fetchedUsers)); }
public virtual IActionResult CreateNotification([FromBody] CreateNotificationEvent model) { var adminId = HttpContext.User.Claims.FirstOrDefault(claim => claim.Type == Constants.UserIdClaimKey); var notification = model.Process(_context, adminId.Value); return(ResponseShell.Ok(notification)); }
public virtual IActionResult PublishNotification([FromRoute] long id) { var notification = _context.Notifications.FirstOrDefault(n => n.Id == id); var adminId = HttpContext.User.Claims.FirstOrDefault(claim => claim.Type == Constants.UserIdClaimKey); var connectionString = _configuration.GetConnectionString(_hostingEnvironment.EnvironmentName); notification = new PublishNotificationEvent().Process(_context, adminId.Value, _validation, connectionString, notification); return(ResponseShell.Ok(notification)); }
public virtual IActionResult AdminById([FromRoute] string id) { var admin = _context.Admins.FirstOrDefault(x => x.Id.ToString() == id); if (admin == null) { // Our response is vague to avoid leaking information return(ResponseShell.Error(Constants.Messages.UserNotFound)); } return(ResponseShell.Ok(admin)); }
public virtual IActionResult RemoveById([FromRoute] string id) { var user = _context.Users.FirstOrDefault(u => u.Id == new Guid(id)); _context.AllUsers.Remove(user); _context.SaveChanges(); return(ResponseShell.Ok(new MaybeSuccess() { Success = true })); }
public override void OnException(ExceptionContext context) { if (context.Exception is IProcessEventException) { // handle explicit 'known' errors var ex = context.Exception as IProcessEventException; Log.Error(context.Exception, ex.Message); context.HttpContext.Response.StatusCode = Constants.StatusCodes.EventErrorStatusCode; context.Result = ex.ResponseShellError; } else { Log.Error(context.Exception, "An unxecpeted related exception occured"); context.HttpContext.Response.StatusCode = Constants.StatusCodes.ErrorUnexpcetedStatusCode; context.Result = ResponseShell.ErrorUnexpected(context.Exception); } // clear it context.Exception = null; }
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (context.ActionArguments.ContainsKey("id")) { var id = context.ActionArguments["id"] as string; if (!string.IsNullOrWhiteSpace(id)) { var check = await _context.Notifications.FirstOrDefaultAsync(u => u.Id.ToString() == id); if (check == null) { context.Result = ResponseShell.NotFound(Constants.Messages.NotificationNotFound); return; } } } await next(); }
public async Task <IActionResult> Refresh([FromBody] RefreshTempUser model) { var existing = _context.Users.FirstOrDefault(user => user.PhoneNumber == model.PhoneNumber.CleanPhone()); if (existing == null) { return(ResponseShell.Error("Could not find user.", new List <string>() { "Either the GenericUser account has not been created", "Or service is temporarily unavailable" })); } if (Constants.Testing.CheckIfOverride(existing) && (_hostingEnvironment.IsDevelopment() || _hostingEnvironment.IsEnvironment("Testing"))) { existing.Token = Constants.Testing.TestValidationToken; // Hold our token and model for a while to give our user a chance to validate their info _memoryCache.SetForChallenge(new TempUser(existing)); // All good thus far, now we just wait on our user to validate return(ResponseShell.Ok(new SimpleSuccess() { Success = true })); } // Fire off our validation var token = await _smsSender.SendValidationToSms(new TempUser() { Email = existing.Email, Id = existing.Id, }); existing.Token = token; // Hold our token and model for a while to give our user a chance to validate their info _memoryCache.SetForChallenge(new TempUser(existing)); // All good thus far, now we just wait on our user to validate return(ResponseShell.Ok(new SimpleSuccess())); }
public virtual IActionResult NotificationLog([FromRoute] long id) { var notification = _context.Notifications.FirstOrDefault(n => n.Id == id); var sentusers = _context.NotificationLog.Where(x => x.NotificationId == notification.Id).Select(x => x.UserId); var locations = _context.Users.Where(x => sentusers.Contains(x.Id)) .Select(x => x.Address.GeoLocation) .Select(p => new GeoLocation(p.Y, p.X)).ToList(); var log = new PublishedNotificationLog() { SentEmail = _context.NotificationLog.Count(x => x.NotificationId == notification.Id && x.Type == LogType.Email), SentSms = _context.NotificationLog.Count(x => x.NotificationId == notification.Id && x.Type == LogType.Sms), Published = notification.Published.GetValueOrDefault(), SentLocations = locations }; return(ResponseShell.Ok(log)); }
public async Task <IActionResult> Validate([FromBody] TokenCheck model) { // Get our Saved User from Memory var savedUser = new CheckValidationTokenEvent().Process(_memoryCache, model); var validatedUser = _context.Users.FirstOrDefault(x => x.PhoneNumber == savedUser.PhoneNumber); if (validatedUser == null) { // Our response is vague to avoid leaking information return(ResponseShell.Error("Invalid")); } validatedUser.LastLogin = DateTime.Now; _context.SaveChanges(); // Get our token var token = await _tokenService.GetToken(validatedUser); // All good, lets give out our token return(ResponseShell.Ok(token)); }
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (context.ActionArguments.ContainsKey("id")) { var id = context.ActionArguments["id"] as string; if (!string.IsNullOrWhiteSpace(id)) { var check = context.HttpContext.User.HasClaim(Constants.UserIdClaimKey, id); var adminCheck = context.HttpContext.User.IsInRole(Constants.AdminRole); if (!check || adminCheck) { context.Result = ResponseShell.AuthError(new Meta() { Message = Constants.Messages.InvalidClaimMsg, Code = 403 }); return; } } } await next(); }
public virtual IActionResult GetConfiguration() { return(ResponseShell.Ok(_context.AdminConfig)); }
public virtual async Task <IActionResult> UpdateSources() { await new PullFromSourcesEvent().Process(_context); return(ResponseShell.Ok()); }
public virtual async Task <IActionResult> UpdateById([FromBody] UpdateableUser tempUser) { try { using (var transaction = _context.Database.BeginTransaction()) { var user = _context.Users.FirstOrDefault(u => u.Id == tempUser.Id); if (user == null) { // Our response is vague to avoid leaking information return(ResponseShell.Error("Could not find an account with that information")); } user.EnabledEmail = tempUser.EnabledEmail; user.EnabledSms = tempUser.EnabledSms; _context.Address.Update(user.Address); user.Address.Zip = tempUser.Address.Zip; user.Address.City = tempUser.Address.City; user.Address.FormattedAddress = tempUser.Address.FormattedAddress; user.Address.Number = tempUser.Address.Number; user.Address.State = tempUser.Address.State; tempUser.Address.GeoLocation.SRID = Constants.SRID; user.Address.GeoLocation = tempUser.Address.GeoLocation; if (!string.IsNullOrWhiteSpace(tempUser.Email) && tempUser.Email != user.Email) { user.Email = tempUser.Email; Log.Information("Sending Email Validation to {user}", tempUser.Email); var temp = new TempUser(user); await _validation.SendValidationToEmail(temp); _memoryCache.SetForChallenge(temp); } tempUser.PhoneNumber = tempUser.PhoneNumber.CleanPhone(); if (!string.IsNullOrWhiteSpace(tempUser.PhoneNumber) && tempUser.PhoneNumber != user.PhoneNumber) { user.PhoneNumber = tempUser.PhoneNumber; Log.Information("Sending SMS Validation to {user}", tempUser.PhoneNumber); var temp = new TempUser(user); await _validation.SendValidationToSms(temp); _memoryCache.SetForChallenge(temp); } if (!string.IsNullOrWhiteSpace(tempUser.Password)) { user.SetPassword(tempUser.Password); } transaction.Commit(); _context.SaveChanges(); return(ResponseShell.Ok(user)); } } catch (Exception e) { Log.Error(e, "Could not update user details"); throw; } }
public virtual IActionResult GetById([FromRoute] string id) { var user = _context.Users.FirstOrDefault(u => u.Id == new Guid(id)); return(ResponseShell.Ok(user)); }
public async Task <IActionResult> CreateWithChallenge([FromBody] TempUser tempUser) { await new CreateDisabledUserAccount().Process(_hostingEnvironment, _memoryCache, _context, _validation, tempUser); return(ResponseShell.Ok()); }
private void AppConfigureJWT(IApplicationBuilder app) { // Allows us to pass token through a query param instead of through a header of authorization app.Use(async(context, next) => { if (string.IsNullOrWhiteSpace(context.Request.Headers["Authorization"])) { if (context.Request.QueryString.HasValue) { var token = context.Request.QueryString.Value .Split('&') .SingleOrDefault(x => x.Contains(Constants.AuthQueryParam))?.Split('=')[1]; if (!string.IsNullOrWhiteSpace(token)) { context.Request.Headers.Add("Authorization", new[] { $"Bearer {token}" }); } } } await next.Invoke(); }); // Note, it is VITAL that this is added BEFORE app.UseMvc() is called. // See https://github.com/mrsheepuk/ASPNETSelfCreatedTokenAuthExample/issues/11 app.UseJwtBearerAuthentication(new JwtBearerOptions { Events = new JwtBearerEvents { OnChallenge = async context => { // Override the response status code. context.Response.StatusCode = Constants.StatusCodes.AuthorizationErrorStatusCode; // Emit the WWW-Authenticate header. context.Response.Headers.Append( HeaderNames.WWWAuthenticate, context.Options.Challenge); await context.Response.WriteAsync(ResponseShell.AuthErrorString(new Meta { Message = Constants.Messages.UnauthorizedMsg, Code = Constants.StatusCodes.AuthorizationErrorStatusCode })); Log.Logger.Warning("Unauthorized access {RemoteIpAddress}", context.HttpContext.Connection); context.HandleResponse(); }, }, TokenValidationParameters = new TokenValidationParameters { IssuerSigningKey = _key, ValidAudience = _tokenOptions.Audience, ValidIssuer = _tokenOptions.Issuer, // When receiving a token, check that it is still valid. ValidateLifetime = true, // This defines the maximum allowable clock skew - i.e. provides a tolerance on the token expiry time // when validating the lifetime. As we're creating the tokens locally and validating them on the same // machines which should have synchronised time, this can be set to zero. Where external tokens are // used, some leeway here could be useful. ClockSkew = TimeSpan.FromMinutes(0) } }); }
public virtual IActionResult ListOfAdmins() { return(ResponseShell.Ok(_context.Admins.ToList())); }
public virtual IActionResult UpdateAdminById([FromBody] AdminUpdateEvent model) { model.Process(_context); return(ResponseShell.Ok(model.GetAdmin(_context))); }
public virtual IActionResult GetNotification([FromRoute] long id) { var notification = _context.Notifications.FirstOrDefault(n => n.Id == id); return(ResponseShell.Ok(notification)); }
public virtual IActionResult ListNotifications() { var list = _context.Notifications.OrderBy(x => x.Created).ToList(); return(ResponseShell.Ok(list)); }
public virtual IActionResult UpdateConfiguration() { return(ResponseShell.NotImplementated()); }
public virtual IActionResult UpdateNotification([FromRoute] long id, [FromBody] CreateNotificationEvent model) { var notification = model.UpdateProcess(_context, id); return(ResponseShell.Ok(notification)); }
public virtual IActionResult CreateAdmin([FromBody] CreateAdminEvent model) { var newAdmin = model.Process(_context); return(ResponseShell.Ok(newAdmin)); }