SHARE
TWEET

Untitled

a guest Sep 24th, 2016 70 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using Feedbk.Core;
  2. using Feedbk.Core.Data;
  3. using Feedbk.Core.Diagnostics;
  4. using Feedbk.Core.Entities;
  5. using Feedbk.Core.Security;
  6. using Feedbk.Services.Email;
  7. using System;
  8. using System.Web.Mvc;
  9. using System.Linq;
  10.  
  11. namespace Feedbk.Services.Authentication
  12. {
  13.     public class AuthenticationService : IAuthenticationService
  14.     {
  15.         #region Fields
  16.  
  17.         private IDiagnosticsSource Trace;
  18.  
  19.         private readonly IAccountRepository _accountRepository;
  20.         private readonly IEmailService _emailService;
  21.  
  22.         #endregion
  23.  
  24.         #region Ctor
  25.  
  26.         /// <summary>
  27.         /// Authentication Service constructor.
  28.         /// </summary>
  29.         /// <param name="logger">IDiagnosticsSource</param>
  30.         /// <param name="accountRepo">Account Repository</param>
  31.         public AuthenticationService(IDiagnosticsSource diagnosticsSource, IAccountRepository accountRepo, IEmailService emailService)
  32.         {
  33.             Trace = diagnosticsSource;
  34.             Trace.Verbose("AuthenticationService init");
  35.  
  36.             this._accountRepository = accountRepo;
  37.             this._emailService = emailService;
  38.         }
  39.  
  40.         #endregion
  41.  
  42.         #region Methods
  43.  
  44.         /// <summary>
  45.         /// Checks if user exists.
  46.         /// </summary>
  47.         /// <param name="email">Email address</param>
  48.         /// <returns>True if exists. False if doesn't exist.</returns>
  49.         public bool UserExists(string email)
  50.         {
  51.             Trace.Verbose("UserExists(email: {0})", email);
  52.  
  53.             if (String.IsNullOrWhiteSpace(email))
  54.                 return false;
  55.  
  56.             if (GetUserByEmail(email) == null)
  57.             {
  58.                 return false;
  59.             }
  60.             else
  61.             {
  62.                 return true;
  63.             }
  64.         }
  65.  
  66.         /// <summary>
  67.         /// Creates new Account.
  68.         /// </summary>
  69.         /// <param name="accountType">Account type.</param>
  70.         /// <param name="createdBy">Email address of the user creating the account.</param>
  71.         /// <returns></returns>
  72.         public Account CreateAccount(AccountType accountType, string createdBy)
  73.         {
  74.             Trace.Verbose("CreateAccount(account type: {0}, created by: {1})", accountType.ToString(), createdBy);
  75.  
  76.             Ensure.Argument.NotNull(accountType);
  77.             Ensure.Argument.NotNullOrEmpty(createdBy);
  78.  
  79.             var account = new Account()
  80.             {
  81.                 Type = accountType,
  82.                 DateCreated = DateTime.Now,
  83.                 CreatedBy = createdBy,
  84.             };
  85.  
  86.             _accountRepository.CreateAccount(account);
  87.  
  88.             Trace.Information("CreateAccount() => Success. Account id: {0}", account.Id);
  89.  
  90.             return account;
  91.         }
  92.  
  93.         /// <summary>
  94.         /// Creates new User object.
  95.         /// </summary>
  96.         /// <param name="email">Email address.</param>
  97.         /// <param name="password">Password.</param>
  98.         /// <returns>User</returns>
  99.         public User CreateUser(string email, string password, int accountId, int roleId)
  100.         {
  101.             Trace.Information("CreateUser(email: {0}, account id: {1}, role: {2})", email, accountId, roleId);
  102.  
  103.             var user = new User()
  104.             {
  105.                 AccountId = accountId,
  106.                 DateCreated = DateTime.Now,
  107.                 Email = email.ToLower(),
  108.                 RoleId = roleId,
  109.                 IsVerified = false,
  110.                 FailedLoginCount = 0
  111.             };
  112.  
  113.             // Hash user's password
  114.             UpdatePasswordAndSalt(user, password);
  115.  
  116.             // Email verification token
  117.             SetEmailVerificationKey(user, user.Email);
  118.  
  119.             // Save
  120.             _accountRepository.CreateUser(user);
  121.  
  122.             Trace.Information(String.Format("CreateUser() => Success. User id: {0}", user.Id));
  123.  
  124.             return user;
  125.         }
  126.  
  127.         /// <summary>
  128.         /// Authenticates user with credentials provided.
  129.         /// </summary>
  130.         /// <param name="email">Email address.</param>
  131.         /// <param name="password">Password.</param>
  132.         /// <returns>User</returns>
  133.         public User Authenticate(string email, string password)
  134.         {
  135.             Trace.Verbose("Authenticate(email: {0})", email);
  136.  
  137.             var user = GetUserByEmail(email);
  138.  
  139.             if (user == null)
  140.                 return null;
  141.  
  142.             if (ValidatePassword(user, password))
  143.             {
  144.                 user.FailedLoginCount = 0;
  145.                 user.DateLastLoggedIn = DateTime.Now;
  146.                 _accountRepository.UpdateUser(user);
  147.  
  148.                 Trace.Information("User authentication successful. User: {0}", user.Email);
  149.  
  150.                 return user;
  151.             }
  152.             else
  153.             {
  154.                 user.FailedLoginCount = user.FailedLoginCount + 1;
  155.                 user.LastFailedLogin = DateTime.Now;
  156.                 _accountRepository.UpdateUser(user);
  157.             }
  158.             return null;
  159.         }
  160.  
  161.         /// <summary>
  162.         /// Checks the email verification token and activates the user if correct.
  163.         /// </summary>
  164.         /// <param name="user">User</param>
  165.         /// <param name="vCode">Verification token.</param>
  166.         /// <returns>True if activated successfully. False otherwise.</returns>
  167.         public bool ActivateUser(string email, string vCode)
  168.         {
  169.             Trace.Verbose("ActivateUser(email: {0})", email);
  170.  
  171.             var user = GetUserByEmail(email);
  172.  
  173.             if (VerifyEmailKey(user, vCode, false))
  174.             {
  175.                 user.IsVerified = true;
  176.  
  177.                 RemoveEmailVerificationKey(user);
  178.                 _accountRepository.UpdateUser(user);
  179.  
  180.                 Trace.Information("User account has been activated. User: {0}", user.Email);
  181.  
  182.                 return true;
  183.             }
  184.  
  185.             Trace.Warning("User account activation failed. Verification key is incorrect.");
  186.  
  187.             return false;
  188.         }
  189.  
  190.         /// <summary>
  191.         /// Get account by id.
  192.         /// </summary>
  193.         /// <param name="id">Id</param>
  194.         /// <returns>Account</returns>
  195.         public Account GetAccountById(int id)
  196.         {
  197.             var account = _accountRepository.Accounts.Where(a => a.Id == id).FirstOrDefault();
  198.  
  199.             if (account != null)
  200.             {
  201.                 Trace.Verbose("GetAccountById(id: {0}) => Account found.", id);
  202.  
  203.                 return account;
  204.             }
  205.             else
  206.             {
  207.                 Trace.Verbose("GetAccountById(id: {0}) => Account not found.", id);
  208.  
  209.                 return null;
  210.             }
  211.         }
  212.  
  213.         /// <summary>
  214.         /// Get user.
  215.         /// </summary>
  216.         /// <param name="email">Email address</param>
  217.         /// <returns>User</returns>
  218.         public User GetUserByEmail(string email)
  219.         {
  220.             email = email.ToLower();
  221.  
  222.             var user = _accountRepository.Users.Where(u => u.Email == email.ToLower()).FirstOrDefault();
  223.  
  224.             if (user != null)
  225.             {
  226.                 Trace.Verbose("GetUserByEmail(email: {0}) => User found: {1}", email, user.Id);
  227.  
  228.                 return user;
  229.             }
  230.             else
  231.             {
  232.                 Trace.Verbose("GetUserByEmail(email: {0}) => User not found.", email);
  233.  
  234.                 return null;
  235.             }
  236.         }
  237.  
  238.         /// <summary>
  239.         /// Checks if password provided matches the user password.
  240.         /// </summary>
  241.         /// <param name="user">User</param>
  242.         /// <param name="password">Password</param>
  243.         /// <returns>True if passwords match. False otherwise.</returns>
  244.         private bool ValidatePassword(User user, string password)
  245.         {
  246.             Trace.Verbose("ValidatePassword(user: {0})", user.Email);
  247.  
  248.             var passwordSalt = user.PasswordSalt;
  249.             var hashedPassword = PasswordHelper.GenerateSaltedHash(password, passwordSalt);
  250.  
  251.             return (user.Password == hashedPassword);
  252.         }
  253.  
  254.         /// <summary>
  255.         /// Generates new salt and hashes the password with it. Updates both properties on user object.
  256.         /// </summary>
  257.         /// <param name="user">User</param>
  258.         /// <param name="password">Password</param>
  259.         private void UpdatePasswordAndSalt(User user, string password)
  260.         {
  261.             Trace.Verbose("UpdatePasswordAndSalt(user: {0})", user.Email);
  262.  
  263.             var passwordSalt = PasswordHelper.GenerateSalt();
  264.             var hashedPassword = PasswordHelper.GenerateSaltedHash(password, passwordSalt);
  265.  
  266.             user.PasswordSalt = passwordSalt;
  267.             user.Password = hashedPassword;
  268.         }
  269.  
  270.         /// <summary>
  271.         /// Creates new email request data.
  272.         /// </summary>
  273.         /// <param name="user">User</param>
  274.         /// <param name="email">Email address</param>
  275.         public void SetEmailVerificationKey(User user, string email = null)
  276.         {
  277.             Trace.Verbose("SetEmailVerificationKey(user: {0}, email: {1})", user.Email, email);
  278.  
  279.             user.NewEmail = email;
  280.             user.EmailVerificationKey = HashingHelper.GenerateHash(Constants.VerificationHashSize);
  281.             user.EmailVerificationKeySent = DateTime.Now;
  282.  
  283.             _accountRepository.UpdateUser(user);
  284.         }
  285.  
  286.         /// <summary>
  287.         /// Removes all data related to new email request.
  288.         /// </summary>
  289.         /// <param name="user">User to remove the data from.</param>
  290.         public void RemoveEmailVerificationKey(User user)
  291.         {
  292.             Trace.Verbose("RemoveEmailVerificationKey(user: {0})", user.Email);
  293.  
  294.             user.NewEmail = null;
  295.             user.EmailVerificationKey = null;
  296.             user.EmailVerificationKeySent = null;
  297.         }
  298.  
  299.         /// <summary>
  300.         /// Creates new password reset key for the user.
  301.         /// </summary>
  302.         /// <param name="user">User</param>
  303.         public void SetPasswordResetKey(User user)
  304.         {
  305.             Trace.Verbose("SetPasswordResetKey(user: {0})", user.Email);
  306.  
  307.             user.PasswordResetKey = HashingHelper.GenerateHash(Constants.VerificationHashSize);
  308.             user.PasswordResetKeySent = DateTime.Now;
  309.  
  310.             _accountRepository.UpdateUser(user);
  311.         }
  312.  
  313.         /// <summary>
  314.         /// Removes all data related to password reset.
  315.         /// </summary>
  316.         /// <param name="user">User to remove the data from.</param>
  317.         public void RemovePasswordResetKey(User user)
  318.         {
  319.             Trace.Verbose("RemovePasswordResetKey(user: {0})", user.Email);
  320.  
  321.             user.PasswordResetKey = null;
  322.             user.PasswordResetKeySent = null;
  323.         }
  324.  
  325.         /// <summary>
  326.         /// Completes email change procedure.
  327.         /// </summary>
  328.         /// <param name="email">Email address.</param>
  329.         /// <param name="vCode">Verification code.</param>
  330.         public void UpdateEmail(string email, string vCode)
  331.         {
  332.             Ensure.Argument.NotNullOrEmpty(email);
  333.             Ensure.Argument.NotNullOrEmpty(vCode);
  334.  
  335.             var user = GetUserByEmail(email);
  336.  
  337.             if (user == null)
  338.                 return;
  339.  
  340.             if (VerifyEmailKey(user, vCode))
  341.             {
  342.                 user.Email = user.NewEmail;
  343.                 RemoveEmailVerificationKey(user);
  344.             }
  345.  
  346.             _accountRepository.UpdateUser(user);
  347.  
  348.             Trace.Information("User email address changed from: {0} to: {1}.", email, user.Email);
  349.         }
  350.  
  351.         /// <summary>
  352.         /// Updates user's password.
  353.         /// </summary>
  354.         /// <param name="email">Email address.</param>
  355.         /// <param name="password">New password.</param>
  356.         public void UpdatePassword(string email, string password)
  357.         {
  358.             Trace.Verbose("UpdatePassword(user: {0})", email);
  359.  
  360.             Ensure.Argument.NotNullOrEmpty(email);
  361.             Ensure.Argument.NotNullOrEmpty(password);
  362.  
  363.             var user = GetUserByEmail(email);
  364.  
  365.             if (user == null)
  366.                 return;
  367.  
  368.             UpdatePasswordAndSalt(user, password);
  369.             RemovePasswordResetKey(user);
  370.  
  371.             _accountRepository.UpdateUser(user);
  372.  
  373.             Trace.Information("User password changed. User: {0}", email);
  374.         }
  375.  
  376.         /// <summary>
  377.         /// Resets user's password with verification code.
  378.         /// </summary>
  379.         /// <param name="email">Email address.</param>
  380.         /// <param name="password">Password.</param>
  381.         /// <param name="vCode">Verification code.</param>
  382.         public void ResetPassword(string email, string password, string vCode)
  383.         {
  384.             Trace.Verbose("ResetPassword(email: {0})", email);
  385.  
  386.             Ensure.Argument.NotNullOrEmpty(email);
  387.             Ensure.Argument.NotNullOrEmpty(vCode);
  388.             Ensure.Argument.NotNullOrEmpty(password);
  389.  
  390.             var user = GetUserByEmail(email);
  391.  
  392.             if (user == null || !user.IsVerified)
  393.                 return;
  394.  
  395.             if (VerifyPasswordResetKey(user, vCode))
  396.             {
  397.                 UpdatePasswordAndSalt(user, password);
  398.                 RemovePasswordResetKey(user);
  399.  
  400.                 _accountRepository.UpdateUser(user);
  401.  
  402.                 Trace.Information("User password reset has been successful. User: {0}", email);
  403.             }
  404.         }
  405.  
  406.         /// <summary>
  407.         /// Checks if the password verification code is valid and not expired (optional).
  408.         /// </summary>
  409.         /// <param name="user">User.</param>
  410.         /// <param name="vCode">Verification code.</param>
  411.         /// <param name="checkDate">Check date.</param>
  412.         /// <returns>True if valid. False otherwise.</returns>
  413.         public bool VerifyPasswordResetKey(User user, string vCode, bool checkDate = true)
  414.         {
  415.             Trace.Verbose("VerifyPasswordKey(user: {0})", user.Email);
  416.  
  417.             if (checkDate)
  418.             {
  419.                 return (user.PasswordResetKey == vCode && user.PasswordResetKeySent > DateTime.Now.AddHours(Constants.HashExpiryTimeInHours * -1));
  420.             }
  421.             else
  422.             {
  423.                 return (user.PasswordResetKey == vCode);
  424.             }
  425.         }
  426.  
  427.         /// <summary>
  428.         /// Checks if the email verification code is valid and not expired (optional).
  429.         /// </summary>
  430.         /// <param name="user">User.</param>
  431.         /// <param name="vCode">Verification code.</param>
  432.         /// <param name="checkDate">Check date.</param>
  433.         /// <returns>True if valid. False otherwise.</returns>
  434.         public bool VerifyEmailKey(User user, string vCode, bool checkDate = true)
  435.         {
  436.             Trace.Verbose("VerifyEmailKey(user: {0})", user.Email);
  437.  
  438.             if (checkDate)
  439.             {
  440.                 return (user.EmailVerificationKey == vCode && user.EmailVerificationKeySent > DateTime.Now.AddHours(Constants.HashExpiryTimeInHours * -1));
  441.             }
  442.             else
  443.             {
  444.                 return (user.EmailVerificationKey == vCode);
  445.             }
  446.         }
  447.  
  448.         #endregion
  449.     }
  450. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top