Beispiel #1
0
        [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));
        }
Beispiel #8
0
        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();
            }
Beispiel #12
0
        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));
        }
Beispiel #14
0
        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();
            }
Beispiel #16
0
 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());
 }
Beispiel #21
0
        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)
                }
            });
        }
Beispiel #22
0
 public virtual IActionResult ListOfAdmins()
 {
     return(ResponseShell.Ok(_context.Admins.ToList()));
 }
Beispiel #23
0
 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));
        }
Beispiel #26
0
 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));
        }
Beispiel #28
0
        public virtual IActionResult CreateAdmin([FromBody] CreateAdminEvent model)
        {
            var newAdmin = model.Process(_context);

            return(ResponseShell.Ok(newAdmin));
        }