Skip to content

Commit

Permalink
Merge pull request #64 from Lombiq/issue/NEST-391
Browse files Browse the repository at this point in the history
NEST-391: Maintenance to make a role site owner
  • Loading branch information
wAsnk authored May 30, 2023
2 parents aa75956 + 2d35147 commit 3c752dd
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,19 @@ public static void SetUpdateSiteUrlMaintenanceConfiguration(

return Task.CompletedTask;
};

public static void SetAddSiteOwnerPermissionToRoleMaintenanceConfiguration(
this OrchardCoreUITestExecutorConfiguration configuration) => configuration.OrchardCoreConfiguration.BeforeAppStart +=
(_, argumentsBuilder) =>
{
argumentsBuilder
.AddWithValue(
"OrchardCore:Lombiq_Hosting_Tenants_Maintenance:AddSiteOwnerPermissionToRole:IsEnabled",
value: true)
.AddWithValue(
"OrchardCore:Lombiq_Hosting_Tenants_Maintenance:AddSiteOwnerPermissionToRole:Role",
value: "Editor");

return Task.CompletedTask;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,11 @@ public static async Task TestSiteUrlMaintenanceExecutionAsync(this UITestContext
await context.GoToAdminRelativeUrlAsync("/Settings/general");
context.Get(By.Name("ISite.BaseUrl")).GetValue().ShouldBe("https://test.com");
}

public static async Task TestSiteOwnerPermissionToRoleMaintenanceExecutionAsync(this UITestContext context)
{
await context.SignInDirectlyAsync();
await context.GoToAdminRelativeUrlAsync("/Roles/Edit/Editor");
context.Get(By.Id("Checkbox.SiteOwner")).GetDomProperty("checked").ShouldBe(bool.TrueString);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public static class FeatureNames
public const string Maintenance = Module;
public const string UpdateSiteUrl = Maintenance + "." + nameof(UpdateSiteUrl);
public const string UpdateShellRequestUrls = Maintenance + "." + nameof(UpdateShellRequestUrls);
public const string AddSiteOwnerPermissionToRole = Maintenance + "." + nameof(AddSiteOwnerPermissionToRole);
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,12 @@
<None Remove="Tests\**" />
</ItemGroup>

<ItemGroup Condition="'$(NuGetBuild)' != 'true'">
<ProjectReference Include="..\..\..\Libraries\Lombiq.HelpfulLibraries\Lombiq.HelpfulLibraries.Common\Lombiq.HelpfulLibraries.Common.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(NuGetBuild)' == 'true'">
<PackageReference Include="Lombiq.HelpfulLibraries.Common" Version="5.1.1" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Lombiq.Hosting.Tenants.Maintenance.Maintenance.AddSiteOwnerPermissionToRole;

public class AddSiteOwnerPermissionToRoleMaintenanceOptions
{
public bool IsEnabled { get; set; }
public string Role { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Lombiq.Hosting.Tenants.Maintenance.Extensions;
using Lombiq.Hosting.Tenants.Maintenance.Models;
using Lombiq.Hosting.Tenants.Maintenance.Services;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using OrchardCore.Security;
using System.Linq;
using System.Threading.Tasks;
using static OrchardCore.Security.Permissions.Permission;
using static OrchardCore.Security.StandardPermissions;

namespace Lombiq.Hosting.Tenants.Maintenance.Maintenance.AddSiteOwnerPermissionToRole;

public class AddSiteOwnerPermissionToRoleMaintenanceProvider : MaintenanceProviderBase
{
private readonly IOptions<AddSiteOwnerPermissionToRoleMaintenanceOptions> _options;
private readonly RoleManager<IRole> _roleManager;

public AddSiteOwnerPermissionToRoleMaintenanceProvider(
IOptions<AddSiteOwnerPermissionToRoleMaintenanceOptions> options,
RoleManager<IRole> roleManager)
{
_options = options;
_roleManager = roleManager;
}

public override Task<bool> ShouldExecuteAsync(MaintenanceTaskExecutionContext context) =>
Task.FromResult(
_options.Value.IsEnabled &&
!context.WasLatestExecutionSuccessful());

public override async Task ExecuteAsync(MaintenanceTaskExecutionContext context)
{
if (await _roleManager.FindByNameAsync(_options.Value.Role) is not Role role) return;

if (role.RoleClaims.Any(claim => claim.ClaimType == ClaimType && claim.ClaimValue == SiteOwner.Name)) return;

role.RoleClaims.Add(new RoleClaim { ClaimType = ClaimType, ClaimValue = SiteOwner.Name });

await _roleManager.UpdateAsync(role);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Lombiq.Hosting.Tenants.Maintenance.Constants;
using Lombiq.Hosting.Tenants.Maintenance.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.Environment.Shell.Configuration;
using OrchardCore.Modules;

namespace Lombiq.Hosting.Tenants.Maintenance.Maintenance.AddSiteOwnerPermissionToRole;

[Feature(FeatureNames.AddSiteOwnerPermissionToRole)]
public class Startup : StartupBase
{
private readonly IShellConfiguration _shellConfiguration;

public Startup(IShellConfiguration shellConfiguration) =>
_shellConfiguration = shellConfiguration;

public override void ConfigureServices(IServiceCollection services)
{
var options = new AddSiteOwnerPermissionToRoleMaintenanceOptions();
var configSection = _shellConfiguration.GetSection("Lombiq_Hosting_Tenants_Maintenance:AddSiteOwnerPermissionToRole");
configSection.Bind(options);
services.Configure<AddSiteOwnerPermissionToRoleMaintenanceOptions>(configSection);

services.AddScoped<IMaintenanceProvider, AddSiteOwnerPermissionToRoleMaintenanceProvider>();
}
}
9 changes: 9 additions & 0 deletions Lombiq.Hosting.Tenants.Maintenance/Manifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,12 @@
DefaultTenantOnly = true,
Dependencies = new[] { Maintenance }
)]

[assembly: Feature(
Id = AddSiteOwnerPermissionToRole,
Name = "Lombiq Hosting - Tenants Maintenance - Add Site Owner Permission To Role",
Description = "Adds the Site Owner permission to a role (e.g., when the production database is copied to staging).",
Category = "Maintenance",
DefaultTenantOnly = true,
Dependencies = new[] { Maintenance }
)]
19 changes: 19 additions & 0 deletions Lombiq.Hosting.Tenants.Maintenance/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,25 @@ public void ConfigureServices(IServiceCollection services) =>

To add new maintenance tasks, you need to implement the `IMaintenanceProvider` interface and register it as a service.

### `Lombiq.Hosting.Tenants.Maintenance.AddSiteOwnerPermissionToRole`

It's a maintenance task that adds the `SiteOwner` permission to a role set in the app configuration. It is available on any tenant.

The following configuration options are available to set the role:

```json
{
"OrchardCore": {
"Lombiq_Hosting_Tenants_Maintenance": {
"AddSiteOwnerPermissionToRole": {
"IsEnabled": true,
"RoleName": "NameOfTheRole"
}
}
}
}
```

### `Lombiq.Hosting.Tenants.Maintenance.UpdateSiteUrl`

It's a maintenance task that updates the site's base URL in the site settings based on the app configuration. It is available on any tenant.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,26 @@
using Lombiq.Hosting.Tenants.Maintenance.Models;
using Microsoft.Extensions.Logging;
using OrchardCore.Environment.Shell;
using OrchardCore.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using YesSql;
using IOrchardClock = OrchardCore.Modules.IClock;

namespace Lombiq.Hosting.Tenants.Maintenance.Services;

public class MaintenanceManager : IMaintenanceManager
{
private readonly IClock _clock;
private readonly IOrchardClock _clock;
private readonly ILogger<MaintenanceManager> _logger;
private readonly IEnumerable<IMaintenanceProvider> _maintenanceProviders;
private readonly ISession _session;
private readonly IShellHost _shellHost;
private readonly ShellSettings _shellSettings;

public MaintenanceManager(
IClock clock,
IOrchardClock clock,
ILogger<MaintenanceManager> logger,
IEnumerable<IMaintenanceProvider> maintenanceProviders,
ISession session,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using OrchardCore.Environment.Shell;
using OrchardCore.Environment.Shell.Models;
using OrchardCore.Modules;
using System;
using System.Threading.Tasks;

namespace Lombiq.Hosting.Tenants.Maintenance.Services;
Expand All @@ -10,16 +11,16 @@ public class MaintenanceRunnerService : ModularTenantEvents
{
private readonly ShellSettings _shellSettings;
private readonly ILogger<MaintenanceRunnerService> _logger;
private readonly IMaintenanceManager _maintenanceManager;
private readonly Lazy<IMaintenanceManager> _maintenanceManagerLazy;

public MaintenanceRunnerService(
ShellSettings shellSettings,
ILogger<MaintenanceRunnerService> logger,
IMaintenanceManager maintenanceManager)
Lazy<IMaintenanceManager> maintenanceManagerLazy)
{
_shellSettings = shellSettings;
_logger = logger;
_maintenanceManager = maintenanceManager;
_maintenanceManagerLazy = maintenanceManagerLazy;
}

public override async Task ActivatedAsync()
Expand All @@ -29,6 +30,6 @@ public override async Task ActivatedAsync()
_logger.LogDebug(
"Executing maintenance tasks on shell '{ShellName}'.",
_shellSettings.Name);
await _maintenanceManager.ExecuteMaintenanceTasksAsync();
await _maintenanceManagerLazy.Value.ExecuteMaintenanceTasksAsync();
}
}
2 changes: 2 additions & 0 deletions Lombiq.Hosting.Tenants.Maintenance/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Lombiq.HelpfulLibraries.Common.DependencyInjection;
using Lombiq.Hosting.Tenants.Maintenance.Constants;
using Lombiq.Hosting.Tenants.Maintenance.Indexes;
using Lombiq.Hosting.Tenants.Maintenance.Services;
Expand All @@ -13,6 +14,7 @@ public class Startup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddLazyInjectionSupport();
services.Configure<StoreCollectionOptions>(options => options.Collections.Add(DocumentCollections.Maintenance));
services.AddScoped<IDataMigration, Migrations>();
services.AddSingleton<IIndexProvider, MaintenanceTaskExecutionIndexProvider>();
Expand Down

0 comments on commit 3c752dd

Please sign in to comment.