Added new feature : display the file/folder and link of a SharingLink object in the permissions reports.
This commit is contained in:
@@ -11,6 +11,16 @@ namespace SharepointToolbox.Services;
|
||||
/// </summary>
|
||||
public class PermissionsService : IPermissionsService
|
||||
{
|
||||
private readonly ISystemGroupTargetResolver? _systemGroupResolver;
|
||||
|
||||
public PermissionsService() : this(null) { }
|
||||
|
||||
public PermissionsService(ISystemGroupTargetResolver? systemGroupResolver)
|
||||
{
|
||||
_systemGroupResolver = systemGroupResolver;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Detects the SharePoint server error raised when a RoleAssignment member
|
||||
/// refers to a user that no longer resolves (orphaned Azure AD account).
|
||||
@@ -336,9 +346,18 @@ public class PermissionsService : IPermissionsService
|
||||
|
||||
var member = ra.Member;
|
||||
var loginName = member.LoginName ?? string.Empty;
|
||||
var memberTitle = member.Title ?? string.Empty;
|
||||
|
||||
// Skip sharing links groups and limited access system groups
|
||||
if (PermissionEntryHelper.IsSharingLinksGroup(loginName))
|
||||
// Classify the member name. The bare "Limited Access System Group" is
|
||||
// pure noise; drop it. The For-Web/For-List and SharingLinks variants
|
||||
// are kept and enriched below with a resolved target URL.
|
||||
var classification = PermissionEntryHelper.Classify(memberTitle);
|
||||
if (classification.Kind == SystemGroupKind.None
|
||||
&& PermissionEntryHelper.IsBareLimitedAccessSystemGroup(loginName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (classification.Kind == SystemGroupKind.LimitedAccessBare)
|
||||
continue;
|
||||
|
||||
// Collect and filter permission levels
|
||||
@@ -362,19 +381,42 @@ public class PermissionsService : IPermissionsService
|
||||
|
||||
// Determine how the permission was granted
|
||||
string grantedThrough = principalType == "SharePointGroup"
|
||||
? $"SharePoint Group: {member.Title}"
|
||||
? $"SharePoint Group: {memberTitle}"
|
||||
: "Direct Permissions";
|
||||
|
||||
// Resolve system-group target (Limited Access For Web/List, SharingLinks)
|
||||
string? targetUrl = null;
|
||||
string? targetLabel = null;
|
||||
string? sharingLinkType = null;
|
||||
if (_systemGroupResolver is not null && classification.Kind != SystemGroupKind.None)
|
||||
{
|
||||
var target = await _systemGroupResolver.ResolveAsync(ctx, classification, ct);
|
||||
if (target is not null)
|
||||
{
|
||||
targetUrl = target.Url;
|
||||
targetLabel = target.Label;
|
||||
sharingLinkType = target.LinkType;
|
||||
}
|
||||
else if (classification.Kind == SystemGroupKind.SharingLink)
|
||||
{
|
||||
// Target lookup failed (deleted item / no access) — still surface link type.
|
||||
sharingLinkType = classification.LinkType;
|
||||
}
|
||||
}
|
||||
|
||||
entries.Add(new PermissionEntry(
|
||||
ObjectType: objectType,
|
||||
Title: title,
|
||||
Url: url,
|
||||
HasUniquePermissions: obj.HasUniqueRoleAssignments,
|
||||
Users: member.Title ?? string.Empty,
|
||||
Users: memberTitle,
|
||||
UserLogins: loginName,
|
||||
PermissionLevels: permLevels,
|
||||
GrantedThrough: grantedThrough,
|
||||
PrincipalType: principalType));
|
||||
PrincipalType: principalType,
|
||||
TargetUrl: targetUrl,
|
||||
TargetLabel: targetLabel,
|
||||
SharingLinkType: sharingLinkType));
|
||||
}
|
||||
|
||||
return entries;
|
||||
|
||||
Reference in New Issue
Block a user