Skip to main content
replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link
  • I am aware that the GetAppUrl() method needs to be adjusted and have addressed that issue herehere.
  • I am aware that the GetAppUrl() method needs to be adjusted and have addressed that issue here.
  • I am aware that the GetAppUrl() method needs to be adjusted and have addressed that issue here.
Source Link
aaronmallen
  • 848
  • 2
  • 9
  • 21

User Login Logic

I want to see if this is as streamlined as possible. Most of the logic is accomplished through methods in the model. The controller does one of four things:

  1. redirects new users to registration
  2. sends locked users to reset password
  3. logs the user in and redirects them to where they should go
  4. fails the login and allows them to try again

The Controller

using System.Web.Mvc;
using System.Web.Security;
using Authenticator.Models;

namespace Authenticator.Controllers
{
    public class HomeController : Controller
    {
        // Get index
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost()]
        public ActionResult Index(LoginViewModel model)
        {
            // Redirect User to Register if they do not exist;
            if (model.VerifyAccountExists() == false)
            {
                return RedirectToAction("Register");
            }

            // Determine if account is locked and redirect user to reset password.
            if (model.VerifyLock())
            {
                return RedirectToAction("PasswordReset");
            }

            if (model.VerifyPassword())
            {
                model.PassLogin();
                FormsAuthentication.SetAuthCookie(model.UserId, model.RememberMe);
                return Redirect(model.GetAppUrl());
            }
            else 
            {
                model.FailLogin();
                ModelState.AddModelError("", "Incorrect Network ID or Password.");
            }

            return View(model);
        }

        // shared view data
        protected override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);
            ViewBag.BodyClass = "authenticator";  
        }
    }
}

The View Model

using System;
using System.Linq;
using System.Data;
using System.Web.Helpers;

namespace Authenticator.Models
{
    public class LoginViewModel
    {
        public string UserId { get; set; }
        public string Password { get; set; }
        public bool RememberMe { get; set; }

        public bool VerifyAccountExists()
        {
            using (var db = new WebContext())
            {
                if (db.UserAccounts.Count(p => p.UserId == UserId) > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        public bool VerifyPassword()
        {
            if (VerifyAccountExists() == false)
            {
                return false;
            }
            using (var db = new WebContext())
            {
                UserAccount account = db.UserAccounts.Find(UserId);
                return Crypto.VerifyHashedPassword(account.PasswordHash, Password);
            }
        }
        public bool VerifyLock()
        {
            if (VerifyAccountExists() == false)
            {
                return false;
            }

            using (var db = new WebContext())
            {
                UserAccount account = db.UserAccounts.Find(UserId);
                return account.Lock;
            }

        }
        public bool FailLogin()
        {
            if (VerifyAccountExists() == false)
            {
                return false;
            }
            using (var db = new WebContext())
            {
                UserAccount account = db.UserAccounts.Find(UserId);
                switch (account.FailedAttempts)
                    {
                        case 1 - 3:
                            account.FailedAttempts = account.FailedAttempts + 1;
                            account.DateUpdated = DateTime.Now;
                            break;
                        default:
                            account.FailedAttempts = 4;
                            account.Lock = true;
                            account.DateUpdated = DateTime.Now;
                            break;
                    }
                    db.Entry(account).State = EntityState.Modified;
                    db.SaveChanges();
                    return true;
            }
        }
        public bool PassLogin()
        {
            if (VerifyAccountExists() == false)
            {
                return false;
            }
            using (var db = new WebContext())
            {
                UserAccount account = db.UserAccounts.Find(UserId);
                account.FailedAttempts = 0;
                account.Lock = false;
                account.DateLastLogin = DateTime.Now;
                account.DateUpdated = DateTime.Now;
                db.Entry(account).State = EntityState.Modified;
                db.SaveChanges();
                return true;
            }
        }
        public string GetAppUrl()
        {
            using (var db = new WebContext())
            {
                var query = (from a in db.Permissions
                             join b in db.UserPermissions on a.Id equals b.PermissionId
                             join c in db.Applications on a.Name equals c.AppName
                             where a.Type == PermissionType.AppAccess & b.UserId == UserId
                             select c).ToList();
                switch (query.Count)
                {
                    case 0:
                        return "http://azshisp11/Tickets/Create?subject==Request%20For%20Application%20Access";
                        // TODO: code ticket logic to except this argument
                    case 1:
                        return query[0].AppUrl;
                    default:
                        return "http://azshisp11/Dashboard/" + UserId;
                }
            }
        }
    }
}

Known Issues

  • I am aware that the GetAppUrl() method needs to be adjusted and have addressed that issue here.