The next generation of the Teknik Services. Written in ASP.NET. https://www.teknik.io/
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.

IdentityHelper.cs 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. using IdentityModel.Client;
  2. using IdentityServer4.Models;
  3. using Newtonsoft.Json;
  4. using Newtonsoft.Json.Linq;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Net.Http;
  9. using System.Threading.Tasks;
  10. using Teknik.Areas.Users.Models;
  11. using Teknik.Configuration;
  12. using Teknik.Utilities;
  13. namespace Teknik.Areas.Users.Utility
  14. {
  15. public static class IdentityHelper
  16. {
  17. public static async Task<string> GetAccessToken(Config config)
  18. {
  19. return await GetAccessToken(config.UserConfig.IdentityServerConfig.Authority, config.UserConfig.IdentityServerConfig.ClientId, config.UserConfig.IdentityServerConfig.ClientSecret, "auth-api");
  20. }
  21. public static async Task<string> GetAccessToken(string authority, string clientId, string secret, string scope)
  22. {
  23. var disco = await DiscoveryClient.GetAsync(authority);
  24. if (disco.IsError) throw new Exception(disco.Error);
  25. var tokenClient = new TokenClient(disco.TokenEndpoint, clientId, secret);
  26. var tokenResponse = await tokenClient.RequestClientCredentialsAsync(scope);
  27. if (tokenResponse.IsError) throw new Exception(tokenResponse.Error);
  28. return tokenResponse.AccessToken;
  29. }
  30. public static Uri CreateUrl(Config config, string path)
  31. {
  32. var authUrl = new Uri(config.UserConfig.IdentityServerConfig.Authority);
  33. return new Uri(authUrl, path);
  34. }
  35. public static async Task<IdentityResult> Get(Config config, Uri url)
  36. {
  37. var client = new HttpClient();
  38. client.SetBearerToken(await GetAccessToken(config));
  39. var content = await client.GetStringAsync(url);
  40. if (!string.IsNullOrEmpty(content))
  41. {
  42. return JsonConvert.DeserializeObject<IdentityResult>(content);
  43. }
  44. return new IdentityResult() { Success = false, Message = "No Data Received" };
  45. }
  46. public static async Task<IdentityResult> Post(Config config, Uri url, object data)
  47. {
  48. var client = new HttpClient();
  49. client.SetBearerToken(await GetAccessToken(config));
  50. var response = await client.PostAsJsonAsync(url, data);
  51. if (response.IsSuccessStatusCode)
  52. {
  53. string content = await response.Content.ReadAsStringAsync();
  54. if (!string.IsNullOrEmpty(content))
  55. {
  56. return JsonConvert.DeserializeObject<IdentityResult>(content);
  57. }
  58. return new IdentityResult() { Success = false, Message = "No Data Received" };
  59. }
  60. return new IdentityResult() { Success = false, Message = "HTTP Error: " + response.StatusCode + " | " + (await response.Content.ReadAsStringAsync()) };
  61. }
  62. // API Functions
  63. public static async Task<IdentityResult> CreateUser(Config config, string username, string password, string recoveryEmail)
  64. {
  65. var manageUrl = CreateUrl(config, $"Manage/CreateUser");
  66. var response = await Post(config, manageUrl,
  67. new
  68. {
  69. username = username,
  70. password = password,
  71. recoveryEmail = recoveryEmail
  72. });
  73. return response;
  74. }
  75. public static async Task<bool> DeleteUser(Config config, string username)
  76. {
  77. var manageUrl = CreateUrl(config, $"Manage/DeleteUser");
  78. var response = await Post(config, manageUrl,
  79. new
  80. {
  81. username = username
  82. });
  83. return response.Success;
  84. }
  85. public static async Task<bool> UserExists(Config config, string username)
  86. {
  87. var manageUrl = CreateUrl(config, $"Manage/UserExists?username={username}");
  88. var result = await Get(config, manageUrl);
  89. if (result.Success)
  90. {
  91. return (bool)result.Data;
  92. }
  93. throw new Exception(result.Message);
  94. }
  95. public static async Task<IdentityUserInfo> GetIdentityUserInfo(Config config, string username)
  96. {
  97. var manageUrl = CreateUrl(config, $"Manage/GetUserInfo?username={username}");
  98. var result = await Get(config, manageUrl);
  99. if (result.Success)
  100. {
  101. return new IdentityUserInfo((JObject)result.Data);
  102. }
  103. throw new Exception(result.Message);
  104. }
  105. public static async Task<bool> CheckPassword(Config config, string username, string password)
  106. {
  107. var manageUrl = CreateUrl(config, $"Manage/CheckPassword");
  108. var response = await Post(config, manageUrl,
  109. new
  110. {
  111. username = username,
  112. password = password
  113. });
  114. if (response.Success)
  115. {
  116. return (bool)response.Data;
  117. }
  118. return false;
  119. }
  120. public static async Task<string> GeneratePasswordResetToken(Config config, string username)
  121. {
  122. var manageUrl = CreateUrl(config, $"Manage/GeneratePasswordResetToken");
  123. var response = await Post(config, manageUrl,
  124. new
  125. {
  126. username = username
  127. });
  128. if (response.Success)
  129. {
  130. return (string)response.Data;
  131. }
  132. throw new Exception(response.Message);
  133. }
  134. public static async Task<IdentityResult> ResetPassword(Config config, string username, string token, string newPassword)
  135. {
  136. var manageUrl = CreateUrl(config, $"Manage/ResetPassword");
  137. var response = await Post(config, manageUrl,
  138. new
  139. {
  140. username = username,
  141. token = token,
  142. password = newPassword
  143. });
  144. return response;
  145. }
  146. public static async Task<IdentityResult> UpdatePassword(Config config, string username, string currentPassword, string newPassword)
  147. {
  148. var manageUrl = CreateUrl(config, $"Manage/UpdatePassword");
  149. var response = await Post(config, manageUrl,
  150. new
  151. {
  152. username = username,
  153. currentPassword = currentPassword,
  154. newPassword = newPassword
  155. });
  156. return response;
  157. }
  158. public static async Task<string> UpdateRecoveryEmail(Config config, string username, string email)
  159. {
  160. var manageUrl = CreateUrl(config, $"Manage/UpdateEmail");
  161. var response = await Post(config, manageUrl,
  162. new
  163. {
  164. username = username,
  165. email = email
  166. });
  167. if (response.Success)
  168. {
  169. return (string)response.Data;
  170. }
  171. throw new Exception(response.Message);
  172. }
  173. public static async Task<IdentityResult> VerifyRecoveryEmail(Config config, string username, string token)
  174. {
  175. var manageUrl = CreateUrl(config, $"Manage/VerifyEmail");
  176. var response = await Post(config, manageUrl,
  177. new
  178. {
  179. username = username,
  180. token = token
  181. });
  182. return response;
  183. }
  184. public static async Task<IdentityResult> UpdateAccountStatus(Config config, string username, AccountStatus accountStatus)
  185. {
  186. var manageUrl = CreateUrl(config, $"Manage/UpdateAccountStatus");
  187. var response = await Post(config, manageUrl,
  188. new
  189. {
  190. username = username,
  191. accountStatus = accountStatus
  192. });
  193. return response;
  194. }
  195. public static async Task<IdentityResult> UpdateAccountType(Config config, string username, AccountType accountType)
  196. {
  197. var manageUrl = CreateUrl(config, $"Manage/UpdateAccountType");
  198. var response = await Post(config, manageUrl,
  199. new
  200. {
  201. username = username,
  202. accountType = accountType
  203. });
  204. return response;
  205. }
  206. public static async Task<IdentityResult> UpdatePGPPublicKey(Config config, string username, string publicKey)
  207. {
  208. var manageUrl = CreateUrl(config, $"Manage/UpdatePGPPublicKey");
  209. var response = await Post(config, manageUrl,
  210. new
  211. {
  212. username = username,
  213. pgpPublicKey = publicKey
  214. });
  215. return response;
  216. }
  217. public static async Task<string> Get2FAKey(Config config, string username)
  218. {
  219. var manageUrl = CreateUrl(config, $"Manage/Get2FAKey?username={username}");
  220. var result = await Get(config, manageUrl);
  221. if (result.Success)
  222. {
  223. return (string)result.Data;
  224. }
  225. throw new Exception(result.Message);
  226. }
  227. public static async Task<string> Reset2FAKey(Config config, string username)
  228. {
  229. var manageUrl = CreateUrl(config, $"Manage/Reset2FAKey");
  230. var response = await Post(config, manageUrl,
  231. new
  232. {
  233. username = username
  234. });
  235. if (response.Success)
  236. {
  237. return (string)response.Data;
  238. }
  239. throw new Exception(response.Message);
  240. }
  241. public static async Task<string[]> Enable2FA(Config config, string username, string code)
  242. {
  243. var manageUrl = CreateUrl(config, $"Manage/Enable2FA");
  244. var response = await Post(config, manageUrl,
  245. new
  246. {
  247. username = username,
  248. code = code
  249. });
  250. if (response.Success)
  251. {
  252. return ((JArray)response.Data).ToObject<string[]>();
  253. }
  254. throw new Exception(response.Message);
  255. }
  256. public static async Task<IdentityResult> Disable2FA(Config config, string username)
  257. {
  258. var manageUrl = CreateUrl(config, $"Manage/Disable2FA");
  259. var response = await Post(config, manageUrl,
  260. new
  261. {
  262. username = username
  263. });
  264. return response;
  265. }
  266. public static async Task<string[]> GenerateRecoveryCodes(Config config, string username)
  267. {
  268. var manageUrl = CreateUrl(config, $"Manage/GenerateRecoveryCodes");
  269. var response = await Post(config, manageUrl,
  270. new
  271. {
  272. username = username
  273. });
  274. if (response.Success)
  275. {
  276. return ((JArray)response.Data).ToObject<string[]>();
  277. }
  278. throw new Exception(response.Message);
  279. }
  280. public static async Task<Client> GetClient(Config config, string username, string clientId)
  281. {
  282. var manageUrl = CreateUrl(config, $"Manage/GetClient?username={username}&clientId={clientId}");
  283. var result = await Get(config, manageUrl);
  284. if (result.Success)
  285. {
  286. return ((JObject)result.Data).ToObject<Client>();
  287. }
  288. throw new Exception(result.Message);
  289. }
  290. public static async Task<Client[]> GetClients(Config config, string username)
  291. {
  292. var manageUrl = CreateUrl(config, $"Manage/GetClients?username={username}");
  293. var result = await Get(config, manageUrl);
  294. if (result.Success)
  295. {
  296. return ((JArray)result.Data).ToObject<Client[]>();
  297. }
  298. throw new Exception(result.Message);
  299. }
  300. public static async Task<IdentityResult> CreateClient(Config config, string username, string name, string homepageUrl, string logoUrl, string callbackUrl, params string[] allowedScopes)
  301. {
  302. var manageUrl = CreateUrl(config, $"Manage/CreateClient");
  303. var response = await Post(config, manageUrl,
  304. new
  305. {
  306. username = username,
  307. name = name,
  308. homepageUrl = homepageUrl,
  309. logoUrl = logoUrl,
  310. callbackUrl = callbackUrl,
  311. allowedScopes = allowedScopes
  312. });
  313. return response;
  314. }
  315. public static async Task<IdentityResult> EditClient(Config config, string username, string clientId, string name, string homepageUrl, string logoUrl, string callbackUrl)
  316. {
  317. var manageUrl = CreateUrl(config, $"Manage/EditClient");
  318. var response = await Post(config, manageUrl,
  319. new
  320. {
  321. username = username,
  322. clientId = clientId,
  323. name = name,
  324. homepageUrl = homepageUrl,
  325. logoUrl = logoUrl,
  326. callbackUrl = callbackUrl
  327. });
  328. return response;
  329. }
  330. public static async Task<IdentityResult> DeleteClient(Config config, string clientId)
  331. {
  332. var manageUrl = CreateUrl(config, $"Manage/DeleteClient");
  333. var response = await Post(config, manageUrl,
  334. new
  335. {
  336. clientId = clientId
  337. });
  338. return response;
  339. }
  340. }
  341. }