279 lines
13 KiB
C#
279 lines
13 KiB
C#
using System.Security.Cryptography;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization.Metadata;
|
|
using LuskiServer.Classes.TableDef;
|
|
using LuskiServer.Enums;
|
|
using ServerDatabase;
|
|
|
|
namespace LuskiServer.Classes;
|
|
|
|
public static class Luski
|
|
{
|
|
public static Database Database = null!;
|
|
|
|
public static TResult GetSettings<TResult>(string path, JsonTypeInfo<TResult> TypeInfo, bool EndOnError = false, bool UpdateOldFile = true) where TResult : new()
|
|
{
|
|
TResult? @out;
|
|
if (!File.Exists(path))
|
|
{
|
|
@out = new();
|
|
try
|
|
{
|
|
File.WriteAllText(path, JsonSerializer.Serialize(@out, TypeInfo));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine("cant write file at '{0}'. make sure the premisions are set", path);
|
|
if (EndOnError) Environment.Exit(0);
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
string Fil = "";
|
|
try
|
|
{
|
|
Fil = File.ReadAllText(path);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine("cant read file at '{0}'. make sure the premisions are set", path);
|
|
if (EndOnError) Environment.Exit(0);
|
|
}
|
|
@out = JsonSerializer.Deserialize(Fil, TypeInfo);
|
|
if (@out is null)
|
|
{
|
|
@out = new();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
@out = new();
|
|
}
|
|
|
|
try
|
|
{
|
|
if (UpdateOldFile) File.WriteAllText(path, JsonSerializer.Serialize(@out, TypeInfo));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine("cant write file at '{0}'. make sure the premisions are set", path);
|
|
if (EndOnError) Environment.Exit(0);
|
|
}
|
|
return @out;
|
|
}
|
|
|
|
public static AppConfig Config = null!;
|
|
|
|
public static bool HasAccessToChannel(long User, long Channel, params ServerPermissions[] RequiredPerms)
|
|
{
|
|
long[] UserRoleIDList = Tables.Users.Read(Users.Roles, Users.ID.CreateParameter(User));
|
|
List<ServerPermissions> pp = RequiredPerms.ToList();
|
|
if (!pp.Contains(ServerPermissions.ViewChannels)) pp.Add(ServerPermissions.ViewChannels);
|
|
List<ServerPermissions> GoodPerms = new();
|
|
bool more = false;
|
|
bool CheckCatPerm(long Cat, List<ServerPermissions> 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)
|
|
{
|
|
if (Tables.UserRoleOverides.Read(UserRoleOverides.UserID, UserRoleOverides.ID.CreateParameter(ChanUserOveride)) != User) continue;
|
|
string[] overrids = Tables.UserRoleOverides.Read(UserRoleOverides.Overides,
|
|
UserRoleOverides.ID.CreateParameter(ChanUserOveride));
|
|
foreach (string o in overrids)
|
|
{
|
|
foreach (ServerPermissions p in pp)
|
|
{
|
|
if (o.StartsWith($"{p.GetNumberString()}:"))
|
|
{
|
|
if (o.EndsWith("0")) return false;
|
|
else GoodPerms.Add(p);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
long[] ChanRoleOverides = Tables.Channels.Read(Channels.RoleOverides, Channels.ID.CreateParameter(Channel));
|
|
foreach (long ChanRoleOveride in ChanRoleOverides)
|
|
{
|
|
if (!UserRoleIDList.Contains(Tables.ServerRoleOverides.Read(ServerRoleOverides.RoleID, ServerRoleOverides.ID.CreateParameter(ChanRoleOveride)))) continue;
|
|
string[] overrids = Tables.UserRoleOverides.Read(ServerRoleOverides.Overides,
|
|
ServerRoleOverides.ID.CreateParameter(ChanRoleOveride));
|
|
foreach (string o in overrids)
|
|
{
|
|
foreach (ServerPermissions p in pp)
|
|
{
|
|
if (o.StartsWith($"{p.GetNumberString()}:"))
|
|
{
|
|
if (o.EndsWith("0")) return false;
|
|
else GoodPerms.Add(p);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (GoodPerms.Count == pp.Count) return true;
|
|
return false;
|
|
}
|
|
|
|
public static class Info
|
|
{
|
|
public static class Routes
|
|
{
|
|
public static class Default
|
|
{
|
|
public const string Base = "v{version:apiVersion}/[controller]";
|
|
public const string BaseID = $"{Base}/{{id?}}";
|
|
public const string Action = $"{Base}/{{action?}}";
|
|
public const string ActionID = $"{Action}/{{id?}}";
|
|
}
|
|
}
|
|
|
|
// public static readonly DateTime ServerEpoch = new(2023, 1, 1, 0, 0, 0, 0);
|
|
|
|
public static long GetTimestampFromEpoch(DateTime Epoch)
|
|
{
|
|
double ts = Math.Round(DateTime.UtcNow.Subtract(Epoch).TotalMilliseconds, 0);
|
|
return long.Parse(ts.ToString().Replace(".", string.Empty));
|
|
}
|
|
}
|
|
|
|
public class Snowflake
|
|
{
|
|
public Snowflake(long ID)
|
|
{
|
|
this.ID = ID;
|
|
Increment = (ushort)((ID << 52) >>> 52);
|
|
Data_ID = (byte)((ID << 44) >>> 56);
|
|
Timestamp = ID >> 20;
|
|
}
|
|
|
|
public static Snowflake GenerateSnowflake(DateTime Epoch)
|
|
{
|
|
i++;
|
|
if (i > 0b_1111_1111_1111) i = 0;
|
|
return new Snowflake((((Info.GetTimestampFromEpoch(Epoch) << 8) | Config.DataId) << 12) | i);
|
|
}
|
|
|
|
public long ID { get; }
|
|
public long Timestamp { get; }
|
|
public byte Data_ID { get; }
|
|
public ushort Increment { get; }
|
|
|
|
private static ushort i = 0;
|
|
}
|
|
|
|
public static class Encryption
|
|
{
|
|
internal const int PasswordVersion = 0;
|
|
|
|
internal static byte[] RemotePasswordEncrypt(string Base64Password, byte[] salt, int PasswordVersion = PasswordVersion)
|
|
{
|
|
return PasswordVersion switch
|
|
{
|
|
0 => JacobTechEncryption.Encryption.Hashing.SHA256(JacobTechEncryption.Encryption.RSA.Decrypt(Convert.FromBase64String(Base64Password), Keys.PrivateKey), salt),
|
|
_ => throw new ArgumentException("The value provided was not accepted", nameof(PasswordVersion)),
|
|
};
|
|
}
|
|
|
|
public static class Keys
|
|
{
|
|
private static readonly RSACryptoServiceProvider RSA = new(4096);
|
|
private static RSAParameters? Priv = null;
|
|
private static string? DBPriv = null;
|
|
private static string? Pub = null;
|
|
internal static RSAParameters PrivateKey
|
|
{
|
|
get
|
|
{
|
|
if (Priv == null)
|
|
{
|
|
Priv = RSA.ExportParameters(true);
|
|
Pub = RSA.ToXmlString(false);
|
|
using RSACryptoServiceProvider rsa = new(4096);
|
|
rsa.FromXmlString(PrivateKeyString);
|
|
DBPriv = rsa.ToXmlString(true);
|
|
}
|
|
return (RSAParameters)Priv;
|
|
}
|
|
}
|
|
|
|
public static string PrivateKeyString
|
|
{
|
|
get
|
|
{
|
|
//This will not stay like this for long so it's not an exploit, lol
|
|
return "<RSAKeyValue><Modulus>2pR655ycDWZuQiPWlcpvloFo2lmcxZJ88nlwNANOri8y+jCrqYvJLLjHW/PHBzDSx/wHEL6GYm/FIPdywgcHzi1a5tuDcdRBrKKqQU/mTW3z2d38H+BJlUCQT/Dai5SXX52p6ZSQBj2Tb4cHZSv3/6vLh1dtJdHYW+RlnadGCKoLJNBF/FQFPBgRkuP69XfAnyM8RTLzzQAcwdmw00pHOdoYV0Ue70MOF3Vv1InnxmB4uOPW6MK45NPH/1u1NkVcp3OZWRAv3xJHfS5CAwtDddnxe4a9f/grvV0lxx4ZCYRLgoe5Lv+0NVIcL+oXdJUI9geyZpfxDpdjdPRc8IA+t+0yyUHTEjyQ3focmFc8fNkmiaxji5sNvG1pWq8Q8MaqgIk1gjRSKJTnWU9N54BMB4pYgRXdVAj/jPS23tgPlcDZNMKvhzIWnzPKEA5CXICPa5DbNYfUbX4DGZlhFv6xkpMMx6jx6WPqIq+XmfaUq6NG6/E/KjbsKzTRk5C4Jfk6doiP5HSdXwP9+yXb1XRus736YoiIABuoCnj8h7OD7+ux31PcCP9PXFayMMxfxZglhw7GhT7MlNb5E9c6ELTqk7exLVxxXG8VL/RpfgyiUzliOjQIM4xyRGBCTXWbr0kRLoW0T9PzGFJzfu2smxSEdmSR9bkC7/i5T3msYa2RiSk=</Modulus><Exponent>AQAB</Exponent><P>5coLKzyBRhzAi8myKb6neZJTxQ2MgQAtXmWCT0xr1xl7wfJ1oQ2q5EQ/FKKD6ejbAyJoJ0deE9dcWUNaxvUmIa9tqHoqxpwr4dBu0IWY+9ZjbS9AmPEzJF0pDqA6NZ5ctxUZ00WzG+swepfjXOPuXqmCX1aV32zJPBN2fo2nrozOdZDqMUB3AeFu4B8zVJKYEXTzVRLnpvY7GdH2xdL/3XvHKwfnrbGv+ScHuNBP1t4oRbNTGLU6eiyK5YbpSL895HrvZYjrg9fkKQDfL0xGQLJOw/agCbwLNlSLhfBSNOfS6B4ehsMurR71Ckpg+kfzy87DssHk6oUrqFD8EcNSqw==</P><Q>84MfGPF7ivPs4hNj7CcVTh8XgOj25kb4j7X+LXzmNTnBtQ/nO9V2j0NUTg/R5gkwSFEyBIJB9lq/wsuebfS22jmxg7mwgVHFFl7JyqcRaiYY1Dl1HKTKgeCsuY7yP5WQCLfYbQ1G7tcgtcQzlPV86W2pgWsVcxcq8gqbk3k4GbPd30kPmfCPxxtxIhyoQxqPxx/FV12PeN9z+G2A70nPDwtkZ2MiiVj/RttTTPrijd5KjV6zS4jDHeYgfO3NZUviyJ8YvhCKB4ttcjM77BV8HdRgBg4XHO+NwDsMukNvAYaPDEfK42UIhne7CZJ/il8h/4OKxRzfFtAnTx/pQ8Jzew==</Q><DP>CnHzrgRzD9/QtMn3SkR7UmBfZG6oO1jptwfAM6CSqlVjNb6ysB5x7SxY/bQhcOl/wxW2TErHMPmyHfCc2Lxd/lv+DRF4jkydBge2cc4Q1Sm6nUTvl8QnAfkmG58W5kcLidrwsJTTfmpjar8qu5c0x6LG5VSHPX+xagSsdzYzMBEAdYGf05tNjY1Uv+VLLQX42ZpKUUypsQIyT4smv3lG3id5NzCFzHRuPlIS3MjDSE4S4JA1L8NVJCaQLbzDL+ZZhuA7r47YvcZ7fY2nl3vNGbXBNNEqFycwD0kqim0RH4yGHrz3wEJxBbeJhe05mUbaAyKj7KU5pZtmD6GWw6vwPw==</DP><DQ>ZUnZGYr4lGe51J+0JHptRj1wjVJZwJcstLpCq7EUIHeRtzqSODUmR5j97CpwaHrR9oKvh2iW/13n/aKsl5f+pu7wg5YtcN0OWau7y+uKNtj54uyzZeK1ySgnMFfhM8mGS9oMz++B3b7mADVIL2GdP4s5wndESMcOOfdnlwQI7cf/Ne0x7Bo/89XaTRIWezMFMxJoB1sHXoOzvVXvF5lf4yYd8VMu/mpiZJq+H3sL2W7pG7yUX4rXfgxG3zAbC1NxVXm31PcUMucv8xyUhDK7mbzI5DvgKU0LbTYiqSd7eOr7fWQvZD6WOTh8OBMTsf64KYwRoMPNl7OlZigj4udzGQ==</DQ><InverseQ>Z5mTYcXZwGh4CZLG5w80GULXzmPm8UQadZJf2PHqSDSNYFdsNGvYP/H1qtn+ZHr6SGJRF2Q0E0MqBIcAZ+iZ7IaaQ+pDszXUoqBKruuLbNk4u2ClYBWjx4ziKfPzF68utOm49EN+Zh7sTOQvUlAO7STE1iuUUGZbCvNybSoH1EP8J+snMPdlIK0M2vdE/yKI7jyqD6NGPTIJYyfnvwkRDr1cv88MgNmOEed8lnTrw69Su21WL2Eh8ePSxStTKQpVMXdefpfTx7B7TrFwDSw7P22RjHc6qFktBXlixwYjuHZBv2OwBA6ii1jQzZjT/IqJFT99pmOmg2BchQwOfD5WCQ==</InverseQ><D>DG0sOZZT4YfPv+SFXWRcs1vtvUV381wwd0vZHv6LJBLx3SW+30zfpd0Rab8HsyHJnJii7DGbYTrvzup9HzPCyVbBwrslvhHDnrrBXs+EjSVcRigSc9t5Q3TKtN4WsUsZef70JcqOOj9DmQUTsg2YXp7X23y9wKHX9jgbYNBIMSjoU5z1mvKfOOXjZeGefFhlCTG5ykirHJ342eUe4jw9pWJ/8heEuonU4heJQTY1M417f4NlzeYiwyZDygGJi/7QgC1DFrxOrxS9H2GYW3pHSQrCvvOPkBgTSy42/hrOG0DmrBKRlW7wbKbw4aEiLpIPKDGS07X9Udzgc3SLA28/DB9AdX6qZSKEmf33LwK47wLEZkiLbU/IO/kb0MpSpl77TrMDrl1J+3Kgcmz7q9eF83W9519/uZgZpOSO/a/97oMKZSfLeyASVP7K1EcqK23K/wjvaP3nvSMGsiQmqCn4jItgfH5N/tcnkNz2DKz3BPcfgAClVH1MFsjDlBqYSHXIqwAFQ8SDBixrPoLoJDkygFoNIrrXqbArVYqXOAgODo2t0foENa/msPJyZ6m6UPi3bMY3gji5qjaSEcvbBmhlSVyHmumgOJ5Rl+L5dS5jAyPgybcVYKab71XQf5sm1UhA8iFWqYgyglmR/b6F9UTFi1QwZA6rgvELFv7DvqjLbmM=</D></RSAKeyValue>";
|
|
}
|
|
}
|
|
|
|
public static string PublicKey
|
|
{
|
|
get
|
|
{
|
|
if (Pub == null)
|
|
{
|
|
Priv = RSA.ExportParameters(true);
|
|
Pub = RSA.ToXmlString(false);
|
|
using RSACryptoServiceProvider rsa = new(4096);
|
|
rsa.FromXmlString(PrivateKeyString);
|
|
DBPriv = rsa.ToXmlString(true);
|
|
}
|
|
return Pub;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |