CentralAPI.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. CentralServer ctmp = JsonConvert.DeserializeObject<CentralServer>(json);
  69. if (ctmp != null)
  70. {
  71. Central = ctmp;
  72. }
  73. else
  74. {
  75. Central = new CentralServer();
  76. }
  77. }
  78. else
  79. {
  80. Central = new CentralServer();
  81. }
  82. }
  83. public bool HasAccessToken()
  84. {
  85. if (Central == null)
  86. return false;
  87. return !string.IsNullOrEmpty(Central.APIKey);
  88. }
  89. private string ZeroTierDir()
  90. {
  91. return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\ZeroTier\\One";
  92. }
  93. private string CentralConfigFile()
  94. {
  95. return ZeroTierDir() + "\\central.conf";
  96. }
  97. public void WriteCentralConfig()
  98. {
  99. string json = JsonConvert.SerializeObject(Central);
  100. byte[] tmp = Encoding.UTF8.GetBytes(json);
  101. if (tmp != null)
  102. {
  103. File.WriteAllBytes(CentralConfigFile(), tmp);
  104. }
  105. }
  106. private void UpdateRequestHeaders()
  107. {
  108. if (client.DefaultRequestHeaders.Contains("Authorization"))
  109. {
  110. client.DefaultRequestHeaders.Remove("Authorization");
  111. }
  112. if (!string.IsNullOrEmpty(Central.APIKey))
  113. {
  114. client.DefaultRequestHeaders.Add("Authorization", "bearer " + Central.APIKey);
  115. }
  116. }
  117. public async Task<bool> Login(string email, string password, bool isNewUser)
  118. {
  119. string postURL = Central.ServerURL + "/api/_auth/local";
  120. CentralLogin login = new CentralLogin(email, password, isNewUser);
  121. var content = new StringContent(JsonConvert.SerializeObject(login), Encoding.UTF8, "application/json");
  122. HttpResponseMessage response = await client.PostAsync(postURL, content);
  123. if (!response.IsSuccessStatusCode)
  124. {
  125. return false;
  126. }
  127. string resContent = await response.Content.ReadAsStringAsync();
  128. CentralUser user = JsonConvert.DeserializeObject<CentralUser>(resContent);
  129. if (user.Tokens.Count == 0)
  130. {
  131. // create token
  132. user = await CreateAuthToken(user);
  133. }
  134. Central.APIKey = user.Tokens[0];
  135. UpdateRequestHeaders();
  136. WriteCentralConfig();
  137. return true;
  138. }
  139. public async Task<CentralUser> CreateAuthToken(CentralUser user)
  140. {
  141. string randomTokenURL = Central.ServerURL + "/api/randomToken";
  142. HttpResponseMessage response = await client.GetAsync(randomTokenURL);
  143. if (!response.IsSuccessStatusCode)
  144. {
  145. // TODO: throw an error
  146. return null;
  147. }
  148. string resContent = await response.Content.ReadAsStringAsync();
  149. CentralToken t = JsonConvert.DeserializeObject<CentralToken>(resContent);
  150. user.Tokens.Add(t.Token);
  151. string tokenObj = "{ \"tokens\": " + JsonConvert.SerializeObject(user.Tokens) + " } ";
  152. string postURL = Central.ServerURL + "/api/user/" + user.Id;
  153. var postContent = new StringContent(tokenObj, Encoding.UTF8, "application/json");
  154. response = await client.PostAsync(postURL, postContent);
  155. if (!response.IsSuccessStatusCode)
  156. {
  157. // TODO: thrown an error
  158. return null;
  159. }
  160. resContent = await response.Content.ReadAsStringAsync();
  161. user = JsonConvert.DeserializeObject<CentralUser>(resContent);
  162. return user;
  163. }
  164. public async Task<List<CentralNetwork>> GetNetworkList()
  165. {
  166. string networkURL = Central.ServerURL + "/api/network";
  167. HttpResponseMessage response = await client.GetAsync(networkURL);
  168. if (!response.IsSuccessStatusCode)
  169. {
  170. // TODO: Throw Error
  171. return new List<CentralNetwork>();
  172. }
  173. string resContent = await response.Content.ReadAsStringAsync();
  174. List<CentralNetwork> networkList = JsonConvert.DeserializeObject<List<CentralNetwork>>(resContent);
  175. return networkList;
  176. }
  177. public async Task<CentralNetwork> CreateNewNetwork()
  178. {
  179. string networkURL = Central.ServerURL + "/api/network?easy=1";
  180. CentralNetwork network = new CentralNetwork();
  181. network.Config = new CentralNetwork.CentralNetworkConfig();
  182. network.Config.Name = NetworkNameGenerator.GenerateName();
  183. string jsonNetwork = JsonConvert.SerializeObject(network);
  184. var postContent = new StringContent(jsonNetwork, Encoding.UTF8, "application/json");
  185. HttpResponseMessage response = await client.PostAsync(networkURL, postContent);
  186. if (!response.IsSuccessStatusCode)
  187. {
  188. return null;
  189. }
  190. string resContent = await response.Content.ReadAsStringAsync();
  191. CentralNetwork newNetwork = JsonConvert.DeserializeObject<CentralNetwork>(resContent);
  192. return newNetwork;
  193. }
  194. public async Task<bool> AuthorizeNode(string nodeAddress, string networkId)
  195. {
  196. string json = "{ \"config\": { \"authorized\": true } }";
  197. string postURL = Central.ServerURL + "/api/network/" + networkId + "/member/" + nodeAddress;
  198. var postContent = new StringContent(json, Encoding.UTF8, "application/json");
  199. HttpResponseMessage response = await client.PostAsync(postURL, postContent);
  200. if (response.IsSuccessStatusCode)
  201. {
  202. return true;
  203. }
  204. return false;
  205. }
  206. }
  207. }