-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Support workday manager structure (#721)
- [x] New feature - [ ] Bug fix - [ ] High impact **Description of work:** Managers structure is changed when workday is rolled out. The manager will no longer be in the department he/she is maanger for. This means they are moved one level up. Logics we have where `isResourceOwner` is combined with `fullDepartment` cannot be used as is. **Testing:** - [ ] Can be tested - [ ] Automatic tests created / updated - [ ] Local tests are passing TBD, tests must be refactored as setup for manager structure will be more complex **Checklist:** - [ ] Considered automated tests - [ ] Considered updating specification / documentation - [ ] Considered work items - [ ] Considered security - [ ] Performed developer testing - [ ] Checklist finalized / ready for review --------- Co-authored-by: Jonathan Idland Olsnes <73334350+Jonathanio123@users.noreply.github.com>
- Loading branch information
1 parent
dd57b94
commit 687eac1
Showing
38 changed files
with
1,170 additions
and
543 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
src/backend/Fusion.Resources.Authorization/IAuthorizationRequirementExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using Fusion.AspNetCore.FluentAuthorization; | ||
using Fusion.Resources.Api.Authorization.Requirements; | ||
using Fusion.Resources.Authorization.Requirements; | ||
|
||
namespace Fusion.Resources | ||
{ | ||
public static class IAuthorizationRequirementExtensions | ||
{ | ||
public static IAuthorizationRequirementRule GlobalRoleAccess(this IAuthorizationRequirementRule builder, params string[] roles) | ||
{ | ||
return builder.AddRule(new GlobalRoleRequirement(roles)); | ||
} | ||
public static IAuthorizationRequirementRule AllGlobalRoleAccess(this IAuthorizationRequirementRule builder, params string[] roles) | ||
{ | ||
return builder.AddRule(new GlobalRoleRequirement(GlobalRoleRequirement.RoleRequirement.All, roles)); | ||
} | ||
|
||
/// <summary> | ||
/// Require that the user is a resource owner. | ||
/// The check uses the resource owner claims in the user profile. | ||
/// </summary> | ||
/// <remarks> | ||
/// <para> | ||
/// To include additional local adjustments a local claims transformer can be used to add new claims. | ||
/// Type="http://schemas.fusion.equinor.com/identity/claims/resourceowner" value="MY DEP PATH" | ||
/// </para> | ||
/// <para> | ||
/// The parents check will only work for the direct path. Other resource owners in sibling departments of a parent will not have access. | ||
/// Ex. Check "L1 L2.1 L3.1 L4.1", owner in L2.1 L3.1, L2.1, L1 will have access, but ex. L2.2 will not have. | ||
/// </para> | ||
/// </remarks> | ||
/// <param name="builder"></param> | ||
/// <param name="includeParents">Should resource owners in any of the direct parent departments have access</param> | ||
/// <param name="includeDescendants">Should anyone that is a resource owner in any of the sub departments have access</param> | ||
public static IAuthorizationRequirementRule BeResourceOwnerForDepartment(this IAuthorizationRequirementRule builder, string department, bool includeParents = false, bool includeDescendants = false) | ||
{ | ||
builder.AddRule(new BeResourceOwnerRequirement(department, includeParents, includeDescendants)); | ||
return builder; | ||
} | ||
} | ||
} |
91 changes: 91 additions & 0 deletions
91
src/backend/Fusion.Resources.Authorization/Requirements/BeResourceOwnerRequirement.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
using Fusion.Authorization; | ||
using Microsoft.AspNetCore.Authorization; | ||
using System; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
|
||
namespace Fusion.Resources.Authorization.Requirements | ||
{ | ||
/// <summary> | ||
/// Adjustment of the same type provided by the intergration lib. | ||
/// This will work against a claim added by the local transformer. This will resolve the role provided by the line org for manager responsebility based on SAP data. | ||
/// This update is harder to update in the integration lib claims transformer, due to optimalization. | ||
/// </summary> | ||
public class BeResourceOwnerRequirement : FusionAuthorizationRequirement, IAuthorizationHandler | ||
{ | ||
public BeResourceOwnerRequirement(string departmentPath, bool includeParents = false, bool includeDescendants = false) | ||
{ | ||
DepartmentPath = departmentPath; | ||
IncludeParents = includeParents; | ||
IncludeDescendants = includeDescendants; | ||
} | ||
|
||
public BeResourceOwnerRequirement() | ||
{ | ||
} | ||
|
||
|
||
public override string Description => ToString(); | ||
|
||
public override string Code => "ResourceOwner"; | ||
|
||
public string? DepartmentPath { get; } | ||
public bool IncludeParents { get; } | ||
public bool IncludeDescendants { get; } | ||
|
||
public Task HandleAsync(AuthorizationHandlerContext context) | ||
{ | ||
var departments = context.User.FindAll(ResourcesClaimTypes.ResourceOwnerForDepartment) | ||
.Select(c => c.Value); | ||
|
||
if (!departments.Any()) | ||
{ | ||
SetEvaluation("User is not resource owner in any departments"); | ||
return Task.CompletedTask; | ||
} | ||
if (string.IsNullOrEmpty(DepartmentPath)) | ||
{ | ||
context.Succeed(this); | ||
return Task.CompletedTask; | ||
} | ||
|
||
// responsibility descendant Descendants | ||
var directResponsibility = departments.Any(d => d.Equals(DepartmentPath, StringComparison.OrdinalIgnoreCase)); | ||
var descendantResponsibility = departments.Any(d => d.StartsWith(DepartmentPath, StringComparison.OrdinalIgnoreCase)); | ||
var parentResponsibility = departments.Any(d => DepartmentPath.StartsWith(d, StringComparison.OrdinalIgnoreCase)); | ||
|
||
var hasAccess = directResponsibility | ||
|| IncludeParents && parentResponsibility | ||
|| IncludeDescendants && descendantResponsibility; | ||
|
||
if (hasAccess) | ||
{ | ||
SetEvaluation($"User has access though responsibility in {string.Join(", ", departments)}. " + | ||
$"[owner in department={directResponsibility}, parents={parentResponsibility}, descendants={descendantResponsibility}]"); | ||
|
||
context.Succeed(this); | ||
} | ||
|
||
SetEvaluation($"User have responsibility in departments: {string.Join(", ", departments)}; But not in the requirement '{DepartmentPath}'"); | ||
|
||
return Task.CompletedTask; | ||
} | ||
|
||
public override string ToString() | ||
{ | ||
if (string.IsNullOrEmpty(DepartmentPath)) | ||
return "User must be resource owner of a department"; | ||
|
||
if (IncludeParents && IncludeDescendants) | ||
return $"User must be resource owner in department '{DepartmentPath}' or any departments above or below"; | ||
|
||
if (IncludeParents) | ||
return $"User must be resource owner in department '{DepartmentPath}' or any departments above"; | ||
|
||
if (IncludeDescendants) | ||
return $"User must be resource owner in department '{DepartmentPath}' or any sub departments"; | ||
|
||
return $"User must be resource owner in department '{DepartmentPath}'"; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.