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 Utilities /// /// 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 }