You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

331 lines
12 KiB

1 year ago
1 year ago
  1. using CircleSDK.Api;
  2. using CircleSDK.Model;
  3. using System.Diagnostics;
  4. using System.Net.WebSockets;
  5. using System.Net;
  6. using System.Security.Cryptography;
  7. using System.Text;
  8. using Newtonsoft.Json;
  9. namespace CDPShared
  10. {
  11. public class CircleAPIHelper
  12. {
  13. private string _customerCode;
  14. private string _appKey;
  15. private string _endUserId;
  16. private string _secret;
  17. private ClientWebSocket _socket;
  18. private CancellationTokenSource _cts;
  19. private string _token; // this needs to be kept up to date
  20. public string Token => _token;
  21. private Timer _refreshToken;
  22. private CircleApi _api;
  23. public CircleApi Api => _api;
  24. private Boolean _authorized = false;
  25. public Boolean Ready => _authorized;
  26. public string Status { get; set; }
  27. public CircleAPIHelper(string customerCode, string appKey, string endUserId, string secret)
  28. {
  29. _api = new CircleApi(); // to use CircleAPI, you need RESTSharp v106.15.0
  30. _customerCode = customerCode;
  31. _appKey = appKey;
  32. _endUserId = endUserId;
  33. _secret = secret;
  34. _refreshToken = new Timer(RefreshToken, null, 100, 5 * 1000); // check every 30 seconds
  35. Status = "Starting up";
  36. }
  37. private void RefreshToken(object state)
  38. {
  39. Status = "Looking for Circle Service";
  40. Boolean bCircleServiceExists = Process.GetProcesses().Any(dr => (dr.ProcessName.ToLower() == "CircleServiceDebug".ToLower()) || (dr.ProcessName.ToLower() == "CircleService".ToLower()));
  41. if (bCircleServiceExists)
  42. {
  43. // we found the service, switch to refresh every 9 minutes.
  44. _refreshToken.Change(9 * 60 * 1000, 9 * 60 * 1000);
  45. GetToken();
  46. Authorize();
  47. }
  48. }
  49. void GetToken()
  50. {
  51. Status = "Getting permission to call Circle Service.";
  52. string nonce = Guid.NewGuid().ToString();
  53. string query = string.Format($"customerId={_customerCode}&AppKey={_appKey}&EndUserId={_endUserId}&nonce={nonce}");
  54. string signature = ComputeSignature(query, _secret);
  55. string fullLine = query + "&signature=" + signature;
  56. WebClient wc = new WebClient();
  57. try
  58. {
  59. string s = wc.DownloadString("https://api.gocircle.ai/api/token?" + fullLine);
  60. s = s.Replace("\\\"", "\"").Trim('\"');
  61. PrettyJWT pt = JsonConvert.DeserializeObject<PrettyJWT>(s);
  62. _token = pt.Token;
  63. }
  64. catch (Exception e)
  65. {
  66. Status = "Unable to get token.";
  67. }
  68. }
  69. string ComputeSignature(string stringToSign, string secret)
  70. {
  71. using (var hmacsha256 = new HMACSHA256(System.Text.ASCIIEncoding.UTF8.GetBytes(secret)))
  72. {
  73. var bytes = Encoding.ASCII.GetBytes(stringToSign);
  74. var hashedBytes = hmacsha256.ComputeHash(bytes);
  75. return Convert.ToBase64String(hashedBytes);
  76. }
  77. }
  78. private void Authorize()
  79. {
  80. Status = "Asking Circle Service for authorization";
  81. var body = new AppAuthorizationRequest(); // AppAuthorizationRequest |
  82. body.Token = _token;
  83. _api.Configuration.AccessToken = _token;
  84. var xCircleAppkey = "Dashboard"; // String | Application `AppKey`
  85. try
  86. {
  87. // authorize
  88. AppAuthorizationReply result = _api.Authorize(body, xCircleAppkey);
  89. _authorized = true;
  90. Debug.WriteLine(result);
  91. Status = "Authorized to use Circle Service";
  92. }
  93. catch (Exception ex)
  94. {
  95. Debug.Print("Exception when calling CircleApi.authorize: " + ex.Message);
  96. _authorized = false;
  97. return;
  98. }
  99. }
  100. public async Task<WhoAmIReply> WhoAmI(string circleId)
  101. {
  102. WhoAmIRequest body = new WhoAmIRequest();
  103. body.CircleId = circleId;
  104. WhoAmIReply result = await _api.WhoAmIAsync(body, "Bearer " + Token, "Dashboard");
  105. if (result.Status.Result.GetValueOrDefault(false))
  106. {
  107. return result;
  108. }
  109. return null;
  110. }
  111. public async Task<CreateCircleReply> CreateCircle(string name, string description)
  112. {
  113. CreateCircleRequest body = new CreateCircleRequest();
  114. body.CircleName = name;
  115. body.CircleDescription = description;
  116. body.CustomerId = Constants.CustomerCode;
  117. body.CustomerToken = Constants.AuthCode;
  118. CreateCircleReply result = await _api.CreateCircleAsync(body, "Bearer " + Token, "Dashboard");
  119. if (result.Status.Result.GetValueOrDefault(false))
  120. {
  121. return result;
  122. }
  123. return null;
  124. }
  125. public async Task<GenInviteReply> GenInvite(string circleId)
  126. {
  127. GenInviteRequest body = new GenInviteRequest();
  128. body.CircleId = circleId;
  129. body.IsAddDevice = false;
  130. GenInviteReply result = await _api.GenInviteAsync(body, "Bearer " + Token, "Dashboard");
  131. if (result.Status.Result.GetValueOrDefault(false))
  132. {
  133. return result;
  134. }
  135. return null;
  136. }
  137. public async Task<ProcessInviteReply> ProcessInvite(string inviteCode, string authCode)
  138. {
  139. ProcessInviteRequest body = new ProcessInviteRequest();
  140. body.InviteId = inviteCode;
  141. body.AuthCode = authCode;
  142. body.Wait20Second = true;
  143. ProcessInviteReply result = await _api.ProcessInviteAsync(body, "Bearer " + Token, "Dashboard");
  144. if (result.Status.Result.GetValueOrDefault(false))
  145. {
  146. return result;
  147. }
  148. return null;
  149. }
  150. public async Task<RevokeDeviceReply> RevokeDevice(string circleId, string deviceId)
  151. {
  152. RevokeDeviceRequest body = new RevokeDeviceRequest();
  153. body.CircleId = circleId;
  154. body.DeviceId = deviceId;
  155. RevokeDeviceReply result = await _api.RevokeDeviceAsync(body, "Bearer " + Token, "Dashboard");
  156. if (result.Status.Result.GetValueOrDefault(false))
  157. {
  158. return result;
  159. }
  160. return null;
  161. }
  162. public async Task<RemoveMemberReply> RemoveMember(string circleId, string memberId)
  163. {
  164. RemoveMemberRequest body = new RemoveMemberRequest();
  165. body.CircleId = circleId;
  166. body.MemberId = memberId;
  167. RemoveMemberReply result = await _api.RemoveMemberAsync(body, "Bearer " + Token, "Dashboard");
  168. if (result.Status.Result.GetValueOrDefault(false))
  169. {
  170. return result;
  171. }
  172. return null;
  173. }
  174. public async Task<List<ProfileInfo>> EnumCircleMembers(string circleId)
  175. {
  176. EnumCircleMembersRequest body = new EnumCircleMembersRequest();
  177. body.CircleId = circleId;
  178. EnumCircleMembersReply result = await _api.EnumCircleMembersAsync(body, "Bearer " + Token, "Dashboard");
  179. if (result.Status.Result.GetValueOrDefault(false))
  180. {
  181. return result.Profiles;
  182. }
  183. return null;
  184. }
  185. public async Task<List<ProfileInfo>> EnumTopicMembers(string circleId, string topicId)
  186. {
  187. EnumTopicMembersRequest body = new EnumTopicMembersRequest();
  188. body.CircleId = circleId;
  189. body.TopicId = topicId;
  190. EnumTopicMembersReply result = await _api.EnumTopicMembersAsync(body, "Bearer " + Token, "Dashboard");
  191. if (result.Status.Result.GetValueOrDefault(false))
  192. {
  193. return result.Profiles;
  194. }
  195. return null;
  196. }
  197. public async Task<List<CircleInfo>> EnumCircles()
  198. {
  199. EnumCirclesRequest body = new EnumCirclesRequest();
  200. EnumCirclesReply result = await _api.EnumCirclesAsync(body, "Bearer " + Token, "Dashboard");
  201. if (result.Status.Result.GetValueOrDefault(false))
  202. {
  203. return result.CircleMeta;
  204. }
  205. return null;
  206. }
  207. public async Task<CircleInfo> GetCircleById(string circleId)
  208. {
  209. List<CircleInfo> circles = await EnumCircles();
  210. if (circles == null)
  211. return null;
  212. foreach (CircleInfo info in circles)
  213. {
  214. if (string.Compare(info.CircleId, circleId,
  215. StringComparison.CurrentCultureIgnoreCase) == 0)
  216. {
  217. return info;
  218. }
  219. }
  220. return null;
  221. }
  222. public async Task<List<TopicInfo>> EnumTopics(string circleId)
  223. {
  224. EnumTopicsRequest body = new EnumTopicsRequest();
  225. body.CircleId = circleId;
  226. EnumTopicsReply result = await _api.EnumTopicsAsync(body, "Bearer " + Token, "Dashboard");
  227. if (result.Status.Result.GetValueOrDefault(false))
  228. {
  229. return result.Topics;
  230. }
  231. return null;
  232. }
  233. public async Task<TopicInfo> GetTopicById(string circleId, string topicId)
  234. {
  235. List<TopicInfo> topics = await EnumTopics(circleId);
  236. foreach (TopicInfo info in topics)
  237. {
  238. if (string.Compare(info.TopicId, topicId,
  239. StringComparison.CurrentCultureIgnoreCase) == 0)
  240. {
  241. return info;
  242. }
  243. }
  244. return null;
  245. }
  246. public async Task<byte[]> EncryptFile(string circleId, string topicId, string filename)
  247. {
  248. EncryptRequest body = new EncryptRequest();
  249. body.CircleId = circleId;
  250. body.TopicId = topicId;
  251. body.FileName = filename;
  252. try
  253. {
  254. body.ToEncrypt = Convert.ToBase64String(File.ReadAllBytes(filename));
  255. EncryptReply result = await _api.EncryptAsync(body, "Bearer " + Token, "Dashboard");
  256. if (result.Status.Result.GetValueOrDefault(false))
  257. {
  258. return Convert.FromBase64String(result.EncryptedData);
  259. }
  260. }
  261. catch (Exception e)
  262. {
  263. MinLogging.LogIt(" **** " + e.Message);
  264. }
  265. return null;
  266. }
  267. public async Task<AddMessageReply> AddMessage(string circleId, string topicId, string message, Int32 msgId, DataGather g = null)
  268. {
  269. if (g == null)
  270. g = new DataGather(this);
  271. AddMessageRequest msg = new AddMessageRequest(circleId, topicId, msgId);
  272. msg.Message = message;
  273. msg.AdditionalJson = JsonConvert.SerializeObject(g.Gather());
  274. return await Api.AddMessageAsync(msg, "Bearer " + Token, "Dashboard");
  275. }
  276. public async Task<GetMessagesReply> GetCircleViewwMessages(string circleId, string topicId)
  277. {
  278. GetMessagesRequest gm = new GetMessagesRequest(circleId, topicId)
  279. {
  280. MsgTypeFilters = new List<int?>()
  281. };
  282. for (int i = (Int32)CircleViewMessages.FileViewed; i < (Int32)CircleViewMessages.LastMessage; i++)
  283. {
  284. gm.MsgTypeFilters.Add(i);
  285. }
  286. return await Api.GetMessagesAsync(gm, "Bearer " + Token, "Dashboard");
  287. }
  288. //public async Task<SetProfilePropertyReply> SetProfileProperty(string circleId, string name, string value)
  289. //{
  290. // SetProfilePropertyRequest gm = new SetProfilePropertyRequest(circleId, name, value);
  291. // return await Api.SetProfilePropertyAsync(gm, "Bearer " + Token, "Dashboard");
  292. //}
  293. }
  294. class PrettyJWT
  295. {
  296. public string Token { get; set; }
  297. public DateTime Expiry { get; set; }
  298. }
  299. }