using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; namespace WinUI { class CentralAPI { private static volatile CentralAPI instance; private static object syncRoot = new Object(); private CookieContainer cookieContainer; private HttpClientHandler clientHandler; private HttpClient client; private CentralServer server; public CentralServer Central { get { return this.server; } set { this.server = value; WriteCentralConfig(); UpdateRequestHeaders(); } } public static CentralAPI Instance { get { if (instance == null) { lock (syncRoot) { if (instance == null) { instance = new CentralAPI(); } } } return instance; } } private CentralAPI() { #if DEBUG ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; #endif cookieContainer = new CookieContainer(); clientHandler = new HttpClientHandler { AllowAutoRedirect = true, UseCookies = true, CookieContainer = cookieContainer }; client = new HttpClient(clientHandler); string centralConfigPath = CentralConfigFile(); if (File.Exists(centralConfigPath)) { byte[] tmp = File.ReadAllBytes(centralConfigPath); string json = Encoding.UTF8.GetString(tmp).Trim(); CentralServer ctmp = JsonConvert.DeserializeObject(json); if (ctmp != null) { Central = ctmp; } else { Central = new CentralServer(); } } else { Central = new CentralServer(); } } public bool HasAccessToken() { if (Central == null) return false; return !string.IsNullOrEmpty(Central.APIKey); } private string ZeroTierDir() { return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\ZeroTier\\One"; } private string CentralConfigFile() { return ZeroTierDir() + "\\central.conf"; } public void WriteCentralConfig() { string json = JsonConvert.SerializeObject(Central); byte[] tmp = Encoding.UTF8.GetBytes(json); if (tmp != null) { File.WriteAllBytes(CentralConfigFile(), tmp); } } private void UpdateRequestHeaders() { if (client.DefaultRequestHeaders.Contains("Authorization")) { client.DefaultRequestHeaders.Remove("Authorization"); } if (!string.IsNullOrEmpty(Central.APIKey)) { client.DefaultRequestHeaders.Add("Authorization", "bearer " + Central.APIKey); } } public async Task Login(string email, string password, bool isNewUser) { string postURL = Central.ServerURL + "/api/_auth/local"; CentralLogin login = new CentralLogin(email, password, isNewUser); var content = new StringContent(JsonConvert.SerializeObject(login), Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.PostAsync(postURL, content); if (!response.IsSuccessStatusCode) { return false; } string resContent = await response.Content.ReadAsStringAsync(); CentralUser user = JsonConvert.DeserializeObject(resContent); if (user.Tokens.Count == 0) { // create token user = await CreateAuthToken(user); } Central.APIKey = user.Tokens[0]; UpdateRequestHeaders(); WriteCentralConfig(); return true; } public async Task CreateAuthToken(CentralUser user) { string randomTokenURL = Central.ServerURL + "/api/randomToken"; HttpResponseMessage response = await client.GetAsync(randomTokenURL); if (!response.IsSuccessStatusCode) { // TODO: throw an error return null; } string resContent = await response.Content.ReadAsStringAsync(); CentralToken t = JsonConvert.DeserializeObject(resContent); user.Tokens.Add(t.Token); string tokenObj = "{ \"tokens\": " + JsonConvert.SerializeObject(user.Tokens) + " } "; string postURL = Central.ServerURL + "/api/user/" + user.Id; var postContent = new StringContent(tokenObj, Encoding.UTF8, "application/json"); response = await client.PostAsync(postURL, postContent); if (!response.IsSuccessStatusCode) { // TODO: thrown an error return null; } resContent = await response.Content.ReadAsStringAsync(); user = JsonConvert.DeserializeObject(resContent); return user; } public async Task> GetNetworkList() { string networkURL = Central.ServerURL + "/api/network"; HttpResponseMessage response = await client.GetAsync(networkURL); if (!response.IsSuccessStatusCode) { // TODO: Throw Error return new List(); } string resContent = await response.Content.ReadAsStringAsync(); List networkList = JsonConvert.DeserializeObject>(resContent); return networkList; } public async Task CreateNewNetwork() { string networkURL = Central.ServerURL + "/api/network?easy=1"; CentralNetwork network = new CentralNetwork(); network.Config = new CentralNetwork.CentralNetworkConfig(); network.Config.Name = NetworkNameGenerator.GenerateName(); string jsonNetwork = JsonConvert.SerializeObject(network); var postContent = new StringContent(jsonNetwork, Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.PostAsync(networkURL, postContent); if (!response.IsSuccessStatusCode) { return null; } string resContent = await response.Content.ReadAsStringAsync(); CentralNetwork newNetwork = JsonConvert.DeserializeObject(resContent); return newNetwork; } public async Task AuthorizeNode(string nodeAddress, string networkId) { string json = "{ \"config\": { \"authorized\": true } }"; string postURL = Central.ServerURL + "/api/network/" + networkId + "/member/" + nodeAddress; var postContent = new StringContent(json, Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.PostAsync(postURL, postContent); if (response.IsSuccessStatusCode) { return true; } return false; } } }