Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }