diff --git a/src/OrchardCoreContrib.Users/AdminMenu.cs b/src/OrchardCoreContrib.Users/AdminMenu.cs
index be5ea268..af590391 100644
--- a/src/OrchardCoreContrib.Users/AdminMenu.cs
+++ b/src/OrchardCoreContrib.Users/AdminMenu.cs
@@ -3,51 +3,42 @@
using OrchardCore.Modules;
using OrchardCore.Mvc.Core.Utilities;
using OrchardCore.Navigation;
-using OrchardCoreContrib.Navigation;
using OrchardCoreContrib.Users.Controllers;
-namespace OrchardCoreContrib.Users
-{
- using OrchardCoreContrib.Navigation;
+namespace OrchardCoreContrib.Users;
- ///
- /// Represents an admin menu for the impersonation feature.
- ///
- [Feature("OrchardCoreContrib.Users.Impersonation")]
- public class AdminMenu : AdminNavigationProvider
- {
- private readonly HttpContext _httpContext;
- private readonly IStringLocalizer S;
+using OrchardCoreContrib.Navigation;
- ///
- /// Initializes a new instance of .
- ///
- /// The .
- public AdminMenu(
- IHttpContextAccessor httpContextAccessor,
- IStringLocalizer localizer)
- {
- _httpContext = httpContextAccessor.HttpContext;
- S = localizer;
- }
+///
+/// Represents an admin menu for the impersonation feature.
+///
+///
+/// Initializes a new instance of .
+///
+/// The .
+[Feature("OrchardCoreContrib.Users.Impersonation")]
+public class AdminMenu(
+ IHttpContextAccessor httpContextAccessor,
+ IStringLocalizer S) : AdminNavigationProvider
+{
+ private readonly HttpContext _httpContext = httpContextAccessor.HttpContext;
- ///
- public override void BuildNavigation(NavigationBuilder builder)
+ ///
+ public override void BuildNavigation(NavigationBuilder builder)
+ {
+ var isImpersonatingClaim = _httpContext.User.FindFirst(ClaimTypesExtended.IsImpersonating);
+
+ if (isImpersonatingClaim?.Value == "true")
{
- var isImpersonatingClaim = _httpContext.User.FindFirst(ClaimTypesExtended.IsImpersonating);
-
- if (isImpersonatingClaim?.Value == "true")
- {
- builder
- .Add(S["Security"], NavigationConstants.AdminMenuSecurityPosition, security => security
- .AddClass("security").Id("security")
- .Add(S["End Impersonation"], S["End Impersonation"].PrefixPosition(), users => users
- .AddClass("endImpersonation").Id("endImpersonation")
- .Action(nameof(ImpersonationController.EndImpersonatation), typeof(ImpersonationController).ControllerName(), "OrchardCoreContrib.Users")
- .LocalNav()
- )
- );
- }
+ builder
+ .Add(S["Security"], NavigationConstants.AdminMenuSecurityPosition, security => security
+ .AddClass("security").Id("security")
+ .Add(S["End Impersonation"], S["End Impersonation"].PrefixPosition(), users => users
+ .AddClass("endImpersonation").Id("endImpersonation")
+ .Action(nameof(ImpersonationController.EndImpersonatation), typeof(ImpersonationController).ControllerName(), "OrchardCoreContrib.Users")
+ .LocalNav()
+ )
+ );
}
}
}
diff --git a/src/OrchardCoreContrib.Users/ClaimTypesExtended.cs b/src/OrchardCoreContrib.Users/ClaimTypesExtended.cs
index 52fbf9b3..bf945d56 100644
--- a/src/OrchardCoreContrib.Users/ClaimTypesExtended.cs
+++ b/src/OrchardCoreContrib.Users/ClaimTypesExtended.cs
@@ -1,18 +1,17 @@
-namespace OrchardCoreContrib.Users
+namespace OrchardCoreContrib.Users;
+
+///
+/// Represents a claim types that be used for impersonation process.
+///
+public static class ClaimTypesExtended
{
///
- /// Represents a claim types that be used for impersonation process.
+ /// Gets the impersonator name.
///
- public static class ClaimTypesExtended
- {
- ///
- /// Gets the impersonator name.
- ///
- public static readonly string ImpersonatorNameIdentifier = nameof(ImpersonatorNameIdentifier);
+ public static readonly string ImpersonatorNameIdentifier = nameof(ImpersonatorNameIdentifier);
- ///
- /// Gets whether the current user is impersonated or not.
- ///
- public static readonly string IsImpersonating = nameof(IsImpersonating);
- }
+ ///
+ /// Gets whether the current user is impersonated or not.
+ ///
+ public static readonly string IsImpersonating = nameof(IsImpersonating);
}
diff --git a/src/OrchardCoreContrib.Users/Controllers/ImpersonationController.cs b/src/OrchardCoreContrib.Users/Controllers/ImpersonationController.cs
index 0743d9bf..86e0d664 100644
--- a/src/OrchardCoreContrib.Users/Controllers/ImpersonationController.cs
+++ b/src/OrchardCoreContrib.Users/Controllers/ImpersonationController.cs
@@ -2,91 +2,71 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OrchardCore.Admin;
using OrchardCore.Modules;
using OrchardCore.Users;
-using System.Linq;
using System.Security.Claims;
-using System.Threading.Tasks;
-namespace OrchardCoreContrib.Users.Controllers
+namespace OrchardCoreContrib.Users.Controllers;
+
+[Authorize]
+[Feature("OrchardCoreContrib.Users.Impersonation")]
+public class ImpersonationController(
+ SignInManager signInManager,
+ UserManager userManager,
+ IAuthorizationService authorizationService,
+ IOptions adminOptions,
+ ILogger logger) : Controller
{
- [Authorize]
- [Feature("OrchardCoreContrib.Users.Impersonation")]
- public class ImpersonationController : Controller
+ private readonly AdminOptions _adminOptions = adminOptions.Value;
+
+ public async Task ImpersonateUser(string userId)
{
- private readonly SignInManager _signInManager;
- private readonly UserManager _userManager;
- private readonly IAuthorizationService _authorizationService;
- private readonly AdminOptions _adminOptions;
- private readonly ILogger _logger;
- private readonly IStringLocalizer S;
-
- public ImpersonationController(
- SignInManager signInManager,
- UserManager userManager,
- IAuthorizationService authorizationService,
- IOptions adminOptions,
- ILogger logger,
- IStringLocalizer stringLocalizer)
+ if (!await authorizationService.AuthorizeAsync(User, UsersPermissions.ManageImpersonationSettings))
{
- _signInManager = signInManager;
- _userManager = userManager;
- _authorizationService = authorizationService;
- _adminOptions = adminOptions.Value;
- _logger = logger;
- S = stringLocalizer;
+ return Forbid();
}
- public async Task ImpersonateUser(string userId)
- {
- if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageImpersonationSettings))
- {
- return Forbid();
- }
+ var currentUserId = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
+ var impersonatedUser = await userManager.FindByIdAsync(userId);
+ var impersonatedUserPrincipal = await signInManager.CreateUserPrincipalAsync(impersonatedUser);
- var currentUserId = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
- var impersonatedUser = await _userManager.FindByIdAsync(userId);
- var impersonatedUserPrincipal = await _signInManager.CreateUserPrincipalAsync(impersonatedUser);
+ impersonatedUserPrincipal.Identities.First().AddClaim(new Claim(ClaimTypesExtended.ImpersonatorNameIdentifier, currentUserId));
+ impersonatedUserPrincipal.Identities.First().AddClaim(new Claim(ClaimTypesExtended.IsImpersonating, "true"));
- impersonatedUserPrincipal.Identities.First().AddClaim(new Claim(ClaimTypesExtended.ImpersonatorNameIdentifier, currentUserId));
- impersonatedUserPrincipal.Identities.First().AddClaim(new Claim(ClaimTypesExtended.IsImpersonating, "true"));
+ await signInManager.SignOutAsync();
+ await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, impersonatedUserPrincipal);
- await _signInManager.SignOutAsync();
- await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, impersonatedUserPrincipal);
+ logger.LogInformation(1, "User '{0}' logged as '{1}'.", User.Identity.Name, impersonatedUser.UserName);
- _logger.LogInformation(1, S["User '{0}' logged as '{1}'.", User.Identity.Name, impersonatedUser.UserName]);
-
- return Redirect($"~/{_adminOptions.AdminUrlPrefix}");
- }
+ return Redirect($"~/{_adminOptions.AdminUrlPrefix}");
+ }
- public async Task EndImpersonatation()
+ public async Task EndImpersonatation()
+ {
+ var isImpersonatingClaim = HttpContext.User.FindFirst(ClaimTypesExtended.IsImpersonating);
+ if (isImpersonatingClaim == null || isImpersonatingClaim?.Value != "true")
{
- var isImpersonatingClaim = HttpContext.User.FindFirst(ClaimTypesExtended.IsImpersonating);
- if (isImpersonatingClaim == null || isImpersonatingClaim?.Value != "true")
- {
- return Forbid();
- }
+ return Forbid();
+ }
- var impersonatorUserId = HttpContext.User.Claims.First(c => c.Type == ClaimTypesExtended.ImpersonatorNameIdentifier).Value;
+ var impersonatorUserId = HttpContext.User.Claims.First(c => c.Type == ClaimTypesExtended.ImpersonatorNameIdentifier).Value;
- var impersonatedUserId = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
- var impersonatedUser = await _userManager.FindByIdAsync(impersonatedUserId);
- var impersonatedUserPrincipal = await _signInManager.CreateUserPrincipalAsync(impersonatedUser);
+ var impersonatedUserId = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
+ var impersonatedUser = await userManager.FindByIdAsync(impersonatedUserId);
+ var impersonatedUserPrincipal = await signInManager.CreateUserPrincipalAsync(impersonatedUser);
- await _signInManager.SignOutAsync();
+ await signInManager.SignOutAsync();
- var impersonaterUser = await _userManager.FindByIdAsync(impersonatorUserId);
- var impersonaterUserPrincipal = await _signInManager.CreateUserPrincipalAsync(impersonaterUser);
+ var impersonaterUser = await userManager.FindByIdAsync(impersonatorUserId);
+ var impersonaterUserPrincipal = await signInManager.CreateUserPrincipalAsync(impersonaterUser);
- await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, impersonaterUserPrincipal);
+ await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, impersonaterUserPrincipal);
- _logger.LogInformation(1, S["Swicthed back to the '{0}' user.", impersonaterUser.UserName]);
+ logger.LogInformation(1, "Swicthed back to the '{0}' user.", impersonaterUser.UserName);
- return Redirect($"~/{_adminOptions.AdminUrlPrefix}");
- }
+ return Redirect($"~/{_adminOptions.AdminUrlPrefix}");
}
}
diff --git a/src/OrchardCoreContrib.Users/Drivers/ImpersonationDisplayDriver.cs b/src/OrchardCoreContrib.Users/Drivers/ImpersonationDisplayDriver.cs
index 9f78c265..0883f041 100644
--- a/src/OrchardCoreContrib.Users/Drivers/ImpersonationDisplayDriver.cs
+++ b/src/OrchardCoreContrib.Users/Drivers/ImpersonationDisplayDriver.cs
@@ -1,4 +1,6 @@
-using OrchardCore.DisplayManagement.Handlers;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using OrchardCore.DisplayManagement.Handlers;
using OrchardCore.DisplayManagement.Views;
using OrchardCore.Modules;
using OrchardCore.Users.Models;
@@ -7,9 +9,20 @@
namespace OrchardCoreContrib.Users.Drivers;
[Feature("OrchardCoreContrib.Users.Impersonation")]
-public class ImpersonationDisplayDriver : DisplayDriver
+public class ImpersonationDisplayDriver(
+ IHttpContextAccessor httpContextAccessor,
+ IAuthorizationService authorizationService) : DisplayDriver
{
- public override IDisplayResult Display(User user, BuildDisplayContext context)
- => Initialize("ImpersonationButton", model => model.User = user)
+ private readonly HttpContext _httpContext = httpContextAccessor.HttpContext;
+
+ public async override Task DisplayAsync(User user, BuildDisplayContext context)
+ {
+ if (!await authorizationService.AuthorizeAsync(_httpContext.User, UsersPermissions.ManageImpersonationSettings))
+ {
+ return null;
+ }
+
+ return Initialize("ImpersonationButton", model => model.User = user)
.Location("SummaryAdmin", "Actions:2");
+ }
}
diff --git a/src/OrchardCoreContrib.Users/Manifest.cs b/src/OrchardCoreContrib.Users/Manifest.cs
index 804d8fcb..ef08a47c 100644
--- a/src/OrchardCoreContrib.Users/Manifest.cs
+++ b/src/OrchardCoreContrib.Users/Manifest.cs
@@ -5,7 +5,7 @@
Name = "Users",
Author = ManifestConstants.Author,
Website = ManifestConstants.Website,
- Version = "1.5.1",
+ Version = "1.7.0",
Category = "Security"
)]
diff --git a/src/OrchardCoreContrib.Users/OrchardCoreContrib.Users.csproj b/src/OrchardCoreContrib.Users/OrchardCoreContrib.Users.csproj
index 50e230a1..978e56d8 100644
--- a/src/OrchardCoreContrib.Users/OrchardCoreContrib.Users.csproj
+++ b/src/OrchardCoreContrib.Users/OrchardCoreContrib.Users.csproj
@@ -2,10 +2,11 @@
true
- 1.6.0
+ 1.7.0
The Orchard Core Contrib Team
Provides a list of users features such as Impersonation.
+ README.md
BSD-3-Clause
https://github.com/OrchardCoreContrib/OrchardCoreContrib.Modules/tree/main/src/OrchardCoreContrib.Users/README.md
https://github.com/OrchardCoreContrib/OrchardCoreContrib.Modules
@@ -26,6 +27,7 @@
+
diff --git a/src/OrchardCoreContrib.Users/Permissions.cs b/src/OrchardCoreContrib.Users/Permissions.cs
index 658adce6..162af4a9 100644
--- a/src/OrchardCoreContrib.Users/Permissions.cs
+++ b/src/OrchardCoreContrib.Users/Permissions.cs
@@ -1,44 +1,32 @@
using OrchardCore.Modules;
-using OrchardCore.Security;
using OrchardCore.Security.Permissions;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-namespace OrchardCoreContrib.Users
+namespace OrchardCoreContrib.Users;
+
+///
+/// Represents a permissions that will be applied into users module.
+///
+[Feature("OrchardCoreContrib.Users.Impersonation")]
+public class Permissions : IPermissionProvider
{
- ///
- /// Represents a permissions that will be applied into users module.
- ///
- [Feature("OrchardCoreContrib.Users.Impersonation")]
- public class Permissions : IPermissionProvider
- {
- ///
- /// Gets a permission for managing a impersonation settings.
- ///
- public static readonly Permission ManageImpersonationSettings = new Permission("ManageImpersonationSettings", "Manage Impersonation Settings", isSecurityCritical: true);
+ private readonly IEnumerable _allPermissions =
+ [
+ UsersPermissions.ManageImpersonationSettings,
+ ];
- ///
- public Task> GetPermissionsAsync()
- {
- return Task.FromResult(new[]
- {
- ManageImpersonationSettings
- }
- .AsEnumerable());
- }
+ ///
+ public Task> GetPermissionsAsync() => Task.FromResult(_allPermissions);
- ///
- public IEnumerable GetDefaultStereotypes()
- {
- return new[]
+ ///
+ public IEnumerable GetDefaultStereotypes()
+ {
+ return
+ [
+ new PermissionStereotype
{
- new PermissionStereotype
- {
- Name = "Administrator",
- Permissions = new[] { ManageImpersonationSettings, StandardPermissions.SiteOwner }
- },
- };
- }
+ Name = "Administrator",
+ Permissions = _allPermissions
+ },
+ ];
}
}
diff --git a/src/OrchardCoreContrib.Users/README.md b/src/OrchardCoreContrib.Users/README.md
index 80bf61e3..2fbc4184 100644
--- a/src/OrchardCoreContrib.Users/README.md
+++ b/src/OrchardCoreContrib.Users/README.md
@@ -4,7 +4,7 @@ This module provides features for users management.
## Version
-1.5.1
+1.7.0
## Category
@@ -34,6 +34,7 @@ Security
| Name | Version |
|---------------------------------------------------------------------------------------------|---------|
+| [`OrchardCoreContrib.Users`](https://www.nuget.org/packages/OrchardCoreContrib.Users/1.7.0) | 1.7.0 |
| [`OrchardCoreContrib.Users`](https://www.nuget.org/packages/OrchardCoreContrib.Users/1.6.0) | 1.6.0 |
| [`OrchardCoreContrib.Users`](https://www.nuget.org/packages/OrchardCoreContrib.Users/1.5.1) | 1.5.1 |
| [`OrchardCoreContrib.Users`](https://www.nuget.org/packages/OrchardCoreContrib.Users/1.5.0) | 1.5.0 |
diff --git a/src/OrchardCoreContrib.Users/Services/AvatarService.cs b/src/OrchardCoreContrib.Users/Services/AvatarService.cs
index 4ba696e4..23efd3f6 100644
--- a/src/OrchardCoreContrib.Users/Services/AvatarService.cs
+++ b/src/OrchardCoreContrib.Users/Services/AvatarService.cs
@@ -1,25 +1,17 @@
using Microsoft.Extensions.Options;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Drawing;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
-using System;
-using System.IO;
namespace OrchardCoreContrib.Users.Services;
-public class AvatarService : IAvatarService
+public class AvatarService(IOptions avatarOptions) : IAvatarService
{
- private readonly AvatarOptions _avatarOptions;
-
- public AvatarService(IOptions avatarOptions)
- {
- _avatarOptions = avatarOptions.Value;
- }
+ private readonly AvatarOptions _avatarOptions = avatarOptions.Value;
public string Generate(string userName)
{
diff --git a/src/OrchardCoreContrib.Users/Services/NullAvatarService.cs b/src/OrchardCoreContrib.Users/Services/NullAvatarService.cs
index ad46cd9e..5bcabc10 100644
--- a/src/OrchardCoreContrib.Users/Services/NullAvatarService.cs
+++ b/src/OrchardCoreContrib.Users/Services/NullAvatarService.cs
@@ -1,8 +1,6 @@
-using System;
-
-namespace OrchardCoreContrib.Users.Services;
+namespace OrchardCoreContrib.Users.Services;
public class NullAvatarService : IAvatarService
{
- public string Generate(string userName) => String.Empty;
+ public string Generate(string userName) => string.Empty;
}
diff --git a/src/OrchardCoreContrib.Users/Startup.cs b/src/OrchardCoreContrib.Users/Startup.cs
index eaced249..b318c0dc 100644
--- a/src/OrchardCoreContrib.Users/Startup.cs
+++ b/src/OrchardCoreContrib.Users/Startup.cs
@@ -13,84 +13,73 @@
using OrchardCoreContrib.Users.Controllers;
using OrchardCoreContrib.Users.Drivers;
using OrchardCoreContrib.Users.Services;
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-namespace OrchardCoreContrib.Users
+namespace OrchardCoreContrib.Users;
+
+///
+/// Represents an entry point to register the impersonation required services.
+///
+///
+/// Initializes a new instance of .
+///
+/// The adminOptions) : StartupBase
{
- ///
- /// Represents an entry point to register the impersonation required services.
- ///
- [Feature("OrchardCoreContrib.Users.Impersonation")]
- public class ImpersonationStartup : StartupBase
- {
- private readonly AdminOptions _adminOptions;
+ private readonly AdminOptions _adminOptions = adminOptions.Value;
- ///
- /// Initializes a new instance of .
- ///
- /// The
- public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
- {
- routes.MapAreaControllerRoute(
- name: "UsersImpersonateUser",
- areaName: "OrchardCoreContrib.Users",
- pattern: _adminOptions.AdminUrlPrefix + "/Users/Impersonate",
- defaults: new { controller = typeof(ImpersonationController).ControllerName(), action = nameof(ImpersonationController.ImpersonateUser) }
- );
- }
+ ///
+ public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
+ {
+ routes.MapAreaControllerRoute(
+ name: "UsersImpersonateUser",
+ areaName: "OrchardCoreContrib.Users",
+ pattern: _adminOptions.AdminUrlPrefix + "/Users/Impersonate",
+ defaults: new
+ {
+ controller = typeof(ImpersonationController).ControllerName(),
+ action = nameof(ImpersonationController.ImpersonateUser)
+ }
+ );
}
+}
+
+///
+/// Represents an entry point to register the user avatar required services.
+///
+[Feature("OrchardCoreContrib.Users.Avatar")]
+public class UserAvatarStartup(IShellConfiguration shellConfiguration) : StartupBase
+{
- ///
- /// Represents an entry point to register the user avatar required services.
- ///
- [Feature("OrchardCoreContrib.Users.Avatar")]
- public class UserAvatarStartup : StartupBase
+ ///
+ public override void ConfigureServices(IServiceCollection services)
{
- private readonly IShellConfiguration _shellConfiguration;
+ services.AddScoped();
- public UserAvatarStartup(IShellConfiguration shellConfiguration)
- {
- _shellConfiguration = shellConfiguration;
- }
-
- ///
- public override void ConfigureServices(IServiceCollection services)
- {
- services.AddScoped();
-
- services.Configure(_shellConfiguration.GetSection("OrchardCoreContrib_Users_AvatarOptions"));
- }
+ services.Configure(shellConfiguration.GetSection("OrchardCoreContrib_Users_AvatarOptions"));
}
}
diff --git a/src/OrchardCoreContrib.Users/UsersPermissions.cs b/src/OrchardCoreContrib.Users/UsersPermissions.cs
new file mode 100644
index 00000000..a9398155
--- /dev/null
+++ b/src/OrchardCoreContrib.Users/UsersPermissions.cs
@@ -0,0 +1,14 @@
+using OrchardCore.Security.Permissions;
+
+namespace OrchardCoreContrib.Users;
+
+///
+/// Provides predefined permissions related to Users module.
+///
+public class UsersPermissions
+{
+ ///
+ /// Gets a permission for managing a impersonation settings.
+ ///
+ public static readonly Permission ManageImpersonationSettings = new("ManageImpersonationSettings", "Manage Impersonation Settings", isSecurityCritical: true);
+}