feat(08-01): add RiskLevel enum and PermissionLevelMapping helper
- RiskLevel enum with High, Medium, Low, ReadOnly tiers - PermissionLevelMapping maps 11 standard SharePoint roles to plain-language labels - Case-insensitive lookup with Medium fallback for unknown roles - GetHighestRisk and GetSimplifiedLabels for row-level formatting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
95
SharepointToolbox/Core/Helpers/PermissionLevelMapping.cs
Normal file
95
SharepointToolbox/Core/Helpers/PermissionLevelMapping.cs
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
using SharepointToolbox.Core.Models;
|
||||||
|
|
||||||
|
namespace SharepointToolbox.Core.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maps SharePoint built-in permission level names to human-readable labels and risk levels.
|
||||||
|
/// Used by SimplifiedPermissionEntry and export services to translate raw role names
|
||||||
|
/// into plain-language descriptions that non-technical users can understand.
|
||||||
|
/// </summary>
|
||||||
|
public static class PermissionLevelMapping
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Result of looking up a SharePoint role name.
|
||||||
|
/// </summary>
|
||||||
|
public record MappingResult(string Label, RiskLevel RiskLevel);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Known SharePoint built-in permission level mappings.
|
||||||
|
/// Keys are case-insensitive via the dictionary comparer.
|
||||||
|
/// </summary>
|
||||||
|
private static readonly Dictionary<string, MappingResult> Mappings = new(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
// High risk — full administrative access
|
||||||
|
["Full Control"] = new("Full control (can manage everything)", RiskLevel.High),
|
||||||
|
["Site Collection Administrator"] = new("Site collection admin (full control)", RiskLevel.High),
|
||||||
|
|
||||||
|
// Medium risk — can modify content
|
||||||
|
["Contribute"] = new("Can edit files and list items", RiskLevel.Medium),
|
||||||
|
["Edit"] = new("Can edit files, lists, and pages", RiskLevel.Medium),
|
||||||
|
["Design"] = new("Can edit pages and use design tools", RiskLevel.Medium),
|
||||||
|
["Approve"] = new("Can approve content and list items", RiskLevel.Medium),
|
||||||
|
["Manage Hierarchy"] = new("Can create sites and manage pages", RiskLevel.Medium),
|
||||||
|
|
||||||
|
// Low risk — read access
|
||||||
|
["Read"] = new("Can view files and pages", RiskLevel.Low),
|
||||||
|
["Restricted Read"] = new("Can view pages only (no download)", RiskLevel.Low),
|
||||||
|
|
||||||
|
// Read-only — most restricted
|
||||||
|
["View Only"] = new("Can view files in browser only", RiskLevel.ReadOnly),
|
||||||
|
["Restricted View"] = new("Restricted view access", RiskLevel.ReadOnly),
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the human-readable label and risk level for a SharePoint role name.
|
||||||
|
/// Returns the mapped result for known roles; for unknown/custom roles,
|
||||||
|
/// returns the raw name as-is with Medium risk level.
|
||||||
|
/// </summary>
|
||||||
|
public static MappingResult GetMapping(string roleName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(roleName))
|
||||||
|
return new MappingResult(roleName, RiskLevel.Low);
|
||||||
|
|
||||||
|
return Mappings.TryGetValue(roleName.Trim(), out var result)
|
||||||
|
? result
|
||||||
|
: new MappingResult(roleName.Trim(), RiskLevel.Medium);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resolves a semicolon-delimited PermissionLevels string into individual mapping results.
|
||||||
|
/// This handles the PermissionEntry.PermissionLevels format (e.g. "Full Control; Contribute").
|
||||||
|
/// </summary>
|
||||||
|
public static IReadOnlyList<MappingResult> GetMappings(string permissionLevels)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(permissionLevels))
|
||||||
|
return Array.Empty<MappingResult>();
|
||||||
|
|
||||||
|
return permissionLevels
|
||||||
|
.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||||
|
.Select(GetMapping)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the highest (most dangerous) risk level from a semicolon-delimited permission levels string.
|
||||||
|
/// Used for row-level color coding when an entry has multiple roles.
|
||||||
|
/// </summary>
|
||||||
|
public static RiskLevel GetHighestRisk(string permissionLevels)
|
||||||
|
{
|
||||||
|
var mappings = GetMappings(permissionLevels);
|
||||||
|
if (mappings.Count == 0) return RiskLevel.Low;
|
||||||
|
|
||||||
|
// High < Medium < Low < ReadOnly in enum order — Min gives highest risk
|
||||||
|
return mappings.Min(m => m.RiskLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a semicolon-delimited PermissionLevels string into a simplified labels string.
|
||||||
|
/// E.g. "Full Control; Contribute" becomes "Full control (can manage everything); Can edit files and list items"
|
||||||
|
/// </summary>
|
||||||
|
public static string GetSimplifiedLabels(string permissionLevels)
|
||||||
|
{
|
||||||
|
var mappings = GetMappings(permissionLevels);
|
||||||
|
return string.Join("; ", mappings.Select(m => m.Label));
|
||||||
|
}
|
||||||
|
}
|
||||||
17
SharepointToolbox/Core/Models/RiskLevel.cs
Normal file
17
SharepointToolbox/Core/Models/RiskLevel.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
namespace SharepointToolbox.Core.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Classifies a SharePoint permission level by its access risk.
|
||||||
|
/// Used for color coding in both WPF DataGrid and HTML export.
|
||||||
|
/// </summary>
|
||||||
|
public enum RiskLevel
|
||||||
|
{
|
||||||
|
/// <summary>Full Control, Site Collection Administrator — can delete site, manage permissions.</summary>
|
||||||
|
High,
|
||||||
|
/// <summary>Contribute, Edit, Design — can modify content.</summary>
|
||||||
|
Medium,
|
||||||
|
/// <summary>Read, Restricted View — can view but not modify.</summary>
|
||||||
|
Low,
|
||||||
|
/// <summary>View Only — most restricted legitimate access.</summary>
|
||||||
|
ReadOnly
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user