private ExecuteContext GetRightsContext(CallerInfo caller, InvokerData invoker, TeamspeakControl ts) { if (needsRecalculation) { cachedRights.Invalidate(); needsRecalculation = false; ReadFile(); } ExecuteContext execCtx; if (invoker != null) { if (cachedRights.TryGetValue(invoker.ClientUid, out execCtx)) { // TODO check if all fields are same // if yes => returen // if no => delete from cache return(execCtx); } execCtx = new ExecuteContext(); // Get Required Matcher Data: // In this region we will iteratively go through different possibilities to obtain // as much data as we can about our invoker. // For this step we will prefer query calls which can give us more than one information // at once and lazily fall back to other calls as long as needed. ulong[] availableGroups = null; if (ts != null) { if (invoker.ClientId.HasValue && (needsAvailableGroups || needsAvailableChanGroups)) { var result = ts.GetClientInfoById(invoker.ClientId.Value); if (result.Ok) { availableGroups = result.Value.ServerGroups; execCtx.ChannelGroupId = result.Value.ChannelGroupId; } } if (needsAvailableGroups && invoker.DatabaseId.HasValue && availableGroups == null) { var result = ts.GetClientServerGroups(invoker.DatabaseId.Value); if (result.Ok) { availableGroups = result.Value; } } } if (availableGroups != null) { execCtx.AvailableGroups = availableGroups; } execCtx.ClientUid = invoker.ClientUid; execCtx.Visibiliy = invoker.Visibiliy; execCtx.ApiToken = invoker.Token; } else { execCtx = new ExecuteContext(); } execCtx.IsApi = caller.ApiCall; ProcessNode(rootRule, execCtx); if (execCtx.MatchingRules.Count == 0) { return(execCtx); } foreach (var rule in execCtx.MatchingRules) { execCtx.DeclAdd.UnionWith(rule.DeclAdd); } if (invoker != null) { cachedRights.Store(invoker.ClientUid, execCtx); } return(execCtx); }
private ExecuteContext GetRightsContext(ExecutionInformation info) { var localRootRule = TryGetRootSafe(); if (info.TryGet <ExecuteContext>(out var execCtx)) { return(execCtx); } if (info.TryGet <InvokerData>(out var invoker)) { execCtx = new ExecuteContext { ServerGroups = invoker.ServerGroups, ClientUid = invoker.ClientUid, Visibiliy = invoker.Visibiliy, ApiToken = invoker.Token, }; // Get Required Matcher Data: // In this region we will iteratively go through different possibilities to obtain // as much data as we can about our invoker. // For this step we will prefer query calls which can give us more than one information // at once and lazily fall back to other calls as long as needed. if (info.TryGet <Ts3Client>(out var ts)) { ulong[] serverGroups = invoker.ServerGroups; if (invoker.ClientId.HasValue && ((needsAvailableGroups && serverGroups == null) || needsAvailableChanGroups)) { var result = ts.GetClientInfoById(invoker.ClientId.Value); if (result.Ok) { serverGroups = result.Value.ServerGroups; execCtx.ChannelGroupId = result.Value.ChannelGroup; } } if (needsAvailableGroups && serverGroups == null) { if (!invoker.DatabaseId.HasValue) { var resultDbId = ts.TsFullClient.ClientGetDbIdFromUid(invoker.ClientUid); if (resultDbId.Ok) { invoker.DatabaseId = resultDbId.Value.ClientDbId; } } if (invoker.DatabaseId.HasValue) { var result = ts.GetClientServerGroups(invoker.DatabaseId.Value); if (result.Ok) { serverGroups = result.Value; } } } execCtx.ServerGroups = serverGroups ?? execCtx.ServerGroups; } } else { execCtx = new ExecuteContext(); } if (info.TryGet <CallerInfo>(out var caller)) { execCtx.IsApi = caller.ApiCall; } if (info.TryGet <Bot>(out var bot)) { execCtx.Bot = bot.Name; } if (localRootRule != null) { ProcessNode(localRootRule, execCtx); } if (execCtx.MatchingRules.Count == 0) { return(execCtx); } foreach (var rule in execCtx.MatchingRules) { execCtx.DeclAdd.UnionWith(rule.DeclAdd); } info.AddDynamicObject(execCtx); return(execCtx); }
private ExecuteContext GetRightsContext(ExecutionInformation info) { var localRootRule = TryGetRootSafe(); if (info.TryGet <ExecuteContext>(out var execCtx)) { return(execCtx); } if (info.TryGet <InvokerData>(out var invoker)) { execCtx = new ExecuteContext { ServerGroups = invoker.ServerGroups, ClientUid = invoker.ClientUid, Visibiliy = invoker.Visibiliy, ApiToken = invoker.Token, }; // Get Required Matcher Data: // In this region we will iteratively go through different possibilities to obtain // as much data as we can about our invoker. // For this step we will prefer query calls which can give us more than one information // at once and lazily fall back to other calls as long as needed. if (info.TryGet <Ts3Client>(out var ts)) { ulong[] serverGroups = invoker.ServerGroups; ulong? channelId = invoker.ChannelId; ulong? databaseId = invoker.DatabaseId; if (invoker.ClientId.HasValue && ((needsAvailableGroups && serverGroups is null) || needsAvailableChanGroups || (needsPermOverview.Length > 0 && (!databaseId.HasValue || !channelId.HasValue)) ) ) { var result = ts.GetClientInfoById(invoker.ClientId.Value); if (result.Ok) { serverGroups = result.Value.ServerGroups; execCtx.ChannelGroupId = result.Value.ChannelGroup; databaseId = result.Value.DatabaseId; channelId = result.Value.ChannelId; } } if (needsAvailableGroups && serverGroups is null) { if (!databaseId.HasValue) { var resultDbId = ts.TsFullClient.ClientGetDbIdFromUid(invoker.ClientUid); if (resultDbId.Ok) { databaseId = resultDbId.Value.ClientDbId; } } if (databaseId.HasValue) { var result = ts.GetClientServerGroups(databaseId.Value); if (result.Ok) { serverGroups = result.Value; } } } execCtx.ServerGroups = serverGroups ?? Array.Empty <ulong>(); if (needsPermOverview.Length > 0 && databaseId.HasValue && channelId.HasValue) { // TODO check if there is any better way to only get the permissions needed. var result = ts.TsFullClient.PermOverview(databaseId.Value, channelId.Value, 0); if (result.Ok) { execCtx.Permissions = new PermOverview[Enum.GetValues(typeof(Ts3Permission)).Length]; foreach (var perm in result.Value) { if (perm.PermissionId < 0 || (int)perm.PermissionId >= execCtx.Permissions.Length) { continue; } var cur = execCtx.Permissions[(int)perm.PermissionId]; execCtx.Permissions[(int)perm.PermissionId] = cur == null ? perm : cur.Combine(perm); } } } } } else { execCtx = new ExecuteContext(); } if (info.TryGet <CallerInfo>(out var caller)) { execCtx.IsApi = caller.ApiCall; } if (info.TryGet <Bot>(out var bot)) { var botInfo = bot.GetInfo(); execCtx.Bot = botInfo.Name; execCtx.Host = botInfo.Server; } if (localRootRule != null) { ProcessNode(localRootRule, execCtx); } if (execCtx.MatchingRules.Count == 0) { return(execCtx); } foreach (var rule in execCtx.MatchingRules) { execCtx.DeclAdd.UnionWith(rule.DeclAdd); } info.AddDynamicObject(execCtx); return(execCtx); }
private ExecuteContext GetRightsContext(InvokerData inv) { if (needsRecalculation) { cachedRights.Invalidate(); needsRecalculation = false; ReadFile(); } if (!cachedRights.TryGetValue(inv, out ExecuteContext execCtx)) { execCtx = new ExecuteContext(); // Get Required Matcher Data: // In this region we will iteratively go through different possobilitys to obtain // as much data as we can about our invoker. // For this step we will prefer query calls which can give us more than one information // at once and lazily fall back to other calls as long as needed. if (inv.ClientId.HasValue && ((needsAvailableGroups && execCtx.AvailableGroups == null) || (needsAvailableChanGroups && !execCtx.ChannelGroupId.HasValue))) { var result = botParent.QueryConnection.GetClientInfoById(inv.ClientId.Value); if (result.Ok) { if (execCtx.AvailableGroups == null) { execCtx.AvailableGroups = result.Value.ServerGroups; } if (!execCtx.ChannelGroupId.HasValue) { execCtx.ChannelGroupId = result.Value.ChannelGroupId; } } } if (needsAvailableGroups && inv.DatabaseId.HasValue && execCtx.AvailableGroups == null) { var result = botParent.QueryConnection.GetClientServerGroups(inv.DatabaseId.Value); if (result.Ok) { execCtx.AvailableGroups = result.Value; } } if (execCtx.AvailableGroups == null) { execCtx.AvailableGroups = new ulong[0]; } execCtx.ClientUid = inv.ClientUid; execCtx.Visibiliy = inv.Visibiliy; execCtx.ApiToken = inv.Token; execCtx.IsApi = inv.IsApi; ProcessNode(rootRule, execCtx); if (execCtx.MatchingRules.Count == 0) { return(execCtx); } foreach (var rule in execCtx.MatchingRules) { execCtx.DeclAdd.UnionWith(rule.DeclAdd); } cachedRights.Store(inv, execCtx); } return(execCtx); }
private async ValueTask <ExecuteContext> GetRightsContext(ExecutionInformation info) { var localRootRule = TryGetRootSafe(); if (info.TryGet <ExecuteContext>(out var execCtx)) { return(execCtx); } execCtx = new ExecuteContext(); if (info.TryGet <ClientCall>(out var clientCall)) { execCtx.ServerGroups = clientCall.ServerGroups; execCtx.ClientUid = clientCall.ClientUid; execCtx.Visibiliy = clientCall.Visibiliy; execCtx.IsApi = false; // Get Required Matcher Data: // In this region we will iteratively go through different possibilities to obtain // as much data as we can about our invoker. // For this step we will prefer query calls which can give us more than one information // at once and lazily fall back to other calls as long as needed. if (info.TryGet <Ts3Client>(out var ts) && info.TryGet <TsFullClient>(out var tsClient)) { ServerGroupId[]? serverGroups = clientCall.ServerGroups; ChannelId? channelId = clientCall.ChannelId; ClientDbId? databaseId = clientCall.DatabaseId; ChannelGroupId?channelGroup = clientCall.ChannelGroup; if (clientCall.ClientId != null && ((needsAvailableGroups && serverGroups is null) || (needsAvailableChanGroups && channelGroup is null) || (needsPermOverview.Length > 0 && (databaseId == null || channelId == null)) ) ) { try { var clientInfo = await ts.GetClientInfoById(clientCall.ClientId.Value); serverGroups = clientInfo.ServerGroups; channelGroup = clientInfo.ChannelGroup; databaseId = clientInfo.DatabaseId; channelId = clientInfo.ChannelId; } catch (AudioBotException) { } } if (needsAvailableGroups && serverGroups is null) { if (databaseId == null) { try { databaseId = await ts.GetClientDbIdByUid(clientCall.ClientUid); } catch (AudioBotException) { } } if (databaseId != null) { try { serverGroups = await ts.GetClientServerGroups(databaseId.Value); } catch (AudioBotException) { } } } execCtx.ChannelGroupId = channelGroup; execCtx.ServerGroups = serverGroups ?? Array.Empty <ServerGroupId>(); if (needsPermOverview.Length > 0 && databaseId != null && channelId != null) { // TODO check if there is any better way to only get the permissions needed. var result = await tsClient.PermOverview(databaseId.Value, channelId.Value, 0); if (result.Ok) { execCtx.Permissions = new PermOverview[Enum.GetValues(typeof(TsPermission)).Length]; foreach (var perm in result.Value) { if (perm.PermissionId < 0 || (int)perm.PermissionId >= execCtx.Permissions.Length) { continue; } var cur = execCtx.Permissions[(int)perm.PermissionId]; execCtx.Permissions[(int)perm.PermissionId] = cur == null ? perm : cur.Combine(perm); } } } } } else if (info.TryGet <ApiCall>(out var apiCallData)) { execCtx.ClientUid = apiCallData.ClientUid; execCtx.ApiToken = apiCallData.Token; execCtx.ApiCallerIp = apiCallData.IpAddress; execCtx.IsApi = true; } if (info.TryGet <Bot>(out var bot)) { var botInfo = bot.GetInfo(); execCtx.Bot = botInfo.Name; execCtx.Host = botInfo.Server; } if (localRootRule != null) { ProcessNode(localRootRule, execCtx); } if (execCtx.MatchingRules.Count == 0) { return(execCtx); } foreach (var rule in execCtx.MatchingRules) { execCtx.DeclAdd.UnionWith(rule.DeclAdd); } info.AddModule(execCtx); return(execCtx); }