Files
LIAM/LiamMsTeams/C4IT.LIAM.MsTeams.cs
Meik 3d4f60d83e chore: sync LIAM solution snapshot incl. diagnostics tooling
- update multiple LIAM projects and solution/config files

- add LiamWorkflowDiagnostics app sources and generated outputs

- include current workspace state (dependencies and build outputs)
2026-02-27 09:12:34 +01:00

1116 lines
40 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Runtime.CompilerServices;
using C4IT.Logging;
using C4IT.MsGraph;
using static C4IT.Logging.cLogManager;
using C4IT.Matrix42.ServerInfo;
using static C4IT.MsGraph.cMsGraphSharepoint;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace C4IT.LIAM
{
public static class LiamInitializer
{
public static Guid msTeamsModuleId = new Guid("2591832a-1b25-ec11-6985-00155d300101");
static public cLiamProviderBase CreateInstance(cLiamConfiguration LiamConfiguration, cLiamProviderData ProviderData)
{
return new cLiamProviderMsTeams(LiamConfiguration, ProviderData);
}
}
public class cLiamProviderMsTeams : cLiamProviderBase
{
public readonly cMsGraphSharepoint MsSharepoint = new cMsGraphSharepoint(new cMsGraphBase());
public const string allowedMailNickNameCharacter = @"[^A-Za-z0-9!#$%&'*+\-/=?^_`{|}~]";
public readonly bool WithoutPrivateChannels = true;
private string lastErrorMessage = null;
private static readonly string[] RequiredGraphRoles = new[]
{
"Application.Read.All",
"Channel.ReadBasic.All",
"Directory.Read.All",
"Files.ReadWrite.All",
"Group.ReadWrite.All",
"GroupMember.Read.All",
"GroupMember.ReadWrite.All",
"Team.Create",
"Team.ReadBasic.All",
"TeamSettings.Read.All",
"User.Read.All",
};
private void SetLastError(string message)
{
lastErrorMessage = string.IsNullOrWhiteSpace(message) ? null : message;
}
public cLiamProviderMsTeams(cLiamConfiguration LiamConfiguration, cLiamProviderData ProviderData) :
base(LiamConfiguration, ProviderData)
{
WithoutPrivateChannels = AdditionalConfiguration.ContainsKey("WithoutPrivateChannels") ? AdditionalConfiguration["WithoutPrivateChannels"].ToLower() == "true" || AdditionalConfiguration["WithoutPrivateChannels"] == "1" : false;
}
public override async Task<bool> LogonAsync()
{
return await LogonAsync(true);
}
public async Task<bool> LogonAsync(bool force = false)
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.msTeamsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
SetLastError("License not valid");
return false;
}
if (!force && this.MsSharepoint.Base.IsOnline)
{
if (!EnsureGraphPermissions(MsSharepoint.Base?.AccessToken))
return false;
SetLastError(null);
return true;
}
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var LI = new cMsGraphLogonInfo() {
Tenant = this.Domain,
ClientID = this.Credential?.Identification,
ClientSecret = this.Credential?.Secret
};
var RetVal = await MsSharepoint.Base.LogonAsync(LI);
if (!RetVal)
{
SetLastError(MsSharepoint.Base?.LastErrorMessage ?? "MsTeams Logon fehlgeschlagen");
return false;
}
if (!EnsureGraphPermissions(MsSharepoint.Base?.AccessToken))
return false;
SetLastError(null);
return RetVal;
}
catch (Exception E)
{
LogException(E);
SetLastError(E.Message);
}
finally
{
LogMethodEnd(CM);
}
if (string.IsNullOrWhiteSpace(lastErrorMessage))
SetLastError("MsTeams Logon fehlgeschlagen");
return false;
}
public override async Task<List<cLiamDataAreaBase>> getDataAreasAsync(int Depth = -1)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!await LogonAsync())
return null;
var DataAreas = new List<cLiamDataAreaBase>();
var DAL = await MsSharepoint.RequestTeamsListAsync();
if (DAL == null)
{
SetLastError(MsSharepoint.Base?.LastErrorMessage ?? "Konnte Teams-Liste nicht abrufen");
return null;
}
foreach (var Entry in DAL)
{
if (!string.IsNullOrEmpty(this.DataAreaRegEx) && !Regex.Match(Entry.Key, this.DataAreaRegEx).Success)
continue;
var MsTeam = await MsSharepoint.RequestGroupInfoAsync(Entry.Value);
if (MsTeam == null)
{
SetLastError(MsSharepoint.Base?.LastErrorMessage ?? $"Konnte Team-Informationen für '{Entry.Key}' nicht abrufen");
continue;
}
var Team = new cLiamMsTeamsTeam(this, MsTeam);
DataAreas.Add(Team);
}
if (Depth > 0)
{
var allChilds = new List<cLiamDataAreaBase>();
foreach (var Entry in DataAreas)
{
var entryChilds = await (Entry as cLiamMsTeamsTeam).getChannels(true);
if (entryChilds != null && entryChilds.Count > 0)
allChilds.AddRange(entryChilds);
}
DataAreas.AddRange(allChilds);
}
SetLastError(null);
return DataAreas;
}
catch (Exception E)
{
LogException(E);
SetLastError(E.Message);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
private bool EnsureGraphPermissions(string accessToken)
{
if (string.IsNullOrWhiteSpace(accessToken))
{
SetLastError("Kein Access Token für Berechtigungsprüfung verfügbar");
return false;
}
try
{
var parts = accessToken.Split('.');
if (parts.Length < 2)
{
SetLastError("Ungültiges Access Token");
return false;
}
var payload = parts[1].Replace('-', '+').Replace('_', '/');
switch (payload.Length % 4)
{
case 2: payload += "=="; break;
case 3: payload += "="; break;
}
var payloadBytes = Convert.FromBase64String(payload);
var payloadJson = Encoding.UTF8.GetString(payloadBytes);
var payloadObj = JsonConvert.DeserializeObject<JObject>(payloadJson);
if (payloadObj == null)
{
SetLastError("Token-Payload konnte nicht gelesen werden");
return false;
}
var granted = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
if (payloadObj.TryGetValue("roles", out var rolesToken) && rolesToken is JArray roleArray)
{
foreach (var role in roleArray.Values<string>())
{
if (!string.IsNullOrWhiteSpace(role))
granted.Add(role);
}
}
if (!granted.Any() && payloadObj.TryGetValue("scp", out var scopeToken))
{
var scopes = scopeToken.Value<string>() ?? string.Empty;
foreach (var scope in scopes.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
granted.Add(scope);
}
var missing = RequiredGraphRoles.Where(required => !granted.Contains(required)).ToList();
if (missing.Count > 0)
{
SetLastError("Fehlende Graph-Berechtigungen: " + string.Join(", ", missing));
return false;
}
return true;
}
catch (Exception ex)
{
SetLastError("Berechtigungsprüfung fehlgeschlagen: " + ex.Message);
return false;
}
}
public override async Task<cLiamDataAreaBase> LoadDataArea(string UID)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.msTeamsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return null;
}
var lstIds = UID.Split('|');
switch (lstIds.Length)
{
case 4:
var FO = await cLiamMsTeamsFolder.Load(this, UID);
return FO;
case 2:
var CH = await cLiamMsTeamsChannel.Load(this, UID);
return CH;
case 1:
var TM = await cLiamMsTeamsTeam.Load(this, UID);
return TM;
}
return null;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public static string getUidItem(ref string UID)
{
try
{
var p = UID.IndexOf('|');
if (p >= 0)
{
var Item = UID.Substring(0, p);
UID = UID.Remove(0, p + 1);
UID = UID.TrimStart();
return Item.Trim();
}
}
catch { };
var h2 = UID;
UID = "";
return h2;
}
public static cMsGraphResultPermission.ePermissionRole getMsGraphRole(eLiamAccessRoles LiamRole)
{
switch (LiamRole)
{
case eLiamAccessRoles.Owner:
return cMsGraphResultPermission.ePermissionRole.owner;
case eLiamAccessRoles.Write:
return cMsGraphResultPermission.ePermissionRole.write;
default:
return cMsGraphResultPermission.ePermissionRole.read;
}
}
public static eLiamAccessRoles getLiamRole(cMsGraphResultPermission.ePermissionRole MsGraphRole)
{
switch (MsGraphRole)
{
case cMsGraphResultPermission.ePermissionRole.owner:
return eLiamAccessRoles.Owner;
case cMsGraphResultPermission.ePermissionRole.write:
return eLiamAccessRoles.Write;
default:
return eLiamAccessRoles.Read;
}
}
public override Task<List<cLiamDataAreaBase>> getSecurityGroupsAsync(string groupFilter)
{
throw new NotImplementedException();
}
public override string GetLastErrorMessage()
{
if (!string.IsNullOrWhiteSpace(lastErrorMessage))
return lastErrorMessage;
return MsSharepoint?.Base?.LastErrorMessage ?? string.Empty;
}
public async Task<cMsGraphResultBase> cloneTeam(string teamId, string name, string description, int visibility, int partsToClone, string additionalMembers, string additionalOwners)
{
var request = new CloneTeamRequest()
{
DisplayName = name,
Visibility = (CloneTeamRequest.TeamVisibilityType)visibility,
MailNickname = Regex.Replace(name, allowedMailNickNameCharacter, ""),
Description = description
};
request.SetClonableParts((CloneTeamRequest.ClonableTeamParts)partsToClone);
var res = await MsSharepoint.CloneTeam(teamId, request);
return res;
}
}
public class cLiamMsTeamsTeam : cLiamDataAreaBase
{
public new readonly cLiamProviderMsTeams Provider = null;
private readonly cMsGraphResultGroup MsTeam = null;
public cLiamMsTeamsTeam(cLiamProviderMsTeams Provider, cMsGraphResultGroup MsTeam) :
base(Provider)
{
this.Provider = Provider;
this.MsTeam = MsTeam;
this.TechnicalName = getUID(MsTeam.ID);
this.DisplayName = MsTeam.DisplayName;
this.Level = 0;
this.UID = getUID(MsTeam.ID);
this.ParentUID = "";
this.DataType = eLiamDataAreaTypes.MsTeamsTeam;
this.SupportsOwners = true;
this.SupportsPermissions = true;
}
internal static string getUID(string TeamID)
{
return $"{TeamID}";
}
internal async Task<List<cLiamDataAreaBase>> getChannels(bool OnlyPrivate)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (MsTeam == null)
return null;
var RegExFilter = this.Provider?.DataAreaRegEx;
var SP = this.Provider?.MsSharepoint;
var WithoutPrivateChannels = this.Provider?.WithoutPrivateChannels ?? false;
if (MsTeam.Channels == null)
if (SP == null || !await MsTeam.ResolveChannels(SP, OnlyPrivate))
return null;
var RetVal = new List<cLiamDataAreaBase>(MsTeam.Channels.Count);
foreach (var Entry in MsTeam.Channels.Values)
{
if (!string.IsNullOrEmpty(RegExFilter) && !Regex.Match(Entry.DisplayName, RegExFilter).Success)
continue;
if (WithoutPrivateChannels && !string.IsNullOrEmpty(Entry.MembershipType) && Entry.MembershipType == "private")
continue;
var DA = new cLiamMsTeamsChannel(Provider, this, Entry);
RetVal.Add(DA);
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.msTeamsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return null;
}
var RetVal = await getChannels(false);
if (RetVal != null)
RetVal.AddRange(await getChildrenFromListAsync(RetVal, Depth));
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public static async Task<cLiamMsTeamsTeam> Load(cLiamProviderMsTeams Provider, string UID)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var arrIDs = UID.Split('|');
if (arrIDs.Length != 1)
return null;
var TeamID = cLiamProviderMsTeams.getUidItem(ref UID);
var T = await Provider.MsSharepoint.RequestGroupInfoAsync(TeamID);
if (T == null)
return null;
var RetVal = new cLiamMsTeamsTeam(Provider, T);
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<List<cLiamUserInfo>> GetOwnersAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
return await GetMembersAsync(true);
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
private async Task<List<cLiamUserInfo>> GetMembersAsync(bool owners)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.msTeamsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return null;
}
var SP = this.Provider?.MsSharepoint;
if (SP == null)
{
LogEntry($"Could not get Sharepoint class from Provider for Team '{this.TechnicalName}'", LogLevels.Warning);
return null;
}
cMsGraphCollectionUsers lstMembers;
if(owners)
lstMembers = await MsTeam.GetOwnersAsync(SP);
else
lstMembers = await MsTeam.GetMembersAsync(SP);
if (lstMembers == null)
{
LogEntry($"Could not get owner list for Team '{this.TechnicalName}'", LogLevels.Warning);
return null;
}
var RetVal = new List<cLiamUserInfo>(lstMembers.Count);
LogEntry($"Owners for Team found: {lstMembers.Count}", LogLevels.Debug);
foreach (var MemberEntry in lstMembers.Values)
{
var User = new cLiamUserInfo()
{
DisplayName = MemberEntry.DisplayName,
GivenName = MemberEntry.GivenName,
SurName = MemberEntry.SurName,
UserPrincipalName = MemberEntry.UserPrincipalName,
EMail = MemberEntry.EMail,
SID = null
};
RetVal.Add(User);
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<List<cLiamPermissionInfo>> GetPermissionsAsync(bool force = false)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.msTeamsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return null;
}
var RetVal = new List<cLiamPermissionInfo>();
var owners = await GetOwnersAsync();
foreach ( var owner in owners)
{
var permission = new cLiamPermissionInfo()
{
User = owner,
AccessRole = eLiamAccessRoles.Owner
};
RetVal.Add(permission);
}
var members = await GetMembersAsync(false);
foreach (var member in members)
{
var permission = new cLiamPermissionInfo()
{
User = member,
AccessRole = eLiamAccessRoles.Write
};
RetVal.Add(permission);
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
public override async Task<cLiamPermissionResult> GrantPermissionAsync(cLiamUserInfo User, eLiamAccessRoles Role)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.msTeamsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return null;
}
var result = new cLiamPermissionResult();
if (Role == eLiamAccessRoles.Read)
{
return result;
}
try
{
var Roles = new List<cMsGraphResultPermission.ePermissionRole>()
{
cLiamProviderMsTeams.getMsGraphRole(Role)
};
var UserInfo = await Provider.MsSharepoint.RequestUserInfoAsync(User.UserPrincipalName);
if(string.IsNullOrEmpty(UserInfo?.ID))
{
LogEntry($"Could not find user {User.UserPrincipalName}", LogLevels.Error);
return null;
}
var retVal = await Provider.MsSharepoint.AddGroupMembership(MsTeam, false, UserInfo);
if(Role == eLiamAccessRoles.Owner)
retVal = await Provider.MsSharepoint.AddGroupMembership(MsTeam, true, UserInfo);
result.Valid = retVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return result;
}
public override async Task<bool> RevokePermissionAsync(cLiamUserInfo User, eLiamAccessRoles Role)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.msTeamsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return false;
}
if (Role == eLiamAccessRoles.Read)
{
return false;
}
try
{
var Roles = new List<cMsGraphResultPermission.ePermissionRole>()
{
cLiamProviderMsTeams.getMsGraphRole(Role)
};
var UserInfo = await Provider.MsSharepoint.RequestUserInfoAsync(User.UserPrincipalName);
if (string.IsNullOrEmpty(UserInfo?.ODataId))
{
LogEntry($"Could not find user {User.UserPrincipalName}", LogLevels.Error);
return false;
}
bool retVal = false;
if (Role == eLiamAccessRoles.Owner)
{
retVal = await Provider.MsSharepoint.DeleteGroupMembership(MsTeam, true, UserInfo);
retVal &= await Provider.MsSharepoint.DeleteGroupMembership(MsTeam, false, UserInfo);
}
if (Role == eLiamAccessRoles.Write)
{
var members = await Provider.MsSharepoint.RequestGroupOwnersAsync(MsTeam.ID, UserInfo.ID);
if(members == null || members.Count == 0)
{
retVal = await Provider.MsSharepoint.DeleteGroupMembership(MsTeam, false, UserInfo);
}
}
return retVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return false;
}
}
public class cLiamMsTeamsChannel : cLiamDataAreaBase
{
public new readonly cLiamProviderMsTeams Provider = null;
public readonly cMsGraphResultChannel MsChannel = null;
public cLiamMsTeamsChannel(cLiamProviderMsTeams Provider, cLiamMsTeamsTeam Team, cMsGraphResultChannel MsChannel, string TeamUID = null) : base(Provider)
{
this.Provider = Provider;
this.MsChannel = MsChannel;
this.TechnicalName = getUID(MsChannel.ID, TeamUID ?? Team?.UID ?? "*");
this.DisplayName = MsChannel.DisplayName;
this.Level = 1;
this.UID = getUID(MsChannel.ID, TeamUID ?? Team?.UID ?? "*");
if (Team != null)
this.ParentUID = Team.UID;
this.DataType = eLiamDataAreaTypes.MsTeamsChannel;
}
internal static string getUID(string ChannelID, string TeamUID)
{
return $"{ChannelID} | {TeamUID}";
}
public override async Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.msTeamsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return null;
}
if (MsChannel == null)
return null;
var RegExFilter = this.Provider?.DataAreaRegEx;
var SP = this.Provider?.MsSharepoint;
if (MsChannel.RootFolder == null)
if (SP == null || !await MsChannel.ResolveRootFolder(SP))
return null;
if (MsChannel.RootFolder.Folders == null)
if (SP == null || !await MsChannel.RootFolder.ResolveFolders(SP))
return null;
var DataAreas = new List<cLiamDataAreaBase>();
foreach (var Entry in MsChannel.RootFolder.Folders.Values)
{
if (!string.IsNullOrEmpty(RegExFilter) && !Regex.Match(Entry.DisplayName, RegExFilter).Success)
continue;
var DA = new cLiamMsTeamsFolder(this, Entry);
DataAreas.Add(DA);
}
DataAreas.AddRange(await getChildrenFromListAsync(DataAreas, Depth));
return DataAreas;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public static async Task<cLiamMsTeamsChannel> Load(cLiamProviderMsTeams Provider, string UID)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var arrIDs = UID.Split('|');
if (arrIDs.Length != 2)
return null;
var ChannelID = cLiamProviderMsTeams.getUidItem(ref UID);
var TeamID = cLiamProviderMsTeams.getUidItem(ref UID);
var C = await Provider.MsSharepoint.RequestChannelInfo(TeamID, ChannelID);
if (C == null)
return null;
var RetVal = new cLiamMsTeamsChannel(Provider, null, C, TeamID);
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
}
public class cLiamMsTeamsFolder : cLiamDataAreaBase
{
public new readonly cLiamProviderMsTeams Provider = null;
public readonly cLiamMsTeamsChannel Channel = null;
public readonly string ChannelUID = null;
public readonly cMsGraphResultFileObject MsFolder = null;
public cLiamMsTeamsFolder(cLiamMsTeamsChannel Channel, cMsGraphResultFileObject MsFolder) : this(Channel.Provider, Channel, Channel, MsFolder) { }
public cLiamMsTeamsFolder(cLiamMsTeamsFolder ParentFolder, cMsGraphResultFileObject MsFolder) : this(ParentFolder.Channel.Provider, ParentFolder.Channel, ParentFolder, MsFolder) { }
private cLiamMsTeamsFolder(cLiamProviderMsTeams Provider, cLiamMsTeamsChannel Channel, cLiamDataAreaBase ParentFolder, cMsGraphResultFileObject MsFolder, string ChannelUID = null) : base(Provider)
{
this.Channel = Channel;
if (Channel == null)
this.ChannelUID = ChannelUID;
else
this.ChannelUID = Channel.UID;
this.Provider = Provider;
this.MsFolder = MsFolder;
this.TechnicalName = MsFolder.DisplayName;
this.DisplayName = MsFolder.DisplayName;
if (ParentFolder != null)
{
this.Level = ParentFolder.Level + 1;
this.ParentUID = ParentFolder.UID;
}
this.UID = getUID(MsFolder.ID, MsFolder.DriveID, ChannelUID ?? Channel?.UID ?? "*|*");
this.DataType = eLiamDataAreaTypes.MsTeamsFolder;
this.SupportsPermissions = true;
}
internal static string getUID(string FolderID, string DriveID, string ChannelUID)
{
return $"{FolderID} | {DriveID} | {ChannelUID}";
}
public override async Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.msTeamsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return null;
}
if (MsFolder == null)
return null;
var RegExFilter = this.Provider?.DataAreaRegEx;
var SP = this.Provider?.MsSharepoint;
if (MsFolder.Folders == null)
if (SP == null || !await MsFolder.ResolveFolders(SP))
return null;
var DataAreas = new List<cLiamDataAreaBase>();
foreach (var Entry in MsFolder.Folders.Values)
{
if (!string.IsNullOrEmpty(RegExFilter) && !Regex.Match(Entry.DisplayName, RegExFilter).Success)
continue;
var DA = new cLiamMsTeamsFolder(this.Provider, this.Channel, this, Entry, this.ChannelUID);
DataAreas.Add(DA);
}
var CL = await getChildrenFromListAsync(DataAreas, Depth);
if (CL != null)
DataAreas.AddRange(CL);
return DataAreas;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public static async Task<cLiamMsTeamsFolder> Load(cLiamProviderMsTeams Provider, string UID)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var arrIDs = UID.Split('|');
if (arrIDs.Length != 4)
return null;
var FolderID = cLiamProviderMsTeams.getUidItem(ref UID);
var DriveID = cLiamProviderMsTeams.getUidItem(ref UID);
var F = await Provider.MsSharepoint.RequestFileObjectInfo(DriveID, FolderID);
if (F == null)
return null;
var RetVal = new cLiamMsTeamsFolder(Provider, null, null, F, UID);
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<List<cLiamPermissionInfo>> GetPermissionsAsync(bool force = false)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.msTeamsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return null;
}
var RetVal = new List<cLiamPermissionInfo>();
if (this.MsFolder.Permissions == null || force)
if (!await this.MsFolder.ResolvePermissions(Provider.MsSharepoint))
return null;
if (this.MsFolder.Permissions == null)
return null;
foreach (var Perm in this.MsFolder.Permissions)
{
if (!(Perm is cMsGraphResultPermission.PermissionDirect) && !(Perm is cMsGraphResultPermission.PermissionLink))
continue;
if (Perm.isInherited)
continue;
if (Perm.Identities != null)
{
foreach (var Role in Perm.Roles)
{
var AccessRole = cLiamProviderMsTeams.getLiamRole(Role);
foreach (var Ident in Perm.Identities)
{
if (Ident.IdentityType != cMsGraphResultPermission.cMsGraphPermissionIdentity.eIdentityType.user)
continue;
if (string.IsNullOrEmpty(Ident.EMail))
continue;
if (!string.IsNullOrEmpty(Ident.ID))
{
var GroupInfo = await Provider.MsSharepoint.RequestGroupInfoAsync(Ident.ID);
if (GroupInfo != null)
continue;
}
var Usr = Ident.EMail.ToLowerInvariant();
var alreadyFound = false;
foreach (var Entry in RetVal)
{
if (Usr == Entry.User.EMail.ToLowerInvariant())
if (AccessRole == Entry.AccessRole)
{
alreadyFound = true;
break;
}
}
if (!alreadyFound)
{
var UsrInfo = new cLiamUserInfo()
{
DisplayName = Ident.DisplayName,
EMail = Ident.EMail,
UserPrincipalName = Ident.EMail
};
var PermInfo = new cLiamPermissionInfo()
{
User = UsrInfo,
AccessRole = AccessRole
};
RetVal.Add(PermInfo);
}
}
}
}
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
public override async Task<cLiamPermissionResult> GrantPermissionAsync(cLiamUserInfo User, eLiamAccessRoles Role)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.msTeamsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return null;
}
var Roles = new List<cMsGraphResultPermission.ePermissionRole>()
{
cLiamProviderMsTeams.getMsGraphRole(Role)
};
var RetVal = await this.MsFolder.AddPermission(Provider.MsSharepoint, Roles, cMsGraphResultPermission.eDriveReceipientType.email, User.EMail);
if (RetVal == null)
return null;
var RetVal2 = new cLiamPermissionResult();
if (RetVal.Count>= 0)
{
RetVal2.Valid = true;
var Perm = RetVal[0];
if (Perm is cMsGraphResultPermission.PermissionLink Link)
{
RetVal2.UserReference = Link.WebUrl;
}
else
RetVal2.UserReference = this.MsFolder.WebUrl;
}
return RetVal2;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<bool> RevokePermissionAsync(cLiamUserInfo User, eLiamAccessRoles Role)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.msTeamsModuleId))
{
LogEntry($"Error: License not valid", LogLevels.Error);
return false;
}
var myRole = cLiamProviderMsTeams.getMsGraphRole(Role);
var RetVal = await this.MsFolder.RemovePermission(Provider.MsSharepoint, myRole, User.EMail);
return RetVal;
}
catch (Exception E)
{
LogException(E);
return false;
}
finally
{
LogMethodEnd(CM);
}
}
}
}