Try your search with a different keyword or use * as a wildcard.
using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Responses;
using Google.Apis.Auth.OAuth2.Web;
using Google.Apis.Util.Store;
using Microsoft.AspNetCore.Mvc;
using Nop.Core;
using Nop.Core.Domain.Messages;
using Nop.Core.Infrastructure;
using Nop.Services.Configuration;
using Nop.Services.Localization;
using Nop.Services.Logging;
using Nop.Services.Messages;
using Nop.Services.Security;
using Nop.Web.Areas.Admin.Factories;
using Nop.Web.Areas.Admin.Infrastructure.Mapper.Extensions;
using Nop.Web.Areas.Admin.Models.Messages;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Mvc.Filters;
namespace Nop.Web.Areas.Admin.Controllers;
public partial class EmailAccountController : BaseAdminController
{
#region Fields
private const char SEPARATOR = '-';
protected readonly EmailAccountSettings _emailAccountSettings;
protected readonly ICustomerActivityService _customerActivityService;
protected readonly IEmailAccountModelFactory _emailAccountModelFactory;
protected readonly IEmailAccountService _emailAccountService;
protected readonly IEmailSender _emailSender;
protected readonly ILocalizationService _localizationService;
protected readonly INopFileProvider _fileProvider;
protected readonly INotificationService _notificationService;
protected readonly IPermissionService _permissionService;
protected readonly ISettingService _settingService;
protected readonly IStoreContext _storeContext;
protected readonly IWebHelper _webHelper;
#endregion
#region Ctor
public EmailAccountController(EmailAccountSettings emailAccountSettings,
ICustomerActivityService customerActivityService,
IEmailAccountModelFactory emailAccountModelFactory,
IEmailAccountService emailAccountService,
IEmailSender emailSender,
ILocalizationService localizationService,
INopFileProvider fileProvider,
INotificationService notificationService,
IPermissionService permissionService,
ISettingService settingService,
IStoreContext storeContext,
IWebHelper webHelper)
{
_emailAccountSettings = emailAccountSettings;
_customerActivityService = customerActivityService;
_emailAccountModelFactory = emailAccountModelFactory;
_emailAccountService = emailAccountService;
_emailSender = emailSender;
_localizationService = localizationService;
_fileProvider = fileProvider;
_notificationService = notificationService;
_permissionService = permissionService;
_settingService = settingService;
_storeContext = storeContext;
_webHelper = webHelper;
}
#endregion
#region Utilities
protected virtual async Task<string> PrepareOAuthUrlAsync(EmailAccount emailAccount)
{
if (string.IsNullOrEmpty(emailAccount.ClientSecret) || string.IsNullOrEmpty(emailAccount.ClientId))
{
ModelState.AddModelError(nameof(EmailAccountModel.ClientSecret), await _localizationService.GetResourceAsync("Admin.Configuration.EmailAccounts.Fields.ClientSecret.Required"));
return string.Empty;
}
var tokenFilePath = _fileProvider.MapPath(NopMessageDefaults.GmailAuthStorePath);
var credentialRoot = _fileProvider.Combine(tokenFilePath, emailAccount.Email);
var codeFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = emailAccount.ClientId,
ClientSecret = emailAccount.ClientSecret
},
Scopes = NopMessageDefaults.GmailScopes,
DataStore = new FileDataStore(credentialRoot, true),
UserDefinedQueryParams = new Dictionary<string, string> { ["emailAccountId"] = emailAccount.Id.ToString() }
});
var redirectUri = Url.Action(nameof(AuthReturn), null, null, _webHelper.GetCurrentRequestProtocol());
var authCode = new AuthorizationCodeWebApp(codeFlow, redirectUri, $"{emailAccount.Id}{SEPARATOR}");
var authResult = await authCode.AuthorizeAsync(emailAccount.Email, CancellationToken.None);
return authResult.RedirectUri?.ToString();
}
#endregion
#region Methods
[CheckPermission(StandardPermission.Configuration.MANAGE_EMAIL_ACCOUNTS)]
public virtual async Task<IActionResult> List()
{
//prepare model
var model = await _emailAccountModelFactory.PrepareEmailAccountSearchModelAsync(new EmailAccountSearchModel());
return View(model);
}
[HttpPost]
[CheckPermission(StandardPermission.Configuration.MANAGE_EMAIL_ACCOUNTS)]
public virtual async Task<IActionResult> List(EmailAccountSearchModel searchModel)
{
//prepare model
var model = await _emailAccountModelFactory.PrepareEmailAccountListModelAsync(searchModel);
return Json(model);
}
[CheckPermission(StandardPermission.Configuration.MANAGE_EMAIL_ACCOUNTS)]
public virtual async Task<IActionResult> MarkAsDefaultEmail(int id)
{
var defaultEmailAccount = await _emailAccountService.GetEmailAccountByIdAsync(id);
if (defaultEmailAccount == null)
return RedirectToAction("List");
_emailAccountSettings.DefaultEmailAccountId = defaultEmailAccount.Id;
await _settingService.SaveSettingAsync(_emailAccountSettings);
return RedirectToAction("List");
}
[CheckPermission(StandardPermission.Configuration.MANAGE_EMAIL_ACCOUNTS)]
public virtual async Task<IActionResult> Create()
{
//prepare model
var model = await _emailAccountModelFactory.PrepareEmailAccountModelAsync(new EmailAccountModel(), null);
return View(model);
}
[HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")]
[CheckPermission(StandardPermission.Configuration.MANAGE_EMAIL_ACCOUNTS)]
public virtual async Task<IActionResult> Create(EmailAccountModel model, bool continueEditing)
{
if (ModelState.IsValid)
{
var emailAccount = model.ToEntity<EmailAccount>();
//set password manually
emailAccount.Password = model.Password;
await _emailAccountService.InsertEmailAccountAsync(emailAccount);
//activity log
await _customerActivityService.InsertActivityAsync("AddNewEmailAccount",
string.Format(await _localizationService.GetResourceAsync("ActivityLog.AddNewEmailAccount"), emailAccount.Id), emailAccount);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Configuration.EmailAccounts.Added"));
return continueEditing ? RedirectToAction("Edit", new { id = emailAccount.Id }) : RedirectToAction("List");
}
//prepare model
model = await _emailAccountModelFactory.PrepareEmailAccountModelAsync(model, null, true);
//if we got this far, something failed, redisplay form
return View(model);
}
[CheckPermission(StandardPermission.Configuration.MANAGE_EMAIL_ACCOUNTS)]
public virtual async Task<IActionResult> Edit(int id)
{
//try to get an email account with the specified id
var emailAccount = await _emailAccountService.GetEmailAccountByIdAsync(id);
if (emailAccount == null)
return RedirectToAction("List");
//prepare model
var model = await _emailAccountModelFactory.PrepareEmailAccountModelAsync(null, emailAccount);
if (emailAccount.EmailAuthenticationMethod == EmailAuthenticationMethod.GmailOAuth2)
model.AuthUrl = await PrepareOAuthUrlAsync(emailAccount);
return View(model);
}
[HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")]
[FormValueRequired("save", "save-continue")]
[CheckPermission(StandardPermission.Configuration.MANAGE_EMAIL_ACCOUNTS)]
public virtual async Task<IActionResult> Edit(EmailAccountModel model, bool continueEditing)
{
//try to get an email account with the specified id
var emailAccount = await _emailAccountService.GetEmailAccountByIdAsync(model.Id);
if (emailAccount == null)
return RedirectToAction("List");
if (ModelState.IsValid)
{
emailAccount = model.ToEntity(emailAccount);
await _emailAccountService.UpdateEmailAccountAsync(emailAccount);
//activity log
await _customerActivityService.InsertActivityAsync("EditEmailAccount",
string.Format(await _localizationService.GetResourceAsync("ActivityLog.EditEmailAccount"), emailAccount.Id), emailAccount);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Configuration.EmailAccounts.Updated"));
return continueEditing ? RedirectToAction("Edit", new { id = emailAccount.Id }) : RedirectToAction("List");
}
//prepare model
model = await _emailAccountModelFactory.PrepareEmailAccountModelAsync(model, emailAccount, true);
if (emailAccount.EmailAuthenticationMethod == EmailAuthenticationMethod.GmailOAuth2)
model.AuthUrl = await PrepareOAuthUrlAsync(emailAccount);
//if we got this far, something failed, redisplay form
return View(model);
}
[HttpPost, ActionName("Edit")]
[FormValueRequired("changesecret")]
[CheckPermission(StandardPermission.Configuration.MANAGE_EMAIL_ACCOUNTS)]
public virtual async Task<IActionResult> ChangeSecret(EmailAccountModel model)
{
//try to get an email account with the specified id
var emailAccount = await _emailAccountService.GetEmailAccountByIdAsync(model.Id);
if (emailAccount == null)
return RedirectToAction("List");
//do not validate model
emailAccount.ClientSecret = model.ClientSecret;
await _emailAccountService.UpdateEmailAccountAsync(emailAccount);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Configuration.EmailAccounts.Fields.ClientSecret.ClientSecretChanged"));
return RedirectToAction("Edit", new { id = emailAccount.Id });
}
[HttpPost, ActionName("Edit")]
[FormValueRequired("changepassword")]
[CheckPermission(StandardPermission.Configuration.MANAGE_EMAIL_ACCOUNTS)]
public virtual async Task<IActionResult> ChangePassword(EmailAccountModel model)
{
//try to get an email account with the specified id
var emailAccount = await _emailAccountService.GetEmailAccountByIdAsync(model.Id);
if (emailAccount == null)
return RedirectToAction("List");
//do not validate model
emailAccount.Password = model.Password;
await _emailAccountService.UpdateEmailAccountAsync(emailAccount);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Configuration.EmailAccounts.Fields.Password.PasswordChanged"));
return RedirectToAction("Edit", new { id = emailAccount.Id });
}
[HttpPost, ActionName("Edit")]
[FormValueRequired("sendtestemail")]
[CheckPermission(StandardPermission.Configuration.MANAGE_EMAIL_ACCOUNTS)]
public virtual async Task<IActionResult> SendTestEmail(EmailAccountModel model)
{
//try to get an email account with the specified id
var emailAccount = await _emailAccountService.GetEmailAccountByIdAsync(model.Id);
if (emailAccount == null)
return RedirectToAction("List");
if (!CommonHelper.IsValidEmail(model.SendTestEmailTo))
{
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Common.WrongEmail"));
return View(await _emailAccountModelFactory.PrepareEmailAccountModelAsync(model, emailAccount, true));
}
try
{
if (string.IsNullOrWhiteSpace(model.SendTestEmailTo))
throw new NopException("Enter test email address");
var store = await _storeContext.GetCurrentStoreAsync();
var subject = store.Name + ". Testing email functionality.";
var body = "Email works fine.";
await _emailSender.SendEmailAsync(emailAccount, subject, body, emailAccount.Email, emailAccount.DisplayName, model.SendTestEmailTo, null);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Configuration.EmailAccounts.SendTestEmail.Success"));
return RedirectToAction("Edit", new { id = emailAccount.Id });
}
catch (Exception exc)
{
_notificationService.ErrorNotification(exc.Message);
}
//prepare model
model = await _emailAccountModelFactory.PrepareEmailAccountModelAsync(model, emailAccount, true);
//if we got this far, something failed, redisplay form
return View(model);
}
[HttpPost]
[CheckPermission(StandardPermission.Configuration.MANAGE_EMAIL_ACCOUNTS)]
public virtual async Task<IActionResult> Delete(int id)
{
//try to get an email account with the specified id
var emailAccount = await _emailAccountService.GetEmailAccountByIdAsync(id);
if (emailAccount == null)
return RedirectToAction("List");
try
{
await _emailAccountService.DeleteEmailAccountAsync(emailAccount);
//activity log
await _customerActivityService.InsertActivityAsync("DeleteEmailAccount",
string.Format(await _localizationService.GetResourceAsync("ActivityLog.DeleteEmailAccount"), emailAccount.Id), emailAccount);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Configuration.EmailAccounts.Deleted"));
return RedirectToAction("List");
}
catch (Exception exc)
{
await _notificationService.ErrorNotificationAsync(exc);
return RedirectToAction("Edit", new { id = emailAccount.Id });
}
}
public virtual async Task<IActionResult> AuthReturn(AuthorizationCodeResponseUrl authorizationCode)
{
if (string.IsNullOrEmpty(authorizationCode.State))
return RedirectToAction(nameof(List));
var strAccountId = authorizationCode.State.Split(SEPARATOR).FirstOrDefault();
if (!int.TryParse(strAccountId, out var accountId) ||
await _emailAccountService.GetEmailAccountByIdAsync(accountId) is not EmailAccount emailAccount)
{
_notificationService.ErrorNotification("Email account could not be loaded");
return RedirectToAction(nameof(List));
}
if (!string.IsNullOrEmpty(authorizationCode.Error))
{
_notificationService.ErrorNotification(authorizationCode.Error);
return RedirectToAction(nameof(Edit), new { id = emailAccount.Id });
}
if (string.IsNullOrEmpty(authorizationCode?.Code))
return RedirectToAction(nameof(Edit), new { id = emailAccount.Id });
var tokenFilePath = _fileProvider.MapPath(NopMessageDefaults.GmailAuthStorePath);
var credentialRoot = _fileProvider.Combine(tokenFilePath, emailAccount.Email);
var flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = emailAccount.ClientId,
ClientSecret = emailAccount.ClientSecret
},
Scopes = NopMessageDefaults.GmailScopes,
DataStore = new FileDataStore(credentialRoot, true)
});
var redirectUri = Url.Action(nameof(AuthReturn), null, null, _webHelper.GetCurrentRequestProtocol());
var tokenResponse = await flow.ExchangeCodeForTokenAsync(emailAccount.Email, authorizationCode.Code, redirectUri, CancellationToken.None);
if (tokenResponse is null || tokenResponse.IsStale)
return RedirectToAction(nameof(Edit), new { id = emailAccount.Id });
_notificationService.SuccessNotification("The token was successfully retrieved from the server");
return RedirectToAction(nameof(Edit), new { id = emailAccount.Id });
}
#endregion
}