-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathSecurityRoleService.cs
More file actions
121 lines (110 loc) · 5.59 KB
/
Copy pathSecurityRoleService.cs
File metadata and controls
121 lines (110 loc) · 5.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using Generator.DTO;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.PowerPlatform.Dataverse.Client;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Sdk.Query;
namespace Generator.Services
{
/// <summary>
/// Service responsible for querying and mapping security roles
/// </summary>
internal class SecurityRoleService
{
private readonly ServiceClient client;
public SecurityRoleService(ServiceClient client)
{
this.client = client;
}
/// <summary>
/// Retrieves and maps security roles with their privileges
/// </summary>
public async Task<Dictionary<string, List<SecurityRole>>> GetSecurityRoles(
List<Guid> rolesInSolution,
Dictionary<string, SecurityPrivilegeMetadata[]> privileges)
{
if (rolesInSolution.Count == 0) return [];
var query = new QueryExpression("role")
{
ColumnSet = new ColumnSet("name"),
Criteria = new FilterExpression(LogicalOperator.And)
{
Conditions =
{
new ConditionExpression("roleid", ConditionOperator.In, rolesInSolution)
}
},
LinkEntities =
{
new LinkEntity("role", "roleprivileges", "roleid", "roleid", JoinOperator.Inner)
{
EntityAlias = "rolepriv",
Columns = new ColumnSet("privilegedepthmask"),
LinkEntities =
{
new LinkEntity("roleprivileges", "privilege", "privilegeid", "privilegeid", JoinOperator.Inner)
{
EntityAlias = "priv",
Columns = new ColumnSet("accessright"),
LinkEntities =
{
new LinkEntity("privilege", "privilegeobjecttypecodes", "privilegeid", "privilegeid", JoinOperator.Inner)
{
EntityAlias = "privotc",
Columns = new ColumnSet("objecttypecode")
}
}
}
}
}
}
};
var roles = await client.RetrieveAllAsync(query);
var rolePrivileges = roles.Select(e =>
{
var name = e.GetAttributeValue<string>("name");
var depth = (PrivilegeDepth)e.GetAttributeValue<AliasedValue>("rolepriv.privilegedepthmask").Value;
var accessRight = (AccessRights)e.GetAttributeValue<AliasedValue>("priv.accessright").Value;
var objectTypeCode = e.GetAttributeValue<AliasedValue>("privotc.objecttypecode").Value as string;
return new
{
name,
depth,
accessRight,
objectTypeCode = objectTypeCode ?? string.Empty
};
});
static PrivilegeDepth? GetDepth(Dictionary<AccessRights, PrivilegeDepth> dict, AccessRights right, SecurityPrivilegeMetadata? meta)
{
if (!dict.TryGetValue(right, out var value))
return meta?.CanBeGlobal ?? false ? 0 : null;
return value;
}
return rolePrivileges
.GroupBy(x => x.objectTypeCode)
.ToDictionary(byLogicalName => byLogicalName.Key, byLogicalName =>
byLogicalName
.GroupBy(x => x.name)
.Select(byRole =>
{
var accessRights = byRole
.GroupBy(x => x.accessRight)
.ToDictionary(x => x.Key, x => x.First().depth);
var privilegeMetadata = privileges.GetValueOrDefault(byLogicalName.Key) ?? [];
return new SecurityRole(
byRole.Key,
byLogicalName.Key,
GetDepth(accessRights, AccessRights.CreateAccess, privilegeMetadata.FirstOrDefault(p => p.PrivilegeType == PrivilegeType.Create)),
GetDepth(accessRights, AccessRights.ReadAccess, privilegeMetadata.FirstOrDefault(p => p.PrivilegeType == PrivilegeType.Read)),
GetDepth(accessRights, AccessRights.WriteAccess, privilegeMetadata.FirstOrDefault(p => p.PrivilegeType == PrivilegeType.Write)),
GetDepth(accessRights, AccessRights.DeleteAccess, privilegeMetadata.FirstOrDefault(p => p.PrivilegeType == PrivilegeType.Delete)),
GetDepth(accessRights, AccessRights.AppendAccess, privilegeMetadata.FirstOrDefault(p => p.PrivilegeType == PrivilegeType.Append)),
GetDepth(accessRights, AccessRights.AppendToAccess, privilegeMetadata.FirstOrDefault(p => p.PrivilegeType == PrivilegeType.AppendTo)),
GetDepth(accessRights, AccessRights.AssignAccess, privilegeMetadata.FirstOrDefault(p => p.PrivilegeType == PrivilegeType.Assign)),
GetDepth(accessRights, AccessRights.ShareAccess, privilegeMetadata.FirstOrDefault(p => p.PrivilegeType == PrivilegeType.Share))
);
})
.ToList());
}
}
}