Webiant Logo Webiant Logo
  1. No results found.

    Try your search with a different keyword or use * as a wildcard.

GoogleAuthenticatorService.cs

using Google.Authenticator;
using Nop.Core;
using Nop.Core.Caching;
using Nop.Data;
using Nop.Plugin.MultiFactorAuth.GoogleAuthenticator.Domains;

namespace Nop.Plugin.MultiFactorAuth.GoogleAuthenticator.Services;

/// 
/// Represents Google Authenticator service
/// 
public class GoogleAuthenticatorService
{
    #region Fields

    protected readonly IRepository _repository;
    protected readonly IStaticCacheManager _staticCacheManager;
    protected readonly IWorkContext _workContext;
    protected readonly GoogleAuthenticatorSettings _googleAuthenticatorSettings;
    protected TwoFactorAuthenticator _twoFactorAuthenticator;
        
    #endregion

    #region Ctr

    public GoogleAuthenticatorService(
        IRepository repository,
        IStaticCacheManager staticCacheManager,
        IWorkContext workContext,
        GoogleAuthenticatorSettings googleAuthenticatorSettings)
    {
        _repository = repository;
        _staticCacheManager = staticCacheManager;
        _workContext = workContext;
        _googleAuthenticatorSettings = googleAuthenticatorSettings;
    }
    #endregion
        
    #region Utilites

    /// 
    /// Insert the configuration
    /// 
    /// Configuration
    /// A task that represents the asynchronous operation
    protected async Task InsertConfigurationAsync(GoogleAuthenticatorRecord configuration)
    {
        ArgumentNullException.ThrowIfNull(configuration);

        await _repository.InsertAsync(configuration);
        await _staticCacheManager.RemoveByPrefixAsync(GoogleAuthenticatorDefaults.PrefixCacheKey);
    }

    /// 
    /// Update the configuration
    /// 
    /// Configuration
    /// A task that represents the asynchronous operation
    protected async Task UpdateConfigurationAsync(GoogleAuthenticatorRecord configuration)
    {
        ArgumentNullException.ThrowIfNull(configuration);

        await _repository.UpdateAsync(configuration);
        await _staticCacheManager.RemoveByPrefixAsync(GoogleAuthenticatorDefaults.PrefixCacheKey);
    }

    /// 
    /// Delete the configuration
    /// 
    /// Configuration
    internal async Task DeleteConfigurationAsync(GoogleAuthenticatorRecord configuration)
    {
        ArgumentNullException.ThrowIfNull(configuration);

        await _repository.DeleteAsync(configuration);
        await _staticCacheManager.RemoveByPrefixAsync(GoogleAuthenticatorDefaults.PrefixCacheKey);
    }

    /// 
    /// Get a configuration by the identifier
    /// 
    /// Configuration identifier
    /// Configuration
    internal async Task GetConfigurationByIdAsync(int configurationId)
    {
        if (configurationId == 0)
            return null;

        return await _staticCacheManager.GetAsync(_staticCacheManager.PrepareKeyForDefaultCache(GoogleAuthenticatorDefaults.ConfigurationCacheKey, configurationId), async () =>
            await _repository.GetByIdAsync(configurationId));
    }

    internal GoogleAuthenticatorRecord GetConfigurationByCustomerEmail(string email)
    {
        if (string.IsNullOrEmpty(email))
            return null;

        var query = _repository.Table;
        return query.FirstOrDefault(record => record.Customer == email);
    }

    #endregion

    #region Methods

    /// 
    /// Get configurations
    /// 
    /// Email
    /// Page index
    /// Page size
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the paged list of configurations
    /// 
    public async Task> GetPagedConfigurationsAsync(string email = null, int pageIndex = 0, int pageSize = int.MaxValue)
    {
        var query = _repository.Table;
        if (!string.IsNullOrWhiteSpace(email))
            query = query.Where(c => c.Customer.Contains(email));
        query = query.OrderBy(configuration => configuration.Id);

        return await query.ToPagedListAsync(pageIndex, pageSize);
    }

    /// 
    /// Check if the customer is registered  
    /// 
    /// 
    /// 
    public bool IsRegisteredCustomer(string customerEmail)
    {
        return GetConfigurationByCustomerEmail(customerEmail) != null;
    }

    /// 
    /// Add configuration of GoogleAuthenticator
    /// 
    /// Customer email
    /// Secret key
    /// A task that represents the asynchronous operation
    public virtual async Task AddGoogleAuthenticatorAccountAsync(string customerEmail, string key)
    {
        var account = new GoogleAuthenticatorRecord
        {
            Customer = customerEmail,
            SecretKey = key,
        };

        await InsertConfigurationAsync(account);
    }

    /// 
    /// Update configuration of GoogleAuthenticator
    /// 
    /// Customer email
    /// Secret key
    /// A task that represents the asynchronous operation
    public async Task UpdateGoogleAuthenticatorAccountAsync(string customerEmail, string key)
    {
        var account = GetConfigurationByCustomerEmail(customerEmail);
        if (account != null)
        {
            account.SecretKey = key;
            await UpdateConfigurationAsync(account);
        }
    }

    /// 
    /// Generate a setup code for a Google Authenticator user to scan
    /// 
    /// Secret key
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the 
    /// 
    public async Task GenerateSetupCode(string secretkey)
    {
        var customer = await _workContext.GetCurrentCustomerAsync();

        return TwoFactorAuthenticator.GenerateSetupCode(
            _googleAuthenticatorSettings.BusinessPrefix,
            customer.Email,
            secretkey, false, _googleAuthenticatorSettings.QRPixelsPerModule);
    }

    /// 
    /// Validate token auth
    /// 
    /// Secret key
    /// Token
    /// 
    public bool ValidateTwoFactorToken(string secretkey, string token)
    {
        return TwoFactorAuthenticator.ValidateTwoFactorPIN(secretkey, token);
    }

    #endregion

    #region Properties

    protected TwoFactorAuthenticator TwoFactorAuthenticator
    {
        get
        {
            _twoFactorAuthenticator = new TwoFactorAuthenticator();
            return _twoFactorAuthenticator;
        }
    }

    #endregion
}