From 612ad59547a34f393f5990f24393bfb9afc6d66f Mon Sep 17 00:00:00 2001 From: JacobTech Date: Sun, 21 May 2023 21:38:55 -0400 Subject: [PATCH] Permission Storage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ● When permissions are applied, it will be done recursively. This will help speed up the code for general permission checks. ● This new layout also makes it faster to get the members who have access to a given channel. ● This push also removed a pointless role override. --- LuskiServer/Classes/Luski.cs | 157 +++++++++++------- LuskiServer/Classes/TableDef/Roles.cs | 1 + .../Controllers/v1/SocketMessageController.cs | 3 +- LuskiServer/Program.cs | 13 -- 4 files changed, 103 insertions(+), 71 deletions(-) diff --git a/LuskiServer/Classes/Luski.cs b/LuskiServer/Classes/Luski.cs index 1d5e194..0f383d3 100644 --- a/LuskiServer/Classes/Luski.cs +++ b/LuskiServer/Classes/Luski.cs @@ -3,6 +3,7 @@ using System.Text.Json; using System.Text.Json.Serialization.Metadata; using LuskiServer.Classes.TableDef; using LuskiServer.Enums; +using Npgsql; using ServerDatabase; namespace LuskiServer.Classes; @@ -65,68 +66,112 @@ public static class Luski public static AppConfig Config = null!; + public static long[] GetChannelBroadcastMembers(long Channel) + { + List Members = new(); + long[] ChanUserOverides = Tables.Channels.Read(Channels.UserOverides, Channels.ID.CreateParameter(Channel)); + long[] ChanRoleOverides = Tables.Channels.Read(Channels.RoleOverides, Channels.ID.CreateParameter(Channel)); + Dictionary ChanRoleIDOverides = new(); + foreach (long cro in ChanRoleOverides) + { + ChanRoleIDOverides.Add(Tables.ServerRoleOverides.Read(ServerRoleOverides.RoleID, ServerRoleOverides.ID.CreateParameter(cro)), cro); + } + Dictionary ChanUserIDOverides = new(); + foreach (long cro in ChanUserOverides) + { + ChanUserIDOverides.Add(Tables.UserRoleOverides.Read(UserRoleOverides.UserID, UserRoleOverides.ID.CreateParameter(cro)), cro); + } + + ServerPermissions[] pp = new[] + { ServerPermissions.ViewChannels, ServerPermissions.ViewCategories, ServerPermissions.ReadMessageHistory }; + using NpgsqlConnection dbConnection = Luski.Database.CreateConnection(); + dbConnection.Open(); + using NpgsqlCommand cmd = new(); + cmd.Connection = dbConnection; + cmd.CommandText = $"SELECT {Roles.ID.Name} FROM {Tables.Roles.Name};"; + NpgsqlDataReader reader = cmd.ExecuteReader(); + while (reader.Read()) + { + long rol = reader.GetInt64(0); + List GoodPerms = new(); + if (ChanRoleIDOverides.ContainsKey(rol)) + { + string[] overides = Tables.ServerRoleOverides.Read(ServerRoleOverides.Overides, + ServerRoleOverides.ID.CreateParameter(ChanRoleIDOverides[rol])); + foreach (string o in overides) + { + foreach (ServerPermissions p in pp) + { + if (GoodPerms.Contains(p)) continue; + if (o.StartsWith($"{p.GetNumberString()}:")) + { + if (o.EndsWith("1")) GoodPerms.Add(p); + } + } + } + + if (GoodPerms.Count == pp.Length) + { + foreach (long m in Tables.Roles.Read(Roles.MembersList, Roles.ID.CreateParameter(rol))) + { + if (!Members.Contains(m)) Members.Add(m); + } + } + } + else + { + ServerPermissions[] pppp = Tables.Roles.Read(Roles.ServerPermissions, Roles.ID.CreateParameter(rol)); + foreach (ServerPermissions p in pp) + { + if (GoodPerms.Contains(p)) continue; + if (pppp.Contains(p)) GoodPerms.Add(p); + } + if (GoodPerms.Count == pp.Length) + { + foreach (long m in Tables.Roles.Read(Roles.MembersList, Roles.ID.CreateParameter(rol))) + { + if (!Members.Contains(m)) Members.Add(m); + } + } + } + } + + foreach (long o in ChanUserOverides) + { + List GoodPerms = new(); + long u = Tables.UserRoleOverides.Read(UserRoleOverides.UserID, UserRoleOverides.ID.CreateParameter(o)); + string[] x = Tables.UserRoleOverides.Read(UserRoleOverides.Overides, UserRoleOverides.ID.CreateParameter(o)); + foreach (string oo in x) + { + foreach (ServerPermissions p in pp) + { + if (GoodPerms.Contains(p)) continue; + if (oo.StartsWith($"{p.GetNumberString()}:")) + { + if (oo.EndsWith("1")) GoodPerms.Add(p); + } + } + } + if (GoodPerms.Count == pp.Length) + { + if (!Members.Contains(u)) Members.Add(u); + } + else + { + if (Members.Contains(u)) Members.Remove(u); + } + } + dbConnection.Close(); + return Members.ToArray(); + } + public static bool HasAccessToChannel(long User, long Channel, params ServerPermissions[] RequiredPerms) { long[] UserRoleIDList = Tables.Users.Read(Users.Roles, Users.ID.CreateParameter(User)); List pp = RequiredPerms.ToList(); if (!pp.Contains(ServerPermissions.ViewChannels)) pp.Add(ServerPermissions.ViewChannels); + if (!pp.Contains(ServerPermissions.ViewCategories)) pp.Add(ServerPermissions.ViewCategories); List GoodPerms = new(); - bool more = false; - bool CheckCatPerm(long Cat, List NeededPerms, bool more2 = false) - { - more = more2; - if (more2 && pp.Contains(ServerPermissions.ViewCategories)) pp.Add(ServerPermissions.ViewCategories); - long Parent = Tables.Categories.Read(Categories.Parent, Categories.ID.CreateParameter(Channel)); - if (Parent != -1 && !CheckCatPerm(Parent, pp, true)) return false; - long[] CatUserOverides = Tables.Categories.Read(Categories.UserOverides, Categories.ID.CreateParameter(Cat)); - foreach (long CatUserOveride in CatUserOverides) - { - if (Tables.UserRoleOverides.Read(UserRoleOverides.UserID, UserRoleOverides.ID.CreateParameter(CatUserOveride)) != User) continue; - string[] overrids = Tables.UserRoleOverides.Read(UserRoleOverides.Overides, - UserRoleOverides.ID.CreateParameter(CatUserOveride)); - foreach (string o in overrids) - { - foreach (ServerPermissions p in NeededPerms) - { - if (o.StartsWith($"{p.GetNumberString()}:")) - { - if (o.EndsWith("0")) return false; - else GoodPerms.Add(p); - } - } - } - } - long[] CatRoleOverides = Tables.Categories.Read(Categories.RoleOverides, Categories.ID.CreateParameter(Cat)); - foreach (long CatRoleOveride in CatRoleOverides) - { - if (!UserRoleIDList.Contains(Tables.ServerRoleOverides.Read(ServerRoleOverides.RoleID, ServerRoleOverides.ID.CreateParameter(CatRoleOveride)))) continue; - string[] overrids = Tables.UserRoleOverides.Read(ServerRoleOverides.Overides, - ServerRoleOverides.ID.CreateParameter(CatRoleOveride)); - foreach (string o in overrids) - { - foreach (ServerPermissions p in NeededPerms) - { - if (o.StartsWith($"{p.GetNumberString()}:")) - { - if (o.EndsWith("0")) return false; - else GoodPerms.Add(p); - } - } - } - } - - if (GoodPerms.Count == NeededPerms.Count) return true; - return false; - } - - if (!CheckCatPerm(Tables.Channels.Read(Channels.Parent, Channels.ID.CreateParameter(Channel)), pp)) return false; - if (more && !GoodPerms.Contains(ServerPermissions.ViewCategories)) return false; - - foreach (ServerPermissions v in GoodPerms) - { - pp.Remove(v); - } - GoodPerms.Clear(); long[] ChanUserOverides = Tables.Channels.Read(Channels.UserOverides, Channels.ID.CreateParameter(Channel)); foreach (long ChanUserOveride in ChanUserOverides) { diff --git a/LuskiServer/Classes/TableDef/Roles.cs b/LuskiServer/Classes/TableDef/Roles.cs index 7483641..6871359 100644 --- a/LuskiServer/Classes/TableDef/Roles.cs +++ b/LuskiServer/Classes/TableDef/Roles.cs @@ -10,4 +10,5 @@ public static class Roles public static TableColumn Color { get; } = new("color"); public static TableColumn Description { get; } = new("description"); public static TableColumn ServerPermissions { get; } = new("server_perms"); + public static TableColumn MembersList { get; } = new("members_list") {DefaultValue = Array.Empty()}; } \ No newline at end of file diff --git a/LuskiServer/Controllers/v1/SocketMessageController.cs b/LuskiServer/Controllers/v1/SocketMessageController.cs index 62320aa..f513948 100644 --- a/LuskiServer/Controllers/v1/SocketMessageController.cs +++ b/LuskiServer/Controllers/v1/SocketMessageController.cs @@ -42,12 +42,11 @@ public class SocketMessageController : ControllerBase Messages.Files.CreateParameter(data.Files), Messages.EncoderType.CreateParameter(data.Encoding), Messages.EncryptionType.CreateParameter(data.Encryption)); - //TODO Get all ID for members to send to WSS.SendData(SendType.ID_Group, new ServerEvent() { Type = DataType.MessageCreate, Data = MessageEvent - }, Array.Empty()); + }, Luski.GetChannelBroadcastMembers(data.ChannelID)); Response.StatusCode = 201; return null!; } diff --git a/LuskiServer/Program.cs b/LuskiServer/Program.cs index f030449..050e646 100644 --- a/LuskiServer/Program.cs +++ b/LuskiServer/Program.cs @@ -75,19 +75,6 @@ if (!Tables.Roles.TryRead(Roles.ID, out _, Roles.ID.CreateParameter(0))) ); } -if (!Tables.ServerRoleOverides.TryRead(ServerRoleOverides.ID, out _, Categories.ID.CreateParameter(0))) -{ - Tables.ServerRoleOverides.Insert( - ServerRoleOverides.ID.CreateParameter(0), - ServerRoleOverides.RoleID.CreateParameter(0), - ServerRoleOverides.Overides.CreateParameter(new string[] - { - $"{ServerPermissions.ViewCategories.GetNumberString()}:1", - $"{ServerPermissions.ViewChannels.GetNumberString()}:1", - }) - ); -} - if (!Tables.Categories.TryRead(Categories.ID, out _, Categories.ID.CreateParameter(0))) { Tables.Categories.Insert(