212 lines
7.0 KiB
C#
212 lines
7.0 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// Represents Google Authenticator service
|
|
/// </summary>
|
|
public class GoogleAuthenticatorService
|
|
{
|
|
#region Fields
|
|
|
|
protected readonly IRepository<GoogleAuthenticatorRecord> _repository;
|
|
protected readonly IStaticCacheManager _staticCacheManager;
|
|
protected readonly IWorkContext _workContext;
|
|
protected readonly GoogleAuthenticatorSettings _googleAuthenticatorSettings;
|
|
protected TwoFactorAuthenticator _twoFactorAuthenticator;
|
|
|
|
#endregion
|
|
|
|
#region Ctr
|
|
|
|
public GoogleAuthenticatorService(
|
|
IRepository<GoogleAuthenticatorRecord> repository,
|
|
IStaticCacheManager staticCacheManager,
|
|
IWorkContext workContext,
|
|
GoogleAuthenticatorSettings googleAuthenticatorSettings)
|
|
{
|
|
_repository = repository;
|
|
_staticCacheManager = staticCacheManager;
|
|
_workContext = workContext;
|
|
_googleAuthenticatorSettings = googleAuthenticatorSettings;
|
|
}
|
|
#endregion
|
|
|
|
#region Utilities
|
|
|
|
/// <summary>
|
|
/// Insert the configuration
|
|
/// </summary>
|
|
/// <param name="configuration">Configuration</param>
|
|
/// <returns>A task that represents the asynchronous operation</returns>
|
|
protected async Task InsertConfigurationAsync(GoogleAuthenticatorRecord configuration)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(configuration);
|
|
|
|
await _repository.InsertAsync(configuration);
|
|
await _staticCacheManager.RemoveByPrefixAsync(GoogleAuthenticatorDefaults.PrefixCacheKey);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update the configuration
|
|
/// </summary>
|
|
/// <param name="configuration">Configuration</param>
|
|
/// <returns>A task that represents the asynchronous operation</returns>
|
|
protected async Task UpdateConfigurationAsync(GoogleAuthenticatorRecord configuration)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(configuration);
|
|
|
|
await _repository.UpdateAsync(configuration);
|
|
await _staticCacheManager.RemoveByPrefixAsync(GoogleAuthenticatorDefaults.PrefixCacheKey);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Delete the configuration
|
|
/// </summary>
|
|
/// <param name="configuration">Configuration</param>
|
|
internal async Task DeleteConfigurationAsync(GoogleAuthenticatorRecord configuration)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(configuration);
|
|
|
|
await _repository.DeleteAsync(configuration);
|
|
await _staticCacheManager.RemoveByPrefixAsync(GoogleAuthenticatorDefaults.PrefixCacheKey);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a configuration by the identifier
|
|
/// </summary>
|
|
/// <param name="configurationId">Configuration identifier</param>
|
|
/// <returns>Configuration</returns>
|
|
internal async Task<GoogleAuthenticatorRecord> 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
|
|
|
|
/// <summary>
|
|
/// Get configurations
|
|
/// </summary>
|
|
/// <param name="email">Email</param>
|
|
/// <param name="pageIndex">Page index</param>
|
|
/// <param name="pageSize">Page size</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the paged list of configurations
|
|
/// </returns>
|
|
public async Task<IPagedList<GoogleAuthenticatorRecord>> 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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if the customer is registered
|
|
/// </summary>
|
|
/// <param name="customerEmail"></param>
|
|
/// <returns></returns>
|
|
public bool IsRegisteredCustomer(string customerEmail)
|
|
{
|
|
return GetConfigurationByCustomerEmail(customerEmail) != null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add configuration of GoogleAuthenticator
|
|
/// </summary>
|
|
/// <param name="customerEmail">Customer email</param>
|
|
/// <param name="key">Secret key</param>
|
|
/// <returns>A task that represents the asynchronous operation</returns>
|
|
public virtual async Task AddGoogleAuthenticatorAccountAsync(string customerEmail, string key)
|
|
{
|
|
var account = new GoogleAuthenticatorRecord
|
|
{
|
|
Customer = customerEmail,
|
|
SecretKey = key,
|
|
};
|
|
|
|
await InsertConfigurationAsync(account);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update configuration of GoogleAuthenticator
|
|
/// </summary>
|
|
/// <param name="customerEmail">Customer email</param>
|
|
/// <param name="key">Secret key</param>
|
|
/// <returns>A task that represents the asynchronous operation</returns>
|
|
public async Task UpdateGoogleAuthenticatorAccountAsync(string customerEmail, string key)
|
|
{
|
|
var account = GetConfigurationByCustomerEmail(customerEmail);
|
|
if (account != null)
|
|
{
|
|
account.SecretKey = key;
|
|
await UpdateConfigurationAsync(account);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate a setup code for a Google Authenticator user to scan
|
|
/// </summary>
|
|
/// <param name="secretkey">Secret key</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the
|
|
/// </returns>
|
|
public async Task<SetupCode> GenerateSetupCode(string secretkey)
|
|
{
|
|
var customer = await _workContext.GetCurrentCustomerAsync();
|
|
|
|
return TwoFactorAuthenticator.GenerateSetupCode(
|
|
_googleAuthenticatorSettings.BusinessPrefix,
|
|
customer.Email,
|
|
secretkey, false, _googleAuthenticatorSettings.QRPixelsPerModule);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate token auth
|
|
/// </summary>
|
|
/// <param name="secretkey">Secret key</param>
|
|
/// <param name="token">Token</param>
|
|
/// <returns></returns>
|
|
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
|
|
} |