Advertisement
Guest User

Untitled

a guest
Mar 20th, 2019
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.50 KB | None | 0 0
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // OptiMargin
  3. // Copyright(c) 2017-2018, Ulysses Commodities
  4. //---------------------------------------------------------------------------//
  5. // Simple auto updater for OptiMargin.
  6. //
  7. // ----------------
  8. // Author : Dmitry «Vortex» Koteroff
  9. // E-mail : krakean@outlook.com
  10. // Skype : internat1onale
  11. // Telegram : @Krakean
  12. // Slack : Dmitry Koteroff
  13. //---------------------------------------------------------------------------//
  14. // Date Ver Who Comment //
  15. // -------- --- --- ------- //
  16. // 17.12.18 1.0 VtX Created
  17. // 05.01.19 2.0 VtX Rewritten
  18. ///////////////////////////////////////////////////////////////////////////////
  19.  
  20. using Newtonsoft.Json;
  21. using Newtonsoft.Json.Linq;
  22. using RestSharp;
  23. using Switch.Cmd.Shared;
  24. using Switch.Cmd.Shared.Components;
  25. using System;
  26. using System.IO;
  27. using System.Linq;
  28. using System.Net;
  29. using System.Security.Cryptography;
  30. using tar_cs;
  31.  
  32. namespace SwitchCmd.Updater
  33. {
  34. class Program
  35. {
  36. /// <summary>
  37. /// Entry point.
  38. /// </summary>
  39. /// <param name="args">Arguments list, see remarks for details</param>
  40. /// <remarks>
  41. /// Arguments list is following:
  42. /// -n to create new update package.
  43. /// -f to specify that this update is mandatory and its better to update.
  44. /// It is decision on frontend side what to do with this info when reported after -c.
  45. /// -c to check whether new version is available.
  46. /// -u perform the update to new version. should be called only after -c.
  47. ///
  48. /// All of them above also expect: --clientid integer and --clientsecret "string"
  49. /// </remarks>
  50. static void Main(string[] args)
  51. {
  52. var input = String.Join(" ", args);
  53. var arg = Arguments.Parse(input).ArgumentDictionary;
  54. bool fail = false;
  55.  
  56. if (arg == null)
  57. fail = true;
  58. // Mandatory args
  59. else if (!arg.ContainsKey("clientid") || !arg.ContainsKey("clientsecret"))
  60. fail = true;
  61.  
  62. VersionInfo.Initialize();
  63.  
  64. // Before we proceed, lets check whether this client is can receive updates at all
  65. if (!fail && !IsClientActive(arg["clientid"].ToString(), arg["clientsecret"].ToString()))
  66. {
  67. Console.WriteLine("Error: client inactive");
  68. return;
  69. }
  70.  
  71. if (!fail && arg.ContainsKey("c"))
  72. ProceedCheckUpdate(arg["clientid"].ToString(), arg["clientsecret"].ToString());
  73. else
  74. fail = true;
  75.  
  76. if (fail)
  77. Console.WriteLine("Error: wrong arguments");
  78. }
  79.  
  80. /// <summary>
  81. /// Perform REST request to Optimargin API.
  82. /// </summary>
  83. /// <param name="clientid">Client's ID</param>
  84. /// <param name="clientsecret">Client's secret</param>
  85. /// <param name="query">Either update_check or client_check</param>
  86. static JObject PerformRequest(string clientid, string clientsecret, string query)
  87. {
  88. // Base URL for REST client.
  89. var client = new RestClient($"https://api.optimargin.com");
  90. client.Timeout = 3000;
  91.  
  92. // Compose request URL
  93. var request = new RestRequest("{clientid}/{clientsecret}/{query}", Method.GET);
  94. request.Timeout = 3000;
  95. request.AddUrlSegment("clientid", clientid);
  96. request.AddUrlSegment("clientsecret", clientsecret);
  97. request.AddUrlSegment("query", query);
  98.  
  99. // Execute request and get response.
  100. IRestResponse response = client.Execute(request);
  101. var jsoncontent = response.Content;
  102.  
  103. // Json can be empty either due to server error, connection timeout,
  104. // or any other possible issue. Anyway, just show simple error
  105. // that indicates something went wrong.
  106. if (jsoncontent == String.Empty)
  107. {
  108. Console.WriteLine("Error: cannot get data");
  109. return null;
  110. }
  111.  
  112. JsonTextReader reader = new JsonTextReader(new StringReader(jsoncontent));
  113. JObject obj = (JObject) JToken.ReadFrom(reader);
  114.  
  115. // This also can be possible due to issue with parsing json.
  116. if (obj == null)
  117. {
  118. Console.WriteLine("Error: malformed json");
  119. return null;
  120. }
  121.  
  122. // For example, if given client is not found.
  123. if (obj.ContainsKey("error"))
  124. {
  125. Console.WriteLine("Error: " + obj["error"]);
  126. return null;
  127. }
  128.  
  129. return obj;
  130. }
  131.  
  132. /// <summary>
  133. /// Checks whether this client is active and allowed to receive updates
  134. /// </summary>
  135. /// <param name="clientid"></param>
  136. /// <param name="clientsecret"></param>
  137. /// <returns></returns>
  138. static bool IsClientActive(string clientid, string clientsecret)
  139. {
  140. var obj = PerformRequest(clientid, clientsecret, "client_check");
  141.  
  142. if (obj == null)
  143. return false;
  144.  
  145. if (!obj.ContainsKey("user"))
  146. {
  147. // Seems like server-side issue.
  148. Console.WriteLine("Error: malformed client json");
  149. return false;
  150. }
  151.  
  152. JToken user = obj["user"];
  153.  
  154. return (bool)user["active"];
  155. }
  156.  
  157. /// <summary>
  158. /// Perform check for updates availablity, and if update is available, perform the update.
  159. /// </summary>
  160. /// <param name="clientid">client's id</param>
  161. /// <param name="clientsecret">client's secret</param>
  162. static async void ProceedCheckUpdate(string clientid, string clientsecret)
  163. {
  164. var obj = PerformRequest(clientid, clientsecret, "update_check");
  165.  
  166. if (obj == null)
  167. return;
  168.  
  169. if (!obj.ContainsKey("updates"))
  170. {
  171. // Seems like server-side issue
  172. Console.WriteLine("Error: malformed updates json");
  173. return;
  174. }
  175.  
  176. if (obj.ContainsKey("error"))
  177. {
  178. // For example, "Your account is disabled".
  179. Console.WriteLine("Error: " + obj["error"]);
  180. return;
  181. }
  182.  
  183. JArray updates = (JArray) obj["updates"];
  184. if (!updates.Any())
  185. {
  186. // Though, its not really correct.
  187. // It means that updates array is empty, which can be possible issue on server side.
  188. // But for client, in result, its just no updates after all.
  189. Console.WriteLine("No update available");
  190. return;
  191. }
  192.  
  193. // We have only last update in array.
  194. JToken update = updates[0];
  195.  
  196. // Get the version tag and compare it with current running version
  197. string tag = (string)update["tagname"];
  198. tag = tag.Replace("v", "");
  199. tag = tag.Replace(".", "");
  200. // Running version
  201. int verRun = Int32.Parse(VersionInfo.Format("{MAJOR}{MINOR}{PATCH}"));
  202. // Version from update.
  203. int verUpd = Int32.Parse(tag);
  204.  
  205. if (verUpd > verRun)
  206. Console.WriteLine("Update available: " + (string)update["tagname"]);
  207. else
  208. {
  209. Console.WriteLine("No update available");
  210. return;
  211. }
  212.  
  213. Console.WriteLine("Downloading update...");
  214. var update_archive = Path.Combine(Utils.GetStoreFolder(), "update.tar");
  215. using (var webcl = new WebClient())
  216. {
  217. webcl.DownloadFile((string)update["fileurl"], update_archive);
  218. }
  219.  
  220. if (!File.Exists(update_archive))
  221. {
  222. Console.WriteLine("Error: update archive is not exists");
  223. return;
  224. }
  225.  
  226. Console.WriteLine("Done. Check md5...");
  227. using (var md5 = MD5.Create())
  228. {
  229. using (var stream = File.OpenRead(update_archive))
  230. {
  231. var hash = md5.ComputeHash(stream);
  232. string updMd5 = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
  233.  
  234. if (updMd5 != (string) update["filemd5"])
  235. {
  236. Console.WriteLine("Error: md5 hash mismatch");
  237. return;
  238. }
  239. }
  240. }
  241.  
  242. Console.WriteLine("Done. Extracting update...");
  243. var updDestFolder = Path.Combine(Utils.GetStoreFolder(), "Update", (string) update["tagname"]);
  244. using (var archTar = File.OpenRead(update_archive))
  245. {
  246. TarReader reader = new TarReader(archTar);
  247.  
  248. await reader.ReadToEndAsync(updDestFolder);
  249. }
  250.  
  251. Console.WriteLine("Done. Removing update.tar...");
  252. File.Delete(update_archive);
  253.  
  254. Console.WriteLine("Done. Update location: " + updDestFolder);
  255. Console.WriteLine("Updater closing now...");
  256. }
  257. }
  258. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement