Skip to content

Commit

Permalink
Addressing warnings.
Browse files Browse the repository at this point in the history
  • Loading branch information
Psichorex committed Jan 20, 2024
1 parent d12a9f2 commit 5addb2e
Show file tree
Hide file tree
Showing 37 changed files with 278 additions and 613 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,45 +17,29 @@
namespace Lombiq.Hosting.Tenants.Admin.Login.Controllers;

[Feature(SubTenant)]
public class TenantLoginController : Controller
public class TenantLoginController(
ISiteService siteService,
SignInManager<IUser> userSignInManager,
IShellHost shellHost,
ShellSettings shellSettings,
ILogger<TenantLoginController> logger,
INotifier notifier,
IHtmlLocalizer<TenantLoginController> htmlLocalizer) : Controller
{
private readonly ISiteService _siteService;
private readonly SignInManager<IUser> _userSignInManager;
private readonly IShellHost _shellHost;
private readonly ShellSettings _shellSettings;
private readonly ILogger _logger;
private readonly INotifier _notifier;
private readonly IHtmlLocalizer H;

public TenantLoginController(
ISiteService siteService,
SignInManager<IUser> userSignInManager,
IShellHost shellHost,
ShellSettings shellSettings,
ILogger<TenantLoginController> logger,
INotifier notifier,
IHtmlLocalizer<TenantLoginController> htmlLocalizer)
{
_siteService = siteService;
_userSignInManager = userSignInManager;
_shellHost = shellHost;
_shellSettings = shellSettings;
_logger = logger;
_notifier = notifier;
H = htmlLocalizer;
}
private readonly ILogger _logger = logger;
private readonly IHtmlLocalizer H = htmlLocalizer;

[HttpPost]
// This is necessary because requests for this action will come from the Default tenant.
[IgnoreAntiforgeryToken]
public async Task<IActionResult> Index(string password)
{
if (_shellSettings.Name.EqualsOrdinalIgnoreCase(ShellSettings.DefaultShellName))
if (shellSettings.Name.EqualsOrdinalIgnoreCase(ShellSettings.DefaultShellName))
{
return NotFound();
}

var defaultShell = await _shellHost.GetScopeAsync(ShellSettings.DefaultShellName);
var defaultShell = await shellHost.GetScopeAsync(ShellSettings.DefaultShellName);
var tenantLoginPasswordValidator = defaultShell?.ServiceProvider.GetService<ITenantLoginPasswordValidator>();

if (defaultShell == null ||
Expand All @@ -65,17 +49,17 @@ public async Task<IActionResult> Index(string password)
return NotFound();
}

var sitesettings = await _siteService.LoadSiteSettingsAsync();
var adminUser = await _userSignInManager.UserManager.FindByIdAsync(sitesettings.SuperUser);
adminUser ??= (await _userSignInManager.UserManager.GetUsersInRoleAsync(Administrator)).FirstOrDefault();
var sitesettings = await siteService.LoadSiteSettingsAsync();
var adminUser = await userSignInManager.UserManager.FindByIdAsync(sitesettings.SuperUser);
adminUser ??= (await userSignInManager.UserManager.GetUsersInRoleAsync(Administrator)).FirstOrDefault();

if (adminUser == null)
{
await _notifier.ErrorAsync(H["No user with administrator role in this tenant."]);
await notifier.ErrorAsync(H["No user with administrator role in this tenant."]);
return Redirect("~/");
}

await _userSignInManager.SignInAsync(adminUser, isPersistent: false);
await userSignInManager.SignInAsync(adminUser, isPersistent: false);
_logger.LogInformation(1, "An admin user logged in from the Default tenant.");

return RedirectToAction("Index", "Admin", new { area = "OrchardCore.Admin" });
Expand Down
37 changes: 11 additions & 26 deletions Lombiq.Hosting.Tenants.Admin.Login/Filters/TenantsIndexFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,13 @@

namespace Lombiq.Hosting.Tenants.Admin.Login.Filters;

public class TenantsIndexFilter : IAsyncResultFilter
public class TenantsIndexFilter(
ILayoutAccessor layoutAccessor,
IShapeFactory shapeFactory,
IShellHost shellHost,
IHttpContextAccessor hca,
IAuthorizationService authorizationService) : IAsyncResultFilter
{
private readonly ILayoutAccessor _layoutAccessor;
private readonly IShapeFactory _shapeFactory;
private readonly IShellHost _shellHost;
private readonly IHttpContextAccessor _hca;
private readonly IAuthorizationService _authorizationService;

public TenantsIndexFilter(
ILayoutAccessor layoutAccessor,
IShapeFactory shapeFactory,
IShellHost shellHost,
IHttpContextAccessor hca,
IAuthorizationService authorizationService)
{
_layoutAccessor = layoutAccessor;
_shapeFactory = shapeFactory;
_shellHost = shellHost;
_hca = hca;
_authorizationService = authorizationService;
}

public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
var actionRouteController = context.ActionDescriptor.RouteValues["Controller"];
Expand All @@ -46,20 +31,20 @@ public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultE
actionRouteArea == $"{nameof(OrchardCore)}.{nameof(OrchardCore.Tenants)}" &&
actionRouteValue is nameof(AdminController.Edit) &&
context.Result is ViewResult &&
await _authorizationService.AuthorizeAsync(
_hca.HttpContext.User,
await authorizationService.AuthorizeAsync(
hca.HttpContext.User,
TenantAdminPermissions.LoginAsAdmin)
)
{
var shellSettings = _shellHost.GetSettings(context.RouteData.Values["Id"].ToString());
var shellSettings = shellHost.GetSettings(context.RouteData.Values["Id"].ToString());
if (shellSettings != null &&
shellSettings.State == TenantState.Running &&
!shellSettings.Name.EqualsOrdinalIgnoreCase(ShellSettings.DefaultShellName))
{
var layout = await _layoutAccessor.GetLayoutAsync();
var layout = await layoutAccessor.GetLayoutAsync();
var contentZone = layout.Zones["Content"];
await contentZone.AddAsync(
await _shapeFactory.CreateAsync("TenantAdminShape", new
await shapeFactory.CreateAsync("TenantAdminShape", new
{
shellSettings.RequestUrlHost,
shellSettings.RequestUrlPrefix,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,11 @@

namespace Lombiq.Hosting.Tenants.EmailQuotaManagement.Filters;

public class DashboardQuotaFilter : IAsyncResultFilter
public class DashboardQuotaFilter(
IShapeFactory shapeFactory,
ILayoutAccessor layoutAccessor,
IEmailQuotaService emailQuotaService) : IAsyncResultFilter
{
private readonly IShapeFactory _shapeFactory;
private readonly ILayoutAccessor _layoutAccessor;
private readonly IEmailQuotaService _emailQuotaService;

public DashboardQuotaFilter(
IShapeFactory shapeFactory,
ILayoutAccessor layoutAccessor,
IEmailQuotaService emailQuotaService)
{
_shapeFactory = shapeFactory;
_layoutAccessor = layoutAccessor;
_emailQuotaService = emailQuotaService;
}

public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
if (!context.IsAdmin())
Expand All @@ -32,19 +21,19 @@ public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultE
}

if (context.Result is ViewResult &&
_emailQuotaService.ShouldLimitEmails())
emailQuotaService.ShouldLimitEmails())
{
var currentEmailQuota = await _emailQuotaService.IsQuotaOverTheLimitAsync();
var currentEmailQuota = await emailQuotaService.IsQuotaOverTheLimitAsync();

var currentUsagePercentage = currentEmailQuota.EmailQuota
.CurrentUsagePercentage(_emailQuotaService.GetEmailQuotaPerMonth());
.CurrentUsagePercentage(emailQuotaService.GetEmailQuotaPerMonth());

if (currentUsagePercentage >= 80)
{
var layout = await _layoutAccessor.GetLayoutAsync();
var layout = await layoutAccessor.GetLayoutAsync();
var contentZone = layout.Zones["Messages"];
await contentZone.AddAsync(
await _shapeFactory.CreateAsync("DashboardQuotaMessage", new
await shapeFactory.CreateAsync("DashboardQuotaMessage", new
{
currentEmailQuota.IsOverQuota,
UsagePercentage = currentUsagePercentage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,11 @@

namespace Lombiq.Hosting.Tenants.EmailQuotaManagement.Filters;

public class EmailSettingsQuotaFilter : IAsyncResultFilter
public class EmailSettingsQuotaFilter(
IShapeFactory shapeFactory,
ILayoutAccessor layoutAccessor,
IEmailQuotaService emailQuotaService) : IAsyncResultFilter
{
private readonly IShapeFactory _shapeFactory;
private readonly ILayoutAccessor _layoutAccessor;
private readonly IEmailQuotaService _emailQuotaService;

public EmailSettingsQuotaFilter(
IShapeFactory shapeFactory,
ILayoutAccessor layoutAccessor,
IEmailQuotaService emailQuotaService)
{
_shapeFactory = shapeFactory;
_layoutAccessor = layoutAccessor;
_emailQuotaService = emailQuotaService;
}

public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
if (!context.IsAdmin())
Expand All @@ -43,17 +32,17 @@ actionRouteValue is nameof(AdminController.Index) &&
context.Result is ViewResult &&
context.RouteData.Values.TryGetValue("GroupId", out var groupId) &&
(string)groupId == "email" &&
_emailQuotaService.ShouldLimitEmails())
emailQuotaService.ShouldLimitEmails())
{
var layout = await _layoutAccessor.GetLayoutAsync();
var layout = await layoutAccessor.GetLayoutAsync();
var contentZone = layout.Zones["Content"];

var quota = await _emailQuotaService.GetOrCreateCurrentQuotaAsync();
var quota = await emailQuotaService.GetOrCreateCurrentQuotaAsync();
await contentZone.AddAsync(
await _shapeFactory.CreateAsync("EmailSettingsQuotaMessage", new
await shapeFactory.CreateAsync("EmailSettingsQuotaMessage", new
{
quota.CurrentEmailUsageCount,
EmailQuotaPerMonth = _emailQuotaService.GetEmailQuotaPerMonth(),
EmailQuotaPerMonth = emailQuotaService.GetEmailQuotaPerMonth(),
}),
"0");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,54 +19,38 @@

namespace Lombiq.Hosting.Tenants.EmailQuotaManagement.Services;

public class EmailQuotaService : IEmailQuotaService
public class EmailQuotaService(
ISession session,
IOptions<EmailQuotaOptions> emailQuotaOptions,
IShellConfiguration shellConfiguration,
IOptions<SmtpSettings> smtpOptions,
IClock clock,
IRoleService roleService,
UserManager<IUser> userManager) : IEmailQuotaService
{
private readonly ISession _session;
private readonly EmailQuotaOptions _emailQuotaOptions;
private readonly IShellConfiguration _shellConfiguration;
private readonly SmtpSettings _smtpOptions;
private readonly IClock _clock;
private readonly IRoleService _roleService;
private readonly UserManager<IUser> _userManager;

public EmailQuotaService(
ISession session,
IOptions<EmailQuotaOptions> emailQuotaOptions,
IShellConfiguration shellConfiguration,
IOptions<SmtpSettings> smtpOptions,
IClock clock,
IRoleService roleService,
UserManager<IUser> userManager)
{
_session = session;
_emailQuotaOptions = emailQuotaOptions.Value;
_shellConfiguration = shellConfiguration;
_smtpOptions = smtpOptions.Value;
_clock = clock;
_roleService = roleService;
_userManager = userManager;
}
private readonly EmailQuotaOptions _emailQuotaOptions = emailQuotaOptions.Value;
private readonly SmtpSettings _smtpOptions = smtpOptions.Value;

public async Task<IEnumerable<string>> GetUserEmailsForEmailReminderAsync()
{
// Get users with site owner permission.
var roles = await _roleService.GetRolesAsync();
var roles = await roleService.GetRolesAsync();
var siteOwnerRoles = roles.Where(role =>
(role as Role)?.RoleClaims.Exists(claim =>
claim.ClaimType == ClaimType && claim.ClaimValue == SiteOwner.Name) == true);

var siteOwners = new List<IUser>();
foreach (var role in siteOwnerRoles)
{
siteOwners.AddRange(await _userManager.GetUsersInRoleAsync(role.RoleName));
siteOwners.AddRange(await userManager.GetUsersInRoleAsync(role.RoleName));
}

return siteOwners.Select(user => (user as User)?.Email);
}

public bool ShouldLimitEmails()
{
var originalHost = _shellConfiguration.GetValue<string>("SmtpSettings:Host");
var originalHost = shellConfiguration.GetValue<string>("SmtpSettings:Host");
return originalHost == _smtpOptions.Host;
}

Expand All @@ -82,31 +66,31 @@ public async Task<QuotaResult> IsQuotaOverTheLimitAsync()

public async Task<EmailQuota> GetOrCreateCurrentQuotaAsync()
{
var currentQuota = await _session.Query<EmailQuota>().FirstOrDefaultAsync();
var currentQuota = await session.Query<EmailQuota>().FirstOrDefaultAsync();

if (currentQuota != null) return currentQuota;

currentQuota = new EmailQuota
{
// Need to set default value otherwise the database might complain about being 01/01/0001 out of range.
LastReminderUtc = _clock.UtcNow.AddMonths(-1),
LastReminderUtc = clock.UtcNow.AddMonths(-1),
};
await _session.SaveAsync(currentQuota);
await session.SaveAsync(currentQuota);

return currentQuota;
}

public Task IncreaseEmailUsageAsync(EmailQuota emailQuota)
{
emailQuota.CurrentEmailUsageCount++;
return _session.SaveAsync(emailQuota);
return session.SaveAsync(emailQuota);
}

public Task SetQuotaOnEmailReminderAsync(EmailQuota emailQuota)
{
emailQuota.LastReminderUtc = _clock.UtcNow;
emailQuota.LastReminderUtc = clock.UtcNow;
emailQuota.LastReminderPercentage = emailQuota.CurrentUsagePercentage(GetEmailQuotaPerMonth());
return _session.SaveAsync(emailQuota);
return session.SaveAsync(emailQuota);
}

public bool ShouldSendReminderEmail(EmailQuota emailQuota, int currentUsagePercentage)
Expand All @@ -116,7 +100,7 @@ public bool ShouldSendReminderEmail(EmailQuota emailQuota, int currentUsagePerce
return false;
}

var isSameMonth = IsSameMonth(_clock.UtcNow, emailQuota.LastReminderUtc);
var isSameMonth = IsSameMonth(clock.UtcNow, emailQuota.LastReminderUtc);

if (!isSameMonth)
{
Expand All @@ -131,7 +115,7 @@ public bool ShouldSendReminderEmail(EmailQuota emailQuota, int currentUsagePerce
public Task ResetQuotaAsync(EmailQuota emailQuota)
{
emailQuota.CurrentEmailUsageCount = 0;
return _session.SaveAsync(emailQuota);
return session.SaveAsync(emailQuota);
}

public int GetEmailQuotaPerMonth() =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Localization;

namespace Lombiq.Hosting.Tenants.EmailQuotaManagement.Services;

public class EmailQuotaSubjectService : IEmailQuotaSubjectService
public class EmailQuotaSubjectService(IStringLocalizer<EmailQuotaSubjectService> stringLocalizer) : IEmailQuotaSubjectService
{
private readonly IStringLocalizer<EmailQuotaSubjectService> T;

public EmailQuotaSubjectService(IStringLocalizer<EmailQuotaSubjectService> stringLocalizer) =>
T = stringLocalizer;

public LocalizedString GetWarningEmailSubject(int percentage) =>
T["[Warning] Your site has used {0}% of its e-mail quota", percentage];
stringLocalizer["[Warning] Your site has used {0}% of its e-mail quota", percentage];

public LocalizedString GetExceededEmailSubject() =>
T["[Action Required] Your site has run over its e-mail quota"];
stringLocalizer["[Action Required] Your site has run over its e-mail quota"];
}
Loading

0 comments on commit 5addb2e

Please sign in to comment.