CentralAPI.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Net.Http;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using Newtonsoft.Json;
  10. namespace WinUI
  11. {
  12. class CentralAPI
  13. {
  14. private static volatile CentralAPI instance;
  15. private static object syncRoot = new Object();
  16. private CookieContainer cookieContainer;
  17. private HttpClientHandler clientHandler;
  18. private HttpClient client;
  19. private CentralServer server;
  20. public CentralServer Central
  21. {
  22. get
  23. {
  24. return this.server;
  25. }
  26. set
  27. {
  28. this.server = value;
  29. WriteCentralConfig();
  30. UpdateRequestHeaders();
  31. }
  32. }
  33. public static CentralAPI Instance
  34. {
  35. get
  36. {
  37. if (instance == null)
  38. {
  39. lock (syncRoot)
  40. {
  41. if (instance == null)
  42. {
  43. instance = new CentralAPI();
  44. }
  45. }
  46. }
  47. return instance;
  48. }
  49. }
  50. private CentralAPI()
  51. {
  52. #if DEBUG
  53. ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
  54. #endif
  55. cookieContainer = new CookieContainer();
  56. clientHandler = new HttpClientHandler
  57. {
  58. AllowAutoRedirect = true,
  59. UseCookies = true,
  60. CookieContainer = cookieContainer
  61. };
  62. client = new HttpClient(clientHandler);
  63. string centralConfigPath = CentralConfigFile();
  64. if (File.Exists(centralConfigPath))
  65. {
  66. byte[] tmp = File.ReadAllBytes(centralConfigPath);
  67. string json = Encoding.UTF8.GetString(tmp).Trim();
  68. Central = JsonConvert.DeserializeObject<CentralServer>(json);
  69. }
  70. else
  71. {
  72. Central = new CentralServer();
  73. }
  74. }
  75. public bool HasAccessToken()
  76. {
  77. if (Central == null)
  78. return false;
  79. return !string.IsNullOrEmpty(Central.APIKey);
  80. }
  81. private string ZeroTierDir()
  82. {
  83. return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\ZeroTier\\One";
  84. }
  85. private string CentralConfigFile()
  86. {
  87. return ZeroTierDir() + "\\central.conf";
  88. }
  89. public void WriteCentralConfig()
  90. {
  91. string json = JsonConvert.SerializeObject(Central);
  92. byte[] tmp = Encoding.UTF8.GetBytes(json);
  93. File.WriteAllBytes(CentralConfigFile(), tmp);
  94. }
  95. private void UpdateRequestHeaders()
  96. {
  97. if (client.DefaultRequestHeaders.Contains("Authorization"))
  98. {
  99. client.DefaultRequestHeaders.Remove("Authorization");
  100. }
  101. if (!string.IsNullOrEmpty(Central.APIKey))
  102. {
  103. client.DefaultRequestHeaders.Add("Authorization", "bearer " + Central.APIKey);
  104. }
  105. }
  106. public async Task<bool> Login(string email, string password, bool isNewUser)
  107. {
  108. string postURL = Central.ServerURL + "/api/_auth/local";
  109. CentralLogin login = new CentralLogin(email, password, isNewUser);
  110. var content = new StringContent(JsonConvert.SerializeObject(login), Encoding.UTF8, "application/json");
  111. HttpResponseMessage response = await client.PostAsync(postURL, content);
  112. if (!response.IsSuccessStatusCode)
  113. {
  114. return false;
  115. }
  116. string resContent = await response.Content.ReadAsStringAsync();
  117. CentralUser user = JsonConvert.DeserializeObject<CentralUser>(resContent);
  118. if (user.Tokens.Count == 0)
  119. {
  120. // create token
  121. user = await CreateAuthToken(user);
  122. }
  123. Central.APIKey = user.Tokens[0];
  124. UpdateRequestHeaders();
  125. WriteCentralConfig();
  126. return true;
  127. }
  128. public async Task<CentralUser> CreateAuthToken(CentralUser user)
  129. {
  130. string randomTokenURL = Central.ServerURL + "/api/randomToken";
  131. HttpResponseMessage response = await client.GetAsync(randomTokenURL);
  132. if (!response.IsSuccessStatusCode)
  133. {
  134. // TODO: throw an error
  135. return null;
  136. }
  137. string resContent = await response.Content.ReadAsStringAsync();
  138. CentralToken t = JsonConvert.DeserializeObject<CentralToken>(resContent);
  139. user.Tokens.Add(t.Token);
  140. string tokenObj = "{ \"tokens\": " + JsonConvert.SerializeObject(user.Tokens) + " } ";
  141. string postURL = Central.ServerURL + "/api/user/" + user.Id;
  142. var postContent = new StringContent(tokenObj, Encoding.UTF8, "application/json");
  143. response = await client.PostAsync(postURL, postContent);
  144. if (!response.IsSuccessStatusCode)
  145. {
  146. // TODO: thrown an error
  147. return null;
  148. }
  149. resContent = await response.Content.ReadAsStringAsync();
  150. user = JsonConvert.DeserializeObject<CentralUser>(resContent);
  151. return user;
  152. }
  153. public async Task<List<CentralNetwork>> GetNetworkList()
  154. {
  155. string networkURL = Central.ServerURL + "/api/network";
  156. HttpResponseMessage response = await client.GetAsync(networkURL);
  157. if (!response.IsSuccessStatusCode)
  158. {
  159. // TODO: Throw Error
  160. return new List<CentralNetwork>();
  161. }
  162. string resContent = await response.Content.ReadAsStringAsync();
  163. List<CentralNetwork> networkList = JsonConvert.DeserializeObject<List<CentralNetwork>>(resContent);
  164. return networkList;
  165. }
  166. public async Task<CentralNetwork> CreateNewNetwork()
  167. {
  168. string networkURL = Central.ServerURL + "/api/network?easy=1";
  169. CentralNetwork network = new CentralNetwork();
  170. network.Config = new CentralNetwork.CentralNetworkConfig();
  171. network.Config.Name = NetworkNameGenerator.GenerateName();
  172. string jsonNetwork = JsonConvert.SerializeObject(network);
  173. var postContent = new StringContent(jsonNetwork, Encoding.UTF8, "application/json");
  174. HttpResponseMessage response = await client.PostAsync(networkURL, postContent);
  175. if (!response.IsSuccessStatusCode)
  176. {
  177. return null;
  178. }
  179. string resContent = await response.Content.ReadAsStringAsync();
  180. CentralNetwork newNetwork = JsonConvert.DeserializeObject<CentralNetwork>(resContent);
  181. return newNetwork;
  182. }
  183. public async Task<bool> AuthorizeNode(string nodeAddress, string networkId)
  184. {
  185. string json = "{ \"config\": { \"authorized\": true } }";
  186. string postURL = Central.ServerURL + "/api/network/" + networkId + "/member/" + nodeAddress;
  187. var postContent = new StringContent(json, Encoding.UTF8, "application/json");
  188. HttpResponseMessage response = await client.PostAsync(postURL, postContent);
  189. if (response.IsSuccessStatusCode)
  190. {
  191. return true;
  192. }
  193. return false;
  194. }
  195. }
  196. }