Restore MsTeams legacy permission compatibility
This commit is contained in:
@@ -35,19 +35,75 @@ namespace C4IT.LIAM
|
|||||||
|
|
||||||
private string lastErrorMessage = null;
|
private string lastErrorMessage = null;
|
||||||
|
|
||||||
private static readonly string[] RequiredGraphRoles = new[]
|
private sealed class GraphPermissionRequirement
|
||||||
{
|
{
|
||||||
"Application.Read.All",
|
public string Description { get; private set; }
|
||||||
"Channel.ReadBasic.All",
|
|
||||||
"Directory.Read.All",
|
public string[] AcceptedPermissions { get; private set; }
|
||||||
"Files.ReadWrite.All",
|
|
||||||
|
public GraphPermissionRequirement(string description, params string[] acceptedPermissions)
|
||||||
|
{
|
||||||
|
Description = description;
|
||||||
|
AcceptedPermissions = acceptedPermissions ?? new string[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly GraphPermissionRequirement[] RequiredGraphPermissions = new[]
|
||||||
|
{
|
||||||
|
new GraphPermissionRequirement(
|
||||||
|
"Team lesen",
|
||||||
|
"Team.ReadBasic.All",
|
||||||
|
"Group.Read.All",
|
||||||
"Group.ReadWrite.All",
|
"Group.ReadWrite.All",
|
||||||
|
"Directory.Read.All",
|
||||||
|
"Directory.ReadWrite.All"),
|
||||||
|
new GraphPermissionRequirement(
|
||||||
|
"Channels lesen",
|
||||||
|
"Channel.ReadBasic.All",
|
||||||
|
"ChannelSettings.Read.All",
|
||||||
|
"ChannelSettings.ReadWrite.All",
|
||||||
|
"Group.Read.All",
|
||||||
|
"Group.ReadWrite.All",
|
||||||
|
"Directory.Read.All",
|
||||||
|
"Directory.ReadWrite.All"),
|
||||||
|
new GraphPermissionRequirement(
|
||||||
|
"Dateien lesen und schreiben",
|
||||||
|
"Files.ReadWrite.All",
|
||||||
|
"Sites.ReadWrite.All",
|
||||||
|
"Sites.FullControl.All"),
|
||||||
|
new GraphPermissionRequirement(
|
||||||
|
"Benutzer lesen",
|
||||||
|
"User.Read.All",
|
||||||
|
"User.ReadWrite.All",
|
||||||
|
"Directory.Read.All",
|
||||||
|
"Directory.ReadWrite.All"),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly GraphPermissionRequirement[] CloneBaseGraphPermissions = new[]
|
||||||
|
{
|
||||||
|
new GraphPermissionRequirement("Teams klonen", "Team.Create"),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly GraphPermissionRequirement[] CloneAppsGraphPermissions = new[]
|
||||||
|
{
|
||||||
|
new GraphPermissionRequirement("Apps mitklonen", "Application.Read.All", "Application.ReadWrite.All"),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly GraphPermissionRequirement[] CloneSettingsGraphPermissions = new[]
|
||||||
|
{
|
||||||
|
new GraphPermissionRequirement("Team-Einstellungen mitklonen", "TeamSettings.Read.All", "TeamSettings.ReadWrite.All"),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly GraphPermissionRequirement[] CloneMemberGraphPermissions = new[]
|
||||||
|
{
|
||||||
|
new GraphPermissionRequirement(
|
||||||
|
"Mitglieder mitklonen",
|
||||||
"GroupMember.Read.All",
|
"GroupMember.Read.All",
|
||||||
"GroupMember.ReadWrite.All",
|
"GroupMember.ReadWrite.All",
|
||||||
"Team.Create",
|
"Group.Read.All",
|
||||||
"Team.ReadBasic.All",
|
"Group.ReadWrite.All",
|
||||||
"TeamSettings.Read.All",
|
"Directory.Read.All",
|
||||||
"User.Read.All",
|
"Directory.ReadWrite.All"),
|
||||||
};
|
};
|
||||||
|
|
||||||
private void SetLastError(string message)
|
private void SetLastError(string message)
|
||||||
@@ -182,9 +238,57 @@ namespace C4IT.LIAM
|
|||||||
|
|
||||||
private bool EnsureGraphPermissions(string accessToken)
|
private bool EnsureGraphPermissions(string accessToken)
|
||||||
{
|
{
|
||||||
|
return EnsureGraphPermissions(accessToken, RequiredGraphPermissions, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool EnsureClonePermissions(string accessToken, int partsToClone)
|
||||||
|
{
|
||||||
|
var requirements = new List<GraphPermissionRequirement>(CloneBaseGraphPermissions);
|
||||||
|
var cloneParts = (CloneTeamRequest.ClonableTeamParts)partsToClone;
|
||||||
|
|
||||||
|
if (cloneParts.HasFlag(CloneTeamRequest.ClonableTeamParts.Apps))
|
||||||
|
requirements.AddRange(CloneAppsGraphPermissions);
|
||||||
|
if (cloneParts.HasFlag(CloneTeamRequest.ClonableTeamParts.Settings))
|
||||||
|
requirements.AddRange(CloneSettingsGraphPermissions);
|
||||||
|
if (cloneParts.HasFlag(CloneTeamRequest.ClonableTeamParts.Members))
|
||||||
|
requirements.AddRange(CloneMemberGraphPermissions);
|
||||||
|
|
||||||
|
return EnsureGraphPermissions(accessToken, requirements, "Team-Klonen");
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool EnsureGraphPermissions(string accessToken, IEnumerable<GraphPermissionRequirement> requirements, string operationName)
|
||||||
|
{
|
||||||
|
if (!TryGetGrantedGraphPermissions(accessToken, out var granted, out var errorMessage))
|
||||||
|
{
|
||||||
|
SetLastError(errorMessage);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var missing = requirements
|
||||||
|
.Where(requirement => requirement.AcceptedPermissions == null || !requirement.AcceptedPermissions.Any(granted.Contains))
|
||||||
|
.Select(requirement => $"{requirement.Description} ({string.Join(" / ", requirement.AcceptedPermissions)})")
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (missing.Count > 0)
|
||||||
|
{
|
||||||
|
var prefix = string.IsNullOrWhiteSpace(operationName)
|
||||||
|
? "Fehlende Graph-Berechtigungen: "
|
||||||
|
: $"Fehlende Graph-Berechtigungen für {operationName}: ";
|
||||||
|
SetLastError(prefix + string.Join(", ", missing));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryGetGrantedGraphPermissions(string accessToken, out HashSet<string> granted, out string errorMessage)
|
||||||
|
{
|
||||||
|
granted = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
errorMessage = null;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(accessToken))
|
if (string.IsNullOrWhiteSpace(accessToken))
|
||||||
{
|
{
|
||||||
SetLastError("Kein Access Token für Berechtigungsprüfung verfügbar");
|
errorMessage = "Kein Access Token für Berechtigungsprüfung verfügbar";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +297,7 @@ namespace C4IT.LIAM
|
|||||||
var parts = accessToken.Split('.');
|
var parts = accessToken.Split('.');
|
||||||
if (parts.Length < 2)
|
if (parts.Length < 2)
|
||||||
{
|
{
|
||||||
SetLastError("Ungültiges Access Token");
|
errorMessage = "Ungültiges Access Token";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,12 +313,10 @@ namespace C4IT.LIAM
|
|||||||
var payloadObj = JsonConvert.DeserializeObject<JObject>(payloadJson);
|
var payloadObj = JsonConvert.DeserializeObject<JObject>(payloadJson);
|
||||||
if (payloadObj == null)
|
if (payloadObj == null)
|
||||||
{
|
{
|
||||||
SetLastError("Token-Payload konnte nicht gelesen werden");
|
errorMessage = "Token-Payload konnte nicht gelesen werden";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var granted = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
if (payloadObj.TryGetValue("roles", out var rolesToken) && rolesToken is JArray roleArray)
|
if (payloadObj.TryGetValue("roles", out var rolesToken) && rolesToken is JArray roleArray)
|
||||||
{
|
{
|
||||||
foreach (var role in roleArray.Values<string>())
|
foreach (var role in roleArray.Values<string>())
|
||||||
@@ -231,10 +333,9 @@ namespace C4IT.LIAM
|
|||||||
granted.Add(scope);
|
granted.Add(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
var missing = RequiredGraphRoles.Where(required => !granted.Contains(required)).ToList();
|
if (!granted.Any())
|
||||||
if (missing.Count > 0)
|
|
||||||
{
|
{
|
||||||
SetLastError("Fehlende Graph-Berechtigungen: " + string.Join(", ", missing));
|
errorMessage = "Keine Graph-Berechtigungen im Access Token gefunden";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +343,7 @@ namespace C4IT.LIAM
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
SetLastError("Berechtigungsprüfung fehlgeschlagen: " + ex.Message);
|
errorMessage = "Berechtigungsprüfung fehlgeschlagen: " + ex.Message;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -349,6 +450,11 @@ namespace C4IT.LIAM
|
|||||||
|
|
||||||
public async Task<cMsGraphResultBase> cloneTeam(string teamId, string name, string description, int visibility, int partsToClone, string additionalMembers, string additionalOwners)
|
public async Task<cMsGraphResultBase> cloneTeam(string teamId, string name, string description, int visibility, int partsToClone, string additionalMembers, string additionalOwners)
|
||||||
{
|
{
|
||||||
|
if (!await LogonAsync())
|
||||||
|
return null;
|
||||||
|
if (!EnsureClonePermissions(MsSharepoint.Base?.AccessToken, partsToClone))
|
||||||
|
return null;
|
||||||
|
|
||||||
var request = new CloneTeamRequest()
|
var request = new CloneTeamRequest()
|
||||||
{
|
{
|
||||||
DisplayName = name,
|
DisplayName = name,
|
||||||
|
|||||||
Reference in New Issue
Block a user