diff --git a/Protest/Http/Listener.cs b/Protest/Http/Listener.cs index 181b39ec..637aaec1 100644 --- a/Protest/Http/Listener.cs +++ b/Protest/Http/Listener.cs @@ -276,8 +276,10 @@ private void ListenerCallback(IAsyncResult result) { ctx.Response.Close(); return; } + - if (String.Equals(path, "/api", StringComparison.Ordinal)) { + + if (String.Equals(ctx.Request.Url?.LocalPath, "/api", StringComparison.Ordinal)) { Api.HandleApiCall(ctx); ctx.Response.Close(); return; diff --git a/Protest/Tools/Api.cs b/Protest/Tools/Api.cs index 9d0c2faf..caaa3164 100644 --- a/Protest/Tools/Api.cs +++ b/Protest/Tools/Api.cs @@ -2,7 +2,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Net; using System.Text; using System.Text.Json; @@ -10,6 +9,7 @@ using System.Threading.Tasks; using Protest.Http; +using static Protest.Tools.Api; namespace Protest.Tools; internal static class Api { @@ -18,6 +18,8 @@ internal static class Api { private static readonly ConcurrentDictionary traffic; private static readonly JsonSerializerOptions apiLinksSerializerOptions; + private static ConcurrentDictionary links; + public enum Permissions : byte { Users = 0x01, Devices = 0x02, @@ -40,12 +42,15 @@ static Api() { apiLinksSerializerOptions = new JsonSerializerOptions(); apiLinksSerializerOptions.Converters.Add(new ApiJsonConverter()); + + Api.links = new ConcurrentDictionary(Load().ToDictionary(link => link.apikey)); } internal static void HandleApiCall(HttpListenerContext ctx) { Dictionary parameters = Listener.ParseQuery(ctx.Request.Url.Query); - if (!parameters.TryGetValue("apikey", out string apiKey)) { + if (!parameters.TryGetValue("key", out string apiKey) + || !Api.links.ContainsKey(apiKey)) { ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized; return; } @@ -70,16 +75,15 @@ internal static Link[] Load() { Link[] profiles = JsonSerializer.Deserialize(plain, apiLinksSerializerOptions); return profiles; } - catch { + catch (Exception ex){ + Logger.Error(ex); return Array.Empty(); } } internal static byte[] List() { - Link[] links = Load(); - - var data = new { - data = links.ToDictionary( + return JsonSerializer.SerializeToUtf8Bytes(new { + data = Api.links.Values.ToDictionary( link => link.guid.ToString(), link => new { guid = new { v = link.guid }, @@ -89,26 +93,26 @@ internal static byte[] List() { permissions = new { v = link.permissions } } ), - length = links.Length - }; - - return JsonSerializer.SerializeToUtf8Bytes(data); + length = Api.links.Count() + }); } internal static byte[] Save(HttpListenerContext ctx, string origin) { using StreamReader reader = new StreamReader(ctx.Request.InputStream, ctx.Request.ContentEncoding); string payload = reader.ReadToEnd(); - try { - Link[] links = JsonSerializer.Deserialize(payload, apiLinksSerializerOptions); + Api.links.Clear(); - for (int i = 0; i < links.Length; i++) { - if (links[i].guid == default(Guid)) { - links[i].guid = Guid.NewGuid(); + try { + Link[] temp = JsonSerializer.Deserialize(payload, apiLinksSerializerOptions); + for (int i = 0; i < temp.Length; i++) { + if (temp[i].guid == default(Guid)) { + temp[i].guid = Guid.NewGuid(); } + Api.links.TryAdd(temp[i].guid.ToString(), temp[i]); } - byte[] plain = JsonSerializer.SerializeToUtf8Bytes(links, apiLinksSerializerOptions); + byte[] plain = JsonSerializer.SerializeToUtf8Bytes(temp, apiLinksSerializerOptions); byte[] cipher = Cryptography.Encrypt(plain, Configuration.DB_KEY, Configuration.DB_KEY_IV); lock (mutex) { File.WriteAllBytes(Data.FILE_API_LINKS, cipher); @@ -116,10 +120,12 @@ internal static byte[] Save(HttpListenerContext ctx, string origin) { Logger.Action(origin, $"Modify API links"); } - catch (JsonException) { + catch (JsonException ex) { + Logger.Error(ex); return Data.CODE_INVALID_ARGUMENT.Array; } - catch (Exception) { + catch (Exception ex) { + Logger.Error(ex); return Data.CODE_FAILED.Array; }