Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Feedbk.Core;
- using Feedbk.Core.Data;
- using Feedbk.Core.Diagnostics;
- using Feedbk.Core.Entities;
- using Feedbk.Core.Security;
- using Feedbk.Services.Email;
- using System;
- using System.Web.Mvc;
- using System.Linq;
- namespace Feedbk.Services.Authentication
- {
- public class AuthenticationService : IAuthenticationService
- {
- #region Fields
- private IDiagnosticsSource Trace;
- private readonly IAccountRepository _accountRepository;
- private readonly IEmailService _emailService;
- #endregion
- #region Ctor
- /// <summary>
- /// Authentication Service constructor.
- /// </summary>
- /// <param name="logger">IDiagnosticsSource</param>
- /// <param name="accountRepo">Account Repository</param>
- public AuthenticationService(IDiagnosticsSource diagnosticsSource, IAccountRepository accountRepo, IEmailService emailService)
- {
- Trace = diagnosticsSource;
- Trace.Verbose("AuthenticationService init");
- this._accountRepository = accountRepo;
- this._emailService = emailService;
- }
- #endregion
- #region Methods
- /// <summary>
- /// Checks if user exists.
- /// </summary>
- /// <param name="email">Email address</param>
- /// <returns>True if exists. False if doesn't exist.</returns>
- public bool UserExists(string email)
- {
- Trace.Verbose("UserExists(email: {0})", email);
- if (String.IsNullOrWhiteSpace(email))
- return false;
- if (GetUserByEmail(email) == null)
- {
- return false;
- }
- else
- {
- return true;
- }
- }
- /// <summary>
- /// Creates new Account.
- /// </summary>
- /// <param name="accountType">Account type.</param>
- /// <param name="createdBy">Email address of the user creating the account.</param>
- /// <returns></returns>
- public Account CreateAccount(AccountType accountType, string createdBy)
- {
- Trace.Verbose("CreateAccount(account type: {0}, created by: {1})", accountType.ToString(), createdBy);
- Ensure.Argument.NotNull(accountType);
- Ensure.Argument.NotNullOrEmpty(createdBy);
- var account = new Account()
- {
- Type = accountType,
- DateCreated = DateTime.Now,
- CreatedBy = createdBy,
- };
- _accountRepository.CreateAccount(account);
- Trace.Information("CreateAccount() => Success. Account id: {0}", account.Id);
- return account;
- }
- /// <summary>
- /// Creates new User object.
- /// </summary>
- /// <param name="email">Email address.</param>
- /// <param name="password">Password.</param>
- /// <returns>User</returns>
- public User CreateUser(string email, string password, int accountId, int roleId)
- {
- Trace.Information("CreateUser(email: {0}, account id: {1}, role: {2})", email, accountId, roleId);
- var user = new User()
- {
- AccountId = accountId,
- DateCreated = DateTime.Now,
- Email = email.ToLower(),
- RoleId = roleId,
- IsVerified = false,
- FailedLoginCount = 0
- };
- // Hash user's password
- UpdatePasswordAndSalt(user, password);
- // Email verification token
- SetEmailVerificationKey(user, user.Email);
- // Save
- _accountRepository.CreateUser(user);
- Trace.Information(String.Format("CreateUser() => Success. User id: {0}", user.Id));
- return user;
- }
- /// <summary>
- /// Authenticates user with credentials provided.
- /// </summary>
- /// <param name="email">Email address.</param>
- /// <param name="password">Password.</param>
- /// <returns>User</returns>
- public User Authenticate(string email, string password)
- {
- Trace.Verbose("Authenticate(email: {0})", email);
- var user = GetUserByEmail(email);
- if (user == null)
- return null;
- if (ValidatePassword(user, password))
- {
- user.FailedLoginCount = 0;
- user.DateLastLoggedIn = DateTime.Now;
- _accountRepository.UpdateUser(user);
- Trace.Information("User authentication successful. User: {0}", user.Email);
- return user;
- }
- else
- {
- user.FailedLoginCount = user.FailedLoginCount + 1;
- user.LastFailedLogin = DateTime.Now;
- _accountRepository.UpdateUser(user);
- }
- return null;
- }
- /// <summary>
- /// Checks the email verification token and activates the user if correct.
- /// </summary>
- /// <param name="user">User</param>
- /// <param name="vCode">Verification token.</param>
- /// <returns>True if activated successfully. False otherwise.</returns>
- public bool ActivateUser(string email, string vCode)
- {
- Trace.Verbose("ActivateUser(email: {0})", email);
- var user = GetUserByEmail(email);
- if (VerifyEmailKey(user, vCode, false))
- {
- user.IsVerified = true;
- RemoveEmailVerificationKey(user);
- _accountRepository.UpdateUser(user);
- Trace.Information("User account has been activated. User: {0}", user.Email);
- return true;
- }
- Trace.Warning("User account activation failed. Verification key is incorrect.");
- return false;
- }
- /// <summary>
- /// Get account by id.
- /// </summary>
- /// <param name="id">Id</param>
- /// <returns>Account</returns>
- public Account GetAccountById(int id)
- {
- var account = _accountRepository.Accounts.Where(a => a.Id == id).FirstOrDefault();
- if (account != null)
- {
- Trace.Verbose("GetAccountById(id: {0}) => Account found.", id);
- return account;
- }
- else
- {
- Trace.Verbose("GetAccountById(id: {0}) => Account not found.", id);
- return null;
- }
- }
- /// <summary>
- /// Get user.
- /// </summary>
- /// <param name="email">Email address</param>
- /// <returns>User</returns>
- public User GetUserByEmail(string email)
- {
- email = email.ToLower();
- var user = _accountRepository.Users.Where(u => u.Email == email.ToLower()).FirstOrDefault();
- if (user != null)
- {
- Trace.Verbose("GetUserByEmail(email: {0}) => User found: {1}", email, user.Id);
- return user;
- }
- else
- {
- Trace.Verbose("GetUserByEmail(email: {0}) => User not found.", email);
- return null;
- }
- }
- /// <summary>
- /// Checks if password provided matches the user password.
- /// </summary>
- /// <param name="user">User</param>
- /// <param name="password">Password</param>
- /// <returns>True if passwords match. False otherwise.</returns>
- private bool ValidatePassword(User user, string password)
- {
- Trace.Verbose("ValidatePassword(user: {0})", user.Email);
- var passwordSalt = user.PasswordSalt;
- var hashedPassword = PasswordHelper.GenerateSaltedHash(password, passwordSalt);
- return (user.Password == hashedPassword);
- }
- /// <summary>
- /// Generates new salt and hashes the password with it. Updates both properties on user object.
- /// </summary>
- /// <param name="user">User</param>
- /// <param name="password">Password</param>
- private void UpdatePasswordAndSalt(User user, string password)
- {
- Trace.Verbose("UpdatePasswordAndSalt(user: {0})", user.Email);
- var passwordSalt = PasswordHelper.GenerateSalt();
- var hashedPassword = PasswordHelper.GenerateSaltedHash(password, passwordSalt);
- user.PasswordSalt = passwordSalt;
- user.Password = hashedPassword;
- }
- /// <summary>
- /// Creates new email request data.
- /// </summary>
- /// <param name="user">User</param>
- /// <param name="email">Email address</param>
- public void SetEmailVerificationKey(User user, string email = null)
- {
- Trace.Verbose("SetEmailVerificationKey(user: {0}, email: {1})", user.Email, email);
- user.NewEmail = email;
- user.EmailVerificationKey = HashingHelper.GenerateHash(Constants.VerificationHashSize);
- user.EmailVerificationKeySent = DateTime.Now;
- _accountRepository.UpdateUser(user);
- }
- /// <summary>
- /// Removes all data related to new email request.
- /// </summary>
- /// <param name="user">User to remove the data from.</param>
- public void RemoveEmailVerificationKey(User user)
- {
- Trace.Verbose("RemoveEmailVerificationKey(user: {0})", user.Email);
- user.NewEmail = null;
- user.EmailVerificationKey = null;
- user.EmailVerificationKeySent = null;
- }
- /// <summary>
- /// Creates new password reset key for the user.
- /// </summary>
- /// <param name="user">User</param>
- public void SetPasswordResetKey(User user)
- {
- Trace.Verbose("SetPasswordResetKey(user: {0})", user.Email);
- user.PasswordResetKey = HashingHelper.GenerateHash(Constants.VerificationHashSize);
- user.PasswordResetKeySent = DateTime.Now;
- _accountRepository.UpdateUser(user);
- }
- /// <summary>
- /// Removes all data related to password reset.
- /// </summary>
- /// <param name="user">User to remove the data from.</param>
- public void RemovePasswordResetKey(User user)
- {
- Trace.Verbose("RemovePasswordResetKey(user: {0})", user.Email);
- user.PasswordResetKey = null;
- user.PasswordResetKeySent = null;
- }
- /// <summary>
- /// Completes email change procedure.
- /// </summary>
- /// <param name="email">Email address.</param>
- /// <param name="vCode">Verification code.</param>
- public void UpdateEmail(string email, string vCode)
- {
- Ensure.Argument.NotNullOrEmpty(email);
- Ensure.Argument.NotNullOrEmpty(vCode);
- var user = GetUserByEmail(email);
- if (user == null)
- return;
- if (VerifyEmailKey(user, vCode))
- {
- user.Email = user.NewEmail;
- RemoveEmailVerificationKey(user);
- }
- _accountRepository.UpdateUser(user);
- Trace.Information("User email address changed from: {0} to: {1}.", email, user.Email);
- }
- /// <summary>
- /// Updates user's password.
- /// </summary>
- /// <param name="email">Email address.</param>
- /// <param name="password">New password.</param>
- public void UpdatePassword(string email, string password)
- {
- Trace.Verbose("UpdatePassword(user: {0})", email);
- Ensure.Argument.NotNullOrEmpty(email);
- Ensure.Argument.NotNullOrEmpty(password);
- var user = GetUserByEmail(email);
- if (user == null)
- return;
- UpdatePasswordAndSalt(user, password);
- RemovePasswordResetKey(user);
- _accountRepository.UpdateUser(user);
- Trace.Information("User password changed. User: {0}", email);
- }
- /// <summary>
- /// Resets user's password with verification code.
- /// </summary>
- /// <param name="email">Email address.</param>
- /// <param name="password">Password.</param>
- /// <param name="vCode">Verification code.</param>
- public void ResetPassword(string email, string password, string vCode)
- {
- Trace.Verbose("ResetPassword(email: {0})", email);
- Ensure.Argument.NotNullOrEmpty(email);
- Ensure.Argument.NotNullOrEmpty(vCode);
- Ensure.Argument.NotNullOrEmpty(password);
- var user = GetUserByEmail(email);
- if (user == null || !user.IsVerified)
- return;
- if (VerifyPasswordResetKey(user, vCode))
- {
- UpdatePasswordAndSalt(user, password);
- RemovePasswordResetKey(user);
- _accountRepository.UpdateUser(user);
- Trace.Information("User password reset has been successful. User: {0}", email);
- }
- }
- /// <summary>
- /// Checks if the password verification code is valid and not expired (optional).
- /// </summary>
- /// <param name="user">User.</param>
- /// <param name="vCode">Verification code.</param>
- /// <param name="checkDate">Check date.</param>
- /// <returns>True if valid. False otherwise.</returns>
- public bool VerifyPasswordResetKey(User user, string vCode, bool checkDate = true)
- {
- Trace.Verbose("VerifyPasswordKey(user: {0})", user.Email);
- if (checkDate)
- {
- return (user.PasswordResetKey == vCode && user.PasswordResetKeySent > DateTime.Now.AddHours(Constants.HashExpiryTimeInHours * -1));
- }
- else
- {
- return (user.PasswordResetKey == vCode);
- }
- }
- /// <summary>
- /// Checks if the email verification code is valid and not expired (optional).
- /// </summary>
- /// <param name="user">User.</param>
- /// <param name="vCode">Verification code.</param>
- /// <param name="checkDate">Check date.</param>
- /// <returns>True if valid. False otherwise.</returns>
- public bool VerifyEmailKey(User user, string vCode, bool checkDate = true)
- {
- Trace.Verbose("VerifyEmailKey(user: {0})", user.Email);
- if (checkDate)
- {
- return (user.EmailVerificationKey == vCode && user.EmailVerificationKeySent > DateTime.Now.AddHours(Constants.HashExpiryTimeInHours * -1));
- }
- else
- {
- return (user.EmailVerificationKey == vCode);
- }
- }
- #endregion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement