using MTWireGuard.Models; using MTWireGuard.Models.Mikrotik; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Linq; using System.Net; using System.Net.Http.Headers; using System.Text; using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; namespace MTWireGuard { public static class MTAPIHandler { private static readonly string MT_IP = Environment.GetEnvironmentVariable("MT_IP"); private static readonly string MT_USER = Environment.GetEnvironmentVariable("MT_USER"); private static readonly string MT_PASS = Environment.GetEnvironmentVariable("MT_PASS"); public static async Task> GetLogsAsync() { string json = await SendGetRequestAsync("log"); var model = JsonConvert.DeserializeObject>(json); return model.Select(x => new LogViewModel() { Id = Convert.ToUInt64(x.Id[1..], 16), Message = x.Message, Time = x.Time, Topics = x.Topics.Split(',').Select(t => t = Helper.UpperCaseTopics.Contains(t) ? t.ToUpper() : t.FirstCharToUpper()).ToList() }).ToList(); } public static async Task> GetServersAsync() { string json = await SendGetRequestAsync("interface/wireguard"); var model = JsonConvert.DeserializeObject>(json); return model.Select(x => new WGServerViewModel() { Id = Convert.ToInt32(x.Id[1..], 16), Name = x.Name, ListenPort = Convert.ToUInt16(x.ListenPort), MTU = Convert.ToUInt16(x.MTU), Running = x.Running, IsEnabled = !x.Disabled, PublicKey = x.PublicKey, PrivateKey = x.PrivateKey }).ToList(); } public static async Task GetServer(string Name) { var servers = await GetServersAsync(); return servers.Find(s => s.Name == Name); } public static async Task> GetServersTraffic() { var json = await SendPostRequestAsync("interface", "{\"stats\", {\".proplist\":\"name,rx-byte, tx-byte\"}}"); List traffic = JsonConvert.DeserializeObject>(json); return traffic; } public static async Task> GetUsersAsync() { using var db = new DBContext(); string json = await SendGetRequestAsync("interface/wireguard/peers"); List apiUsers = JsonConvert.DeserializeObject>(json); List dbUsers = db.Users.ToList(); Dictionary differences = new(); // Start Checking DB and Router sync foreach (var apiUser in apiUsers) { var id = Convert.ToInt32(apiUser.Id[1..], 16); var dbUser = dbUsers.Find(u => u.Id == id); if (dbUser == null) { differences.Add(id, true); } else { string publickey = apiUser.PublicKey; bool publicKeyDifferent = dbUser.PublicKey != publickey; bool noPrivateKey = string.IsNullOrWhiteSpace(dbUser.PrivateKey); differences.Add(id, publicKeyDifferent | noPrivateKey); } } // End Checking return apiUsers.Select(x => new WGPeerViewModel() { Id = Convert.ToInt32(x.Id[1..], 16), Name = (dbUsers.Find(u => u.Id == Convert.ToInt32(x.Id[1..], 16)) != null) ? dbUsers.Find(u => u.Id == Convert.ToInt32(x.Id[1..], 16)).Name : "", Address = x.AllowedAddress, CurrentAddress = $"{x.CurrentEndpointAddress}:{x.CurrentEndpointPort}", Interface = x.Interface, IsEnabled = !x.Disabled, PublicKey = x.PublicKey, Download = x.RX, Upload = x.TX, IsDifferent = differences[Convert.ToInt32(x.Id[1..], 16)] }).ToList(); } public static async Task GetUser(int id) { var users = await GetUsersAsync(); return users.Find(u => u.Id == id); } public static async Task GetIPAddress() { var json = await SendGetRequestAsync("ip/address?interface=ether1&.proplist=address"); var IP = JsonConvert.DeserializeObject>(json).FirstOrDefault(); var address = IP.Address[..IP.Address.IndexOf('/')]; return address; } public static async Task GetInfo() { var json = await SendGetRequestAsync("system/resource"); var model = JsonConvert.DeserializeObject(json); return new() { Architecture = model.ArchitectureName, BoardName = model.BoardName, CPU = model.CPU, CPUCount = Convert.ToByte(model.CPUCount), CPUFrequency = Convert.ToInt16(model.CPUFrequency), CPULoad = Convert.ToByte(model.CPULoad), TotalHDDBytes = Convert.ToInt64(model.TotalHDDSpace), FreeHDDBytes = Convert.ToInt64(model.FreeHDDSpace), UsedHDDBytes = Convert.ToInt64(model.TotalHDDSpace) - Convert.ToInt64(model.FreeHDDSpace), FreeHDDPercentage = (byte)(Convert.ToInt64(model.FreeHDDSpace) * 100 / Convert.ToInt64(model.TotalHDDSpace)), TotalRAMBytes = Convert.ToInt64(model.TotalMemory), FreeRAMBytes = Convert.ToInt64(model.FreeMemory), UsedRAMBytes = Convert.ToInt64(model.TotalMemory) - Convert.ToInt64(model.FreeMemory), FreeRAMPercentage = (byte)(Convert.ToInt64(model.FreeMemory) * 100 / Convert.ToInt64(model.TotalMemory)), TotalHDD = Helper.ConvertByteSize(Convert.ToInt64(model.TotalHDDSpace)), FreeHDD = Helper.ConvertByteSize(Convert.ToInt64(model.FreeHDDSpace)), UsedHDD = Helper.ConvertByteSize(Convert.ToInt64(model.TotalHDDSpace) - Convert.ToInt64(model.FreeHDDSpace)), TotalRAM = Helper.ConvertByteSize(Convert.ToInt64(model.TotalMemory)), FreeRAM = Helper.ConvertByteSize(Convert.ToInt64(model.FreeMemory)), UsedRAM = Helper.ConvertByteSize(Convert.ToInt64(model.TotalMemory) - Convert.ToInt64(model.FreeMemory)), UPTime = model.Uptime. Replace('d', ' '). Replace('h', ':'). Replace('m', ':'). Replace("s", ""), Platform = model.Platform, Version = model.Version }; } public static async Task TryConnectAsync() { try { var connection = await SendGetRequestAsync("", true); var status = JsonConvert.DeserializeObject(connection); if ((status.Error == 400 && status.Message == "Bad Request") || (status.Error == 401 && status.Message == "Unauthorized")) { return true; } throw new($"[{status.Error}] Login failed, {status.Message}.
Enter router username/password in environment variables (MT_USER/MT_PASS)."); } catch { throw; } } public static async Task GetCurrentSessionID() { var sessionJson = await SendGetRequestAsync("user/active?name=admin&via=api&.proplist=when"); JArray session = JArray.Parse(sessionJson); var jobsJson = await SendGetRequestAsync("system/script/job?type=api-login&started=" + session.FirstOrDefault()["when"]); JArray jobs = JArray.Parse(jobsJson); return jobs.FirstOrDefault()[".id"].ToString(); } public static async Task KillJob(string JobID) { return await SendDeleteRequestAsync("system/script/job/" + JobID); } public static async Task GetTrafficSpeed() { return await SendPostRequestAsync("interface/monitor-traffic", "{\"interface\":\"ether1\",\"duration\":\"3s\"}"); } private static async Task SendGetRequestAsync(string URL, bool IsTest = false) { HttpClientHandler handler = new() { ServerCertificateCustomValidationCallback = delegate { return true; } }; using HttpClient httpClient = new(handler); using var request = new HttpRequestMessage(new HttpMethod("GET"), $"https://{MT_IP}/rest/{URL}"); string base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{MT_USER}:{MT_PASS}")); if (!IsTest) request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}"); HttpResponseMessage response = await httpClient.SendAsync(request); string APIResponse = await response.Content.ReadAsStringAsync(); return APIResponse; } private static async Task SendPostRequestAsync(string URL, string Data) { HttpClientHandler handler = new() { ServerCertificateCustomValidationCallback = (requestMessage, certificate, chain, policyErrors) => true }; using HttpClient httpClient = new(handler); using var request = new HttpRequestMessage(new HttpMethod("GET"), $"https://{MT_IP}/rest/{URL}"); string base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{MT_USER}:{MT_PASS}")); request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}"); request.Content = new StringContent(Data); request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); HttpResponseMessage response = await httpClient.SendAsync(request); return await response.Content.ReadAsStringAsync(); } private static async Task SendDeleteRequestAsync(string URL) { HttpClientHandler handler = new() { ServerCertificateCustomValidationCallback = (requestMessage, certificate, chain, policyErrors) => true }; using HttpClient httpClient = new(handler); using var request = new HttpRequestMessage(new HttpMethod("DELETE"), $"https://{MT_IP}/rest/{URL}"); string base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{MT_USER}:{MT_PASS}")); request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}"); HttpResponseMessage response = await httpClient.SendAsync(request); return await response.Content.ReadAsStringAsync(); } } }