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.

UserController.cs 56KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Teknik.Areas.Users.Models;
  5. using Teknik.Areas.Users.ViewModels;
  6. using Teknik.Controllers;
  7. using Teknik.Utilities;
  8. using Teknik.Areas.Users.Utility;
  9. using Teknik.Filters;
  10. using QRCoder;
  11. using TwoStepsAuthenticator;
  12. using Teknik.Attributes;
  13. using Teknik.Utilities.Cryptography;
  14. using Microsoft.Extensions.Logging;
  15. using Teknik.Configuration;
  16. using Teknik.Data;
  17. using Microsoft.AspNetCore.Authorization;
  18. using Microsoft.AspNetCore.Mvc;
  19. using Microsoft.EntityFrameworkCore;
  20. using System.Net;
  21. using Microsoft.AspNetCore.Mvc.ViewEngines;
  22. using System.Threading.Tasks;
  23. using Teknik.Logging;
  24. using System.Security.Claims;
  25. using Microsoft.AspNetCore.Authentication.Cookies;
  26. using Microsoft.AspNetCore.Authentication;
  27. using IdentityServer4.Services;
  28. using Microsoft.AspNetCore.Identity;
  29. using IdentityModel.Client;
  30. using System.Net.Http;
  31. using Newtonsoft.Json.Linq;
  32. using Teknik.Security;
  33. using Microsoft.IdentityModel.Tokens;
  34. using IdentityModel;
  35. using System.Security.Cryptography;
  36. using System.IdentityModel.Tokens.Jwt;
  37. using Microsoft.AspNetCore.Http;
  38. using IdentityServer4.Models;
  39. namespace Teknik.Areas.Users.Controllers
  40. {
  41. [Authorize]
  42. [Area("User")]
  43. public class UserController : DefaultController
  44. {
  45. private static readonly UsedCodesManager usedCodesManager = new UsedCodesManager();
  46. private const string _AuthSessionKey = "AuthenticatedUser";
  47. private readonly IHttpContextAccessor _httpContextAccessor;
  48. private ISession _session => _httpContextAccessor.HttpContext.Session;
  49. private readonly LogoutSessionManager _logoutSessions;
  50. public UserController(ILogger<Logger> logger, Config config, TeknikEntities dbContext, LogoutSessionManager logoutSessions, IHttpContextAccessor httpContextAccessor) : base(logger, config, dbContext)
  51. {
  52. _logoutSessions = logoutSessions;
  53. _httpContextAccessor = httpContextAccessor;
  54. }
  55. [HttpGet]
  56. public IActionResult Login(string returnUrl)
  57. {
  58. // Let's double check their email and git accounts to make sure they exist
  59. string email = UserHelper.GetUserEmailAddress(_config, User.Identity.Name);
  60. if (_config.EmailConfig.Enabled && !UserHelper.UserEmailExists(_config, email))
  61. {
  62. //UserHelper.AddUserEmail(_config, email, model.Password);
  63. }
  64. if (_config.GitConfig.Enabled && !UserHelper.UserGitExists(_config, User.Identity.Name))
  65. {
  66. //UserHelper.AddUserGit(_config, User.Identity.Name, model.Password);
  67. }
  68. if (!string.IsNullOrEmpty(returnUrl))
  69. {
  70. return Redirect(returnUrl);
  71. }
  72. return Redirect(Url.SubRouteUrl("www", "Home.Index"));
  73. }
  74. [HttpGet]
  75. public async Task Logout()
  76. {
  77. // these are the sub & sid to signout
  78. //var sub = User.FindFirst("sub")?.Value;
  79. //var sid = User.FindFirst("sid")?.Value;
  80. await HttpContext.SignOutAsync("Cookies");
  81. await HttpContext.SignOutAsync("oidc");
  82. //_logoutSessions.Add(sub, sid);
  83. }
  84. [AllowAnonymous]
  85. public IActionResult GetPremium()
  86. {
  87. ViewBag.Title = "Get a Premium Account";
  88. GetPremiumViewModel model = new GetPremiumViewModel();
  89. return View(model);
  90. }
  91. [HttpGet]
  92. [AllowAnonymous]
  93. public IActionResult Register(string inviteCode, string ReturnUrl)
  94. {
  95. RegisterViewModel model = new RegisterViewModel();
  96. model.InviteCode = inviteCode;
  97. model.ReturnUrl = ReturnUrl;
  98. return View("/Areas/User/Views/User/ViewRegistration.cshtml", model);
  99. }
  100. [HttpPost]
  101. [AllowAnonymous]
  102. public async Task<IActionResult> Register([Bind(Prefix = "Register")]RegisterViewModel model)
  103. {
  104. model.Error = false;
  105. model.ErrorMessage = string.Empty;
  106. if (ModelState.IsValid)
  107. {
  108. if (_config.UserConfig.RegistrationEnabled)
  109. {
  110. if (!model.Error && !UserHelper.ValidUsername(_config, model.Username))
  111. {
  112. model.Error = true;
  113. model.ErrorMessage = "That username is not valid";
  114. }
  115. if (!model.Error && !(await UserHelper.UsernameAvailable(_dbContext, _config, model.Username)))
  116. {
  117. model.Error = true;
  118. model.ErrorMessage = "That username is not available";
  119. }
  120. if (!model.Error && model.Password != model.ConfirmPassword)
  121. {
  122. model.Error = true;
  123. model.ErrorMessage = "Passwords must match";
  124. }
  125. // Validate the Invite Code
  126. if (!model.Error && _config.UserConfig.InviteCodeRequired && string.IsNullOrEmpty(model.InviteCode))
  127. {
  128. model.Error = true;
  129. model.ErrorMessage = "An Invite Code is required to register";
  130. }
  131. if (!model.Error && !string.IsNullOrEmpty(model.InviteCode) && _dbContext.InviteCodes.Where(c => c.Code == model.InviteCode && c.Active && c.ClaimedUser == null).FirstOrDefault() == null)
  132. {
  133. model.Error = true;
  134. model.ErrorMessage = "Invalid Invite Code";
  135. }
  136. if (!model.Error)
  137. {
  138. try
  139. {
  140. await UserHelper.CreateAccount(_dbContext, _config, Url, model.Username, model.Password, model.RecoveryEmail, model.InviteCode);
  141. }
  142. catch (Exception ex)
  143. {
  144. model.Error = true;
  145. model.ErrorMessage = ex.GetFullMessage(true);
  146. }
  147. if (!model.Error)
  148. {
  149. // Let's log them in
  150. return GenerateActionResult(new { success = true, redirectUrl = Url.SubRouteUrl("account", "User.Login", new { returnUrl = model.ReturnUrl }) }, Redirect(Url.SubRouteUrl("account", "User.Login", new { returnUrl = model.ReturnUrl })));
  151. }
  152. }
  153. }
  154. if (!model.Error)
  155. {
  156. model.Error = true;
  157. model.ErrorMessage = "User Registration is Disabled";
  158. }
  159. }
  160. else
  161. {
  162. model.Error = true;
  163. model.ErrorMessage = "Missing Required Fields";
  164. }
  165. return GenerateActionResult(new { error = model.ErrorMessage }, View("/Areas/User/Views/User/ViewRegistration.cshtml", model));
  166. }
  167. // GET: Profile/Profile
  168. [AllowAnonymous]
  169. public async Task<IActionResult> ViewProfile(string username)
  170. {
  171. if (string.IsNullOrEmpty(username))
  172. {
  173. username = User.Identity.Name;
  174. }
  175. ProfileViewModel model = new ProfileViewModel();
  176. ViewBag.Title = "User Does Not Exist";
  177. ViewBag.Description = "The User does not exist";
  178. try
  179. {
  180. User user = UserHelper.GetUser(_dbContext, username);
  181. if (user != null)
  182. {
  183. ViewBag.Title = username + "'s Profile";
  184. ViewBag.Description = "Viewing " + username + "'s Profile";
  185. model.UserID = user.UserId;
  186. model.Username = user.Username;
  187. if (_config.EmailConfig.Enabled)
  188. {
  189. model.Email = string.Format("{0}@{1}", user.Username, _config.EmailConfig.Domain);
  190. }
  191. // Get the user claims for this user
  192. model.IdentityUserInfo = await IdentityHelper.GetIdentityUserInfo(_config, user.Username);
  193. model.LastSeen = UserHelper.GetLastAccountActivity(_dbContext, _config, user.Username, model.IdentityUserInfo);
  194. model.UserSettings = user.UserSettings;
  195. model.BlogSettings = user.BlogSettings;
  196. model.UploadSettings = user.UploadSettings;
  197. model.Uploads = _dbContext.Uploads.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DateUploaded).ToList();
  198. model.Pastes = _dbContext.Pastes.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DatePosted).ToList();
  199. model.ShortenedUrls = _dbContext.ShortenedUrls.Where(s => s.UserId == user.UserId).OrderByDescending(s => s.DateAdded).ToList();
  200. model.Vaults = _dbContext.Vaults.Where(v => v.UserId == user.UserId).OrderByDescending(v => v.DateCreated).ToList();
  201. return View(model);
  202. }
  203. model.Error = true;
  204. model.ErrorMessage = "The user does not exist";
  205. }
  206. catch (Exception ex)
  207. {
  208. model.Error = true;
  209. model.ErrorMessage = ex.GetFullMessage(true);
  210. }
  211. return View(model);
  212. }
  213. public IActionResult ViewServiceData()
  214. {
  215. string username = User.Identity.Name;
  216. ViewServiceDataViewModel model = new ViewServiceDataViewModel();
  217. ViewBag.Title = "User Does Not Exist";
  218. ViewBag.Description = "The User does not exist";
  219. try
  220. {
  221. User user = UserHelper.GetUser(_dbContext, username);
  222. if (user != null)
  223. {
  224. ViewBag.Title = "Service Data";
  225. ViewBag.Description = "Viewing all of your service data";
  226. model.Uploads = _dbContext.Uploads.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DateUploaded).ToList();
  227. model.Pastes = _dbContext.Pastes.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DatePosted).ToList();
  228. model.ShortenedUrls = _dbContext.ShortenedUrls.Where(s => s.UserId == user.UserId).OrderByDescending(s => s.DateAdded).ToList();
  229. model.Vaults = _dbContext.Vaults.Where(v => v.UserId == user.UserId).OrderByDescending(v => v.DateCreated).ToList();
  230. return View(model);
  231. }
  232. model.Error = true;
  233. model.ErrorMessage = "The user does not exist";
  234. }
  235. catch (Exception ex)
  236. {
  237. model.Error = true;
  238. model.ErrorMessage = ex.GetFullMessage(true);
  239. }
  240. return View(model);
  241. }
  242. public IActionResult Settings()
  243. {
  244. return Redirect(Url.SubRouteUrl("account", "User.ProfileSettings"));
  245. }
  246. public IActionResult ProfileSettings()
  247. {
  248. string username = User.Identity.Name;
  249. User user = UserHelper.GetUser(_dbContext, username);
  250. if (user != null)
  251. {
  252. ViewBag.Title = "Profile Settings";
  253. ViewBag.Description = "Your " + _config.Title + " Profile Settings";
  254. ProfileSettingsViewModel model = new ProfileSettingsViewModel();
  255. model.Page = "Profile";
  256. model.UserID = user.UserId;
  257. model.Username = user.Username;
  258. model.About = user.UserSettings.About;
  259. model.Quote = user.UserSettings.Quote;
  260. model.Website = user.UserSettings.Website;
  261. return View("/Areas/User/Views/User/Settings/ProfileSettings.cshtml", model);
  262. }
  263. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  264. }
  265. public IActionResult AccountSettings()
  266. {
  267. string username = User.Identity.Name;
  268. User user = UserHelper.GetUser(_dbContext, username);
  269. if (user != null)
  270. {
  271. ViewBag.Title = "Account Settings";
  272. ViewBag.Description = "Your " + _config.Title + " Account Settings";
  273. AccountSettingsViewModel model = new AccountSettingsViewModel();
  274. model.Page = "Account";
  275. model.UserID = user.UserId;
  276. model.Username = user.Username;
  277. return View("/Areas/User/Views/User/Settings/AccountSettings.cshtml", model);
  278. }
  279. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  280. }
  281. public async Task<IActionResult> SecuritySettings()
  282. {
  283. string username = User.Identity.Name;
  284. User user = UserHelper.GetUser(_dbContext, username);
  285. if (user != null)
  286. {
  287. ViewBag.Title = "Security Settings";
  288. ViewBag.Description = "Your " + _config.Title + " Security Settings";
  289. SecuritySettingsViewModel model = new SecuritySettingsViewModel();
  290. model.Page = "Security";
  291. model.UserID = user.UserId;
  292. model.Username = user.Username;
  293. // Get the user secure info
  294. IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, user.Username);
  295. //model.TrustedDeviceCount = user.TrustedDevices.Count;
  296. //model.AuthTokens = new List<AuthTokenViewModel>();
  297. //foreach (AuthToken token in user.AuthTokens)
  298. //{
  299. // AuthTokenViewModel tokenModel = new AuthTokenViewModel();
  300. // tokenModel.AuthTokenId = token.AuthTokenId;
  301. // tokenModel.Name = token.Name;
  302. // tokenModel.LastDateUsed = token.LastDateUsed;
  303. // model.AuthTokens.Add(tokenModel);
  304. //}
  305. model.PgpPublicKey = userInfo.PGPPublicKey;
  306. model.RecoveryEmail = userInfo.RecoveryEmail;
  307. if (userInfo.RecoveryVerified.HasValue)
  308. model.RecoveryVerified = userInfo.RecoveryVerified.Value;
  309. if (userInfo.TwoFactorEnabled.HasValue)
  310. model.TwoFactorEnabled = userInfo.TwoFactorEnabled.Value;
  311. return View("/Areas/User/Views/User/Settings/SecuritySettings.cshtml", model);
  312. }
  313. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  314. }
  315. public async Task<IActionResult> DeveloperSettings()
  316. {
  317. string username = User.Identity.Name;
  318. User user = UserHelper.GetUser(_dbContext, username);
  319. if (user != null)
  320. {
  321. ViewBag.Title = "Developer Settings";
  322. ViewBag.Description = "Your " + _config.Title + " Developer Settings";
  323. DeveloperSettingsViewModel model = new DeveloperSettingsViewModel();
  324. model.Page = "Developer";
  325. model.UserID = user.UserId;
  326. model.Username = user.Username;
  327. model.AuthTokens = new List<AuthTokenViewModel>();
  328. model.Clients = new List<ClientViewModel>();
  329. //foreach (AuthToken token in user.AuthTokens)
  330. //{
  331. // AuthTokenViewModel tokenModel = new AuthTokenViewModel();
  332. // tokenModel.AuthTokenId = token.AuthTokenId;
  333. // tokenModel.Name = token.Name;
  334. // tokenModel.LastDateUsed = token.LastDateUsed;
  335. // model.AuthTokens.Add(tokenModel);
  336. //}
  337. Client[] clients = await IdentityHelper.GetClients(_config, username);
  338. foreach (Client client in clients)
  339. {
  340. model.Clients.Add(new ClientViewModel()
  341. {
  342. Id = client.ClientId,
  343. Name = client.ClientName,
  344. HomepageUrl = client.ClientUri,
  345. LogoUrl = client.LogoUri,
  346. CallbackUrl = string.Join(',', client.RedirectUris),
  347. AllowedScopes = client.AllowedScopes
  348. });
  349. }
  350. return View("/Areas/User/Views/User/Settings/DeveloperSettings.cshtml", model);
  351. }
  352. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  353. }
  354. public IActionResult InviteSettings()
  355. {
  356. string username = User.Identity.Name;
  357. User user = UserHelper.GetUser(_dbContext, username);
  358. if (user != null)
  359. {
  360. ViewBag.Title = "Invite Settings";
  361. ViewBag.Description = "Your " + _config.Title + " Invite Settings";
  362. InviteSettingsViewModel model = new InviteSettingsViewModel();
  363. model.Page = "Invite";
  364. model.UserID = user.UserId;
  365. model.Username = user.Username;
  366. List<InviteCodeViewModel> availableCodes = new List<InviteCodeViewModel>();
  367. List<InviteCodeViewModel> claimedCodes = new List<InviteCodeViewModel>();
  368. if (user.OwnedInviteCodes != null)
  369. {
  370. foreach (InviteCode inviteCode in user.OwnedInviteCodes.Where(c => c.Active))
  371. {
  372. InviteCodeViewModel inviteCodeViewModel = new InviteCodeViewModel();
  373. inviteCodeViewModel.ClaimedUser = inviteCode.ClaimedUser;
  374. inviteCodeViewModel.Active = inviteCode.Active;
  375. inviteCodeViewModel.Code = inviteCode.Code;
  376. inviteCodeViewModel.InviteCodeId = inviteCode.InviteCodeId;
  377. inviteCodeViewModel.Owner = inviteCode.Owner;
  378. if (inviteCode.ClaimedUser == null)
  379. availableCodes.Add(inviteCodeViewModel);
  380. if (inviteCode.ClaimedUser != null)
  381. claimedCodes.Add(inviteCodeViewModel);
  382. }
  383. }
  384. model.AvailableCodes = availableCodes;
  385. model.ClaimedCodes = claimedCodes;
  386. return View("/Areas/User/Views/User/Settings/InviteSettings.cshtml", model);
  387. }
  388. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  389. }
  390. public IActionResult BlogSettings()
  391. {
  392. string username = User.Identity.Name;
  393. User user = UserHelper.GetUser(_dbContext, username);
  394. if (user != null)
  395. {
  396. ViewBag.Title = "Blog Settings";
  397. ViewBag.Description = "Your " + _config.Title + " Blog Settings";
  398. BlogSettingsViewModel model = new BlogSettingsViewModel();
  399. model.Page = "Blog";
  400. model.UserID = user.UserId;
  401. model.Username = user.Username;
  402. model.Title = user.BlogSettings.Title;
  403. model.Description = user.BlogSettings.Description;
  404. return View("/Areas/User/Views/User/Settings/BlogSettings.cshtml", model);
  405. }
  406. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  407. }
  408. public IActionResult UploadSettings()
  409. {
  410. string username = User.Identity.Name;
  411. User user = UserHelper.GetUser(_dbContext, username);
  412. if (user != null)
  413. {
  414. ViewBag.Title = "Upload Settings";
  415. ViewBag.Description = "Your " + _config.Title + " Upload Settings";
  416. UploadSettingsViewModel model = new UploadSettingsViewModel();
  417. model.Page = "Upload";
  418. model.UserID = user.UserId;
  419. model.Username = user.Username;
  420. model.Encrypt = user.UploadSettings.Encrypt;
  421. model.ExpirationLength = user.UploadSettings.ExpirationLength;
  422. model.ExpirationUnit = user.UploadSettings.ExpirationUnit;
  423. return View("/Areas/User/Views/User/Settings/UploadSettings.cshtml", model);
  424. }
  425. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  426. }
  427. [HttpGet]
  428. [AllowAnonymous]
  429. public async Task<IActionResult> ViewRawPGP(string username)
  430. {
  431. ViewBag.Title = username + "'s Public Key";
  432. ViewBag.Description = "The PGP public key for " + username;
  433. IdentityUserInfo userClaims = await IdentityHelper.GetIdentityUserInfo(_config, username);
  434. if (!string.IsNullOrEmpty(userClaims.PGPPublicKey))
  435. {
  436. return Content(userClaims.PGPPublicKey, "text/plain");
  437. }
  438. return new StatusCodeResult(StatusCodes.Status404NotFound);
  439. }
  440. [HttpPost]
  441. [ValidateAntiForgeryToken]
  442. public IActionResult EditBlog(BlogSettingsViewModel settings)
  443. {
  444. if (ModelState.IsValid)
  445. {
  446. try
  447. {
  448. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  449. if (user != null)
  450. {
  451. // Blogs
  452. user.BlogSettings.Title = settings.Title;
  453. user.BlogSettings.Description = settings.Description;
  454. UserHelper.EditAccount(_dbContext, _config, user);
  455. return Json(new { result = true });
  456. }
  457. return Json(new { error = "User does not exist" });
  458. }
  459. catch (Exception ex)
  460. {
  461. return Json(new { error = ex.GetFullMessage(true) });
  462. }
  463. }
  464. return Json(new { error = "Invalid Parameters" });
  465. }
  466. [HttpPost]
  467. [ValidateAntiForgeryToken]
  468. public IActionResult EditProfile(ProfileSettingsViewModel settings)
  469. {
  470. if (ModelState.IsValid)
  471. {
  472. try
  473. {
  474. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  475. if (user != null)
  476. {
  477. // Profile Info
  478. user.UserSettings.Website = settings.Website;
  479. user.UserSettings.Quote = settings.Quote;
  480. user.UserSettings.About = settings.About;
  481. UserHelper.EditAccount(_dbContext, _config, user);
  482. return Json(new { result = true });
  483. }
  484. return Json(new { error = "User does not exist" });
  485. }
  486. catch (Exception ex)
  487. {
  488. return Json(new { error = ex.GetFullMessage(true) });
  489. }
  490. }
  491. return Json(new { error = "Invalid Parameters" });
  492. }
  493. [HttpPost]
  494. [ValidateAntiForgeryToken]
  495. public async Task<IActionResult> EditSecurity(SecuritySettingsViewModel settings)
  496. {
  497. if (ModelState.IsValid)
  498. {
  499. try
  500. {
  501. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  502. if (user != null)
  503. {
  504. // PGP Key valid?
  505. if (!string.IsNullOrEmpty(settings.PgpPublicKey) && !PGP.IsPublicKey(settings.PgpPublicKey))
  506. {
  507. return Json(new { error = "Invalid PGP Public Key" });
  508. }
  509. // Get the user secure info
  510. IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, user.Username);
  511. if (userInfo.PGPPublicKey != settings.PgpPublicKey)
  512. {
  513. var result = await IdentityHelper.UpdatePGPPublicKey(_config, user.Username, settings.PgpPublicKey);
  514. if (!result.Success)
  515. return Json(new { error = result.Message });
  516. }
  517. if (userInfo.RecoveryEmail != settings.RecoveryEmail)
  518. {
  519. var token = await IdentityHelper.UpdateRecoveryEmail(_config, user.Username, settings.RecoveryEmail);
  520. // If they have a recovery email, let's send a verification
  521. if (!string.IsNullOrEmpty(settings.RecoveryEmail))
  522. {
  523. string resetUrl = Url.SubRouteUrl("account", "User.ResetPassword", new { Username = user.Username });
  524. string verifyUrl = Url.SubRouteUrl("account", "User.VerifyRecoveryEmail", new { Username = user.Username, Code = WebUtility.UrlEncode(token) });
  525. UserHelper.SendRecoveryEmailVerification(_config, user.Username, settings.RecoveryEmail, resetUrl, verifyUrl);
  526. }
  527. }
  528. //if (!settings.TwoFactorEnabled && (!userInfo.TwoFactorEnabled.HasValue || userInfo.TwoFactorEnabled.Value))
  529. //{
  530. // var result = await IdentityHelper.Disable2FA(_config, user.Username);
  531. // if (!result.Success)
  532. // return Json(new { error = result.Message });
  533. //}
  534. //UserHelper.EditAccount(_dbContext, _config, user, changePass, settings.NewPassword);
  535. //if (!oldTwoFactor && settings.TwoFactorEnabled)
  536. //{
  537. // return Json(new { result = new { checkAuth = true, key = newKey, qrUrl = Url.SubRouteUrl("account", "User.Action", new { action = "GenerateAuthQrCode", key = newKey }) } });
  538. //}
  539. return Json(new { result = true });
  540. }
  541. return Json(new { error = "User does not exist" });
  542. }
  543. catch (Exception ex)
  544. {
  545. return Json(new { error = ex.GetFullMessage(true) });
  546. }
  547. }
  548. return Json(new { error = "Invalid Parameters" });
  549. }
  550. [HttpPost]
  551. [ValidateAntiForgeryToken]
  552. public IActionResult EditUpload(UploadSettingsViewModel settings)
  553. {
  554. if (ModelState.IsValid)
  555. {
  556. try
  557. {
  558. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  559. if (user != null)
  560. {
  561. // Profile Info
  562. user.UploadSettings.Encrypt = settings.Encrypt;
  563. user.UploadSettings.ExpirationUnit = settings.ExpirationUnit;
  564. user.UploadSettings.ExpirationLength = settings.ExpirationLength;
  565. UserHelper.EditAccount(_dbContext, _config, user);
  566. return Json(new { result = true });
  567. }
  568. return Json(new { error = "User does not exist" });
  569. }
  570. catch (Exception ex)
  571. {
  572. return Json(new { error = ex.GetFullMessage(true) });
  573. }
  574. }
  575. return Json(new { error = "Invalid Parameters" });
  576. }
  577. public async Task<IActionResult> ChangePassword(AccountSettingsViewModel settings)
  578. {
  579. if (ModelState.IsValid)
  580. {
  581. try
  582. {
  583. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  584. if (user != null)
  585. {
  586. // Did they enter their old password
  587. if (string.IsNullOrEmpty(settings.CurrentPassword))
  588. return Json(new { error = "You must enter your current password" });
  589. // Did they enter a new password
  590. if (string.IsNullOrEmpty(settings.NewPassword) || string.IsNullOrEmpty(settings.NewPasswordConfirm))
  591. return Json(new { error = "You must enter your new password" });
  592. // Old Password Valid?
  593. if (!(await UserHelper.UserPasswordCorrect(_config, user.Username, settings.CurrentPassword)))
  594. return Json(new { error = "Invalid Original Password" });
  595. // The New Password Match?
  596. if (settings.NewPassword != settings.NewPasswordConfirm)
  597. return Json(new { error = "New Password must match confirmation" });
  598. // Are password resets enabled?
  599. if (!_config.UserConfig.PasswordResetEnabled)
  600. return Json(new { error = "Password resets are disabled" });
  601. // Change their password
  602. await UserHelper.ChangeAccountPassword(_dbContext, _config, user.Username, settings.CurrentPassword, settings.NewPassword);
  603. return Json(new { result = true });
  604. }
  605. return Json(new { error = "User does not exist" });
  606. }
  607. catch (Exception ex)
  608. {
  609. return Json(new { error = ex.GetFullMessage(true) });
  610. }
  611. }
  612. return Json(new { error = "Invalid Parameters" });
  613. }
  614. [HttpPost]
  615. [ValidateAntiForgeryToken]
  616. public async Task<IActionResult> Delete()
  617. {
  618. if (ModelState.IsValid)
  619. {
  620. try
  621. {
  622. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  623. if (user != null)
  624. {
  625. await UserHelper.DeleteAccount(_dbContext, _config, user);
  626. // Sign Out
  627. await HttpContext.SignOutAsync("Cookies");
  628. await HttpContext.SignOutAsync("oidc");
  629. return Json(new { result = true });
  630. }
  631. }
  632. catch (Exception ex)
  633. {
  634. return Json(new { error = ex.GetFullMessage(true) });
  635. }
  636. }
  637. return Json(new { error = "Unable to delete user" });
  638. }
  639. [HttpGet]
  640. public async Task<IActionResult> VerifyRecoveryEmail(string username, string code)
  641. {
  642. bool verified = true;
  643. if (string.IsNullOrEmpty(code))
  644. verified &= false;
  645. // Is there a code?
  646. if (verified)
  647. {
  648. var result = await IdentityHelper.VerifyRecoveryEmail(_config, username, WebUtility.UrlDecode(code));
  649. verified &= result.Success;
  650. }
  651. RecoveryEmailVerificationViewModel model = new RecoveryEmailVerificationViewModel();
  652. model.Success = verified;
  653. return View("/Areas/User/Views/User/ViewRecoveryEmailVerification.cshtml", model);
  654. }
  655. [HttpPost]
  656. [ValidateAntiForgeryToken]
  657. public async Task<IActionResult> ResendVerifyRecoveryEmail()
  658. {
  659. if (ModelState.IsValid)
  660. {
  661. try
  662. {
  663. IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
  664. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  665. if (user != null)
  666. {
  667. //If they have a recovery email, let's send a verification
  668. if (!string.IsNullOrEmpty(userInfo.RecoveryEmail))
  669. {
  670. if (!userInfo.RecoveryVerified.HasValue || !userInfo.RecoveryVerified.Value)
  671. {
  672. var token = await IdentityHelper.UpdateRecoveryEmail(_config, user.Username, userInfo.RecoveryEmail);
  673. string resetUrl = Url.SubRouteUrl("account", "User.ResetPassword", new { Username = user.Username });
  674. string verifyUrl = Url.SubRouteUrl("account", "User.VerifyRecoveryEmail", new { Username = user.Username, Code = WebUtility.UrlEncode(token) });
  675. UserHelper.SendRecoveryEmailVerification(_config, user.Username, userInfo.RecoveryEmail, resetUrl, verifyUrl);
  676. return Json(new { result = true });
  677. }
  678. return Json(new { error = "The recovery email is already verified" });
  679. }
  680. }
  681. }
  682. catch (Exception ex)
  683. {
  684. return Json(new { error = ex.GetFullMessage(true) });
  685. }
  686. }
  687. return Json(new { error = "Unable to resend verification" });
  688. }
  689. [HttpGet]
  690. [AllowAnonymous]
  691. public IActionResult ResetPassword(string username)
  692. {
  693. ResetPasswordViewModel model = new ResetPasswordViewModel();
  694. model.Username = username;
  695. return View("/Areas/User/Views/User/ResetPassword.cshtml", model);
  696. }
  697. [HttpPost]
  698. [AllowAnonymous]
  699. [ValidateAntiForgeryToken]
  700. public async Task<IActionResult> SendResetPasswordVerification(string username)
  701. {
  702. if (ModelState.IsValid)
  703. {
  704. try
  705. {
  706. User user = UserHelper.GetUser(_dbContext, username);
  707. if (user != null)
  708. {
  709. IdentityUserInfo userClaims = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
  710. // If they have a recovery email, let's send a verification
  711. if (!string.IsNullOrEmpty(userClaims.RecoveryEmail) && userClaims.RecoveryVerified.HasValue && userClaims.RecoveryVerified.Value)
  712. {
  713. string verifyCode = await IdentityHelper.GeneratePasswordResetToken(_config, User.Identity.Name);
  714. string resetUrl = Url.SubRouteUrl("account", "User.VerifyResetPassword", new { Username = user.Username, Code = WebUtility.UrlEncode(verifyCode) });
  715. UserHelper.SendResetPasswordVerification(_config, user.Username, userClaims.RecoveryEmail, resetUrl);
  716. return Json(new { result = true });
  717. }
  718. return Json(new { error = "The user doesn't have a recovery email specified, or has not been verified." });
  719. }
  720. return Json(new { error = "The username is not valid" });
  721. }
  722. catch (Exception ex)
  723. {
  724. return Json(new { error = ex.GetFullMessage(true) });
  725. }
  726. }
  727. return Json(new { error = "Unable to send reset link" });
  728. }
  729. [HttpGet]
  730. [AllowAnonymous]
  731. public async Task<IActionResult> VerifyResetPassword(string username, string code)
  732. {
  733. bool verified = true;
  734. if (string.IsNullOrEmpty(code))
  735. verified &= false;
  736. // Is there a code?
  737. if (verified)
  738. {
  739. // The password reset code is valid, let's get their user account for this session
  740. User user = UserHelper.GetUser(_dbContext, username);
  741. _session.SetString(_AuthSessionKey, user.Username);
  742. _session.SetString("AuthCode", WebUtility.UrlDecode(code));
  743. await _session.CommitAsync();
  744. }
  745. ResetPasswordVerificationViewModel model = new ResetPasswordVerificationViewModel();
  746. model.Success = verified;
  747. return View("/Areas/User/Views/User/ResetPasswordVerification.cshtml", model);
  748. }
  749. [HttpPost]
  750. [AllowAnonymous]
  751. [ValidateAntiForgeryToken]
  752. public async Task<IActionResult> SetUserPassword(SetPasswordViewModel passwordViewModel)
  753. {
  754. if (ModelState.IsValid)
  755. {
  756. try
  757. {
  758. await _session.LoadAsync();
  759. string code = _session.GetString("AuthCode");
  760. if (!string.IsNullOrEmpty(code))
  761. {
  762. string username = _session.GetString(_AuthSessionKey);
  763. if (!string.IsNullOrEmpty(username))
  764. {
  765. if (string.IsNullOrEmpty(passwordViewModel.Password))
  766. {
  767. return Json(new { error = "Password must not be empty" });
  768. }
  769. if (passwordViewModel.Password != passwordViewModel.PasswordConfirm)
  770. {
  771. return Json(new { error = "Passwords must match" });
  772. }
  773. try
  774. {
  775. await UserHelper.ResetAccountPassword(_dbContext, _config, username, code, passwordViewModel.Password);
  776. _session.Remove(_AuthSessionKey);
  777. _session.Remove("AuthCode");
  778. return Json(new { result = true });
  779. }
  780. catch (Exception ex)
  781. {
  782. return Json(new { error = ex.Message });
  783. }
  784. }
  785. return Json(new { error = "User does not exist" });
  786. }
  787. return Json(new { error = "Invalid Code" });
  788. }
  789. catch (Exception ex)
  790. {
  791. return Json(new { error = ex.GetFullMessage(true) });
  792. }
  793. }
  794. return Json(new { error = "Unable to reset user password" });
  795. }
  796. [HttpPost]
  797. [ValidateAntiForgeryToken]
  798. public async Task<IActionResult> Generate2FA()
  799. {
  800. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  801. if (user != null)
  802. {
  803. // Get User Identity Info
  804. var userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
  805. if (userInfo.TwoFactorEnabled.HasValue && !userInfo.TwoFactorEnabled.Value)
  806. {
  807. // Validate the code with the identity server
  808. var key = await IdentityHelper.Reset2FAKey(_config, user.Username);
  809. if (!string.IsNullOrEmpty(key))
  810. {
  811. return Json(new { result = true, key = key, qrUrl = Url.SubRouteUrl("account", "User.Action", new { action = "GenerateAuthQrCode", key = key }) });
  812. }
  813. return Json(new { error = "Unable to generate Two Factor Authentication key" });
  814. }
  815. return Json(new { error = "User already has Two Factor Authentication enabled" });
  816. }
  817. return Json(new { error = "User does not exist" });
  818. }
  819. [HttpPost]
  820. [ValidateAntiForgeryToken]
  821. public async Task<IActionResult> VerifyAuthenticatorCode(string code)
  822. {
  823. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  824. if (user != null)
  825. {
  826. // Get User Identity Info
  827. var userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
  828. if (userInfo.TwoFactorEnabled.HasValue && !userInfo.TwoFactorEnabled.Value)
  829. {
  830. // Validate the code with the identity server
  831. var result = await IdentityHelper.Enable2FA(_config, user.Username, code);
  832. if (result.Any())
  833. {
  834. return Json(new { result = true, recoveryCodes = result });
  835. }
  836. return Json(new { error = "Invalid Authentication Code" });
  837. }
  838. return Json(new { error = "User already has Two Factor Authentication enabled" });
  839. }
  840. return Json(new { error = "User does not exist" });
  841. }
  842. [HttpPost]
  843. [ValidateAntiForgeryToken]
  844. public async Task<IActionResult> ResetRecoveryCodes()
  845. {
  846. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  847. if (user != null)
  848. {
  849. // Get User Identity Info
  850. var userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
  851. if (userInfo.TwoFactorEnabled.HasValue && userInfo.TwoFactorEnabled.Value)
  852. {
  853. // Regenerate the recovery codes
  854. var result = await IdentityHelper.GenerateRecoveryCodes(_config, user.Username);
  855. if (result.Any())
  856. {
  857. return Json(new { result = true, recoveryCodes = result });
  858. }
  859. return Json(new { error = "Invalid Authentication Code" });
  860. }
  861. return Json(new { error = "User doesn't have Two Factor Authentication enabled" });
  862. }
  863. return Json(new { error = "User does not exist" });
  864. }
  865. [HttpPost]
  866. [ValidateAntiForgeryToken]
  867. public async Task<IActionResult> Disable2FA()
  868. {
  869. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  870. if (user != null)
  871. {
  872. // Get User Identity Info
  873. var userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
  874. if (userInfo.TwoFactorEnabled.HasValue && userInfo.TwoFactorEnabled.Value)
  875. {
  876. // Validate the code with the identity server
  877. var result = await IdentityHelper.Disable2FA(_config, user.Username);
  878. if (result.Success)
  879. {
  880. return Json(new { result = true });
  881. }
  882. return Json(new { error = result.Message });
  883. }
  884. return Json(new { error = "User doesn't have Two Factor Authentication enabled" });
  885. }
  886. return Json(new { error = "User does not exist" });
  887. }
  888. [HttpGet]
  889. public IActionResult GenerateAuthQrCode(string key)
  890. {
  891. var ProvisionUrl = string.Format("otpauth://totp/{0}:{1}?secret={2}", _config.Title, User.Identity.Name, key);
  892. QRCodeGenerator qrGenerator = new QRCodeGenerator();
  893. QRCodeData qrCodeData = qrGenerator.CreateQrCode(ProvisionUrl, QRCodeGenerator.ECCLevel.Q);
  894. PngByteQRCode qrCode = new PngByteQRCode(qrCodeData);
  895. return File(qrCode.GetGraphic(20), "image/png");
  896. }
  897. [HttpPost]
  898. [ValidateAntiForgeryToken]
  899. public IActionResult ClearTrustedDevices()
  900. {
  901. try
  902. {
  903. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  904. if (user != null)
  905. {
  906. //if (user.SecuritySettings.AllowTrustedDevices)
  907. //{
  908. // // let's clear the trusted devices
  909. // user.TrustedDevices.Clear();
  910. // List<TrustedDevice> foundDevices = _dbContext.TrustedDevices.Where(d => d.UserId == user.UserId).ToList();
  911. // if (foundDevices != null)
  912. // {
  913. // foreach (TrustedDevice device in foundDevices)
  914. // {
  915. // _dbContext.TrustedDevices.Remove(device);
  916. // }
  917. // }
  918. // _dbContext.Entry(user).State = EntityState.Modified;
  919. // _dbContext.SaveChanges();
  920. // return Json(new { result = true });
  921. //}
  922. return Json(new { error = "User does not allow trusted devices" });
  923. }
  924. return Json(new { error = "User does not exist" });
  925. }
  926. catch (Exception ex)
  927. {
  928. return Json(new { error = ex.GetFullMessage(true) });
  929. }
  930. }
  931. [HttpPost]
  932. [ValidateAntiForgeryToken]
  933. public async Task<IActionResult> GenerateToken(string name, [FromServices] ICompositeViewEngine viewEngine)
  934. {
  935. try
  936. {
  937. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  938. if (user != null)
  939. {
  940. //string newTokenStr = UserHelper.GenerateAuthToken(_dbContext, user.Username);
  941. //if (!string.IsNullOrEmpty(newTokenStr))
  942. //{
  943. // AuthToken token = new AuthToken();
  944. // token.UserId = user.UserId;
  945. // token.HashedToken = SHA256.Hash(newTokenStr);
  946. // token.Name = name;
  947. // _dbContext.AuthTokens.Add(token);
  948. // _dbContext.SaveChanges();
  949. // AuthTokenViewModel model = new AuthTokenViewModel();
  950. // model.AuthTokenId = token.AuthTokenId;
  951. // model.Name = token.Name;
  952. // model.LastDateUsed = token.LastDateUsed;
  953. // string renderedView = await RenderPartialViewToString(viewEngine, "~/Areas/User/Views/User/Settings/AuthToken.cshtml", model);
  954. // return Json(new { result = new { token = newTokenStr, html = renderedView } });
  955. //}
  956. return Json(new { error = "Unable to generate Auth Token" });
  957. }
  958. return Json(new { error = "User does not exist" });
  959. }
  960. catch (Exception ex)
  961. {
  962. return Json(new { error = ex.GetFullMessage(true) });
  963. }
  964. }
  965. [HttpPost]
  966. [ValidateAntiForgeryToken]
  967. public IActionResult RevokeAllTokens()
  968. {
  969. try
  970. {
  971. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  972. if (user != null)
  973. {
  974. //user.AuthTokens.Clear();
  975. //List<AuthToken> foundTokens = _dbContext.AuthTokens.Where(d => d.UserId == user.UserId).ToList();
  976. //if (foundTokens != null)
  977. //{
  978. // foreach (AuthToken token in foundTokens)
  979. // {
  980. // _dbContext.AuthTokens.Remove(token);
  981. // }
  982. //}
  983. _dbContext.Entry(user).State = EntityState.Modified;
  984. _dbContext.SaveChanges();
  985. return Json(new { result = true });
  986. }
  987. return Json(new { error = "User does not exist" });
  988. }
  989. catch (Exception ex)
  990. {
  991. return Json(new { error = ex.GetFullMessage(true) });
  992. }
  993. }
  994. [HttpPost]
  995. [ValidateAntiForgeryToken]
  996. public IActionResult EditTokenName(int tokenId, string name)
  997. {
  998. try
  999. {
  1000. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  1001. if (user != null)
  1002. {
  1003. //AuthToken foundToken = _dbContext.AuthTokens.Where(d => d.UserId == user.UserId && d.AuthTokenId == tokenId).FirstOrDefault();
  1004. //if (foundToken != null)
  1005. //{
  1006. // foundToken.Name = name;
  1007. // _dbContext.Entry(foundToken).State = EntityState.Modified;
  1008. // _dbContext.SaveChanges();
  1009. // return Json(new { result = new { name = name } });
  1010. //}
  1011. return Json(new { error = "Authentication Token does not exist" });
  1012. }
  1013. return Json(new { error = "User does not exist" });
  1014. }
  1015. catch (Exception ex)
  1016. {
  1017. return Json(new { error = ex.GetFullMessage(true) });
  1018. }
  1019. }
  1020. [HttpPost]
  1021. [ValidateAntiForgeryToken]
  1022. public IActionResult DeleteToken(int tokenId)
  1023. {
  1024. try
  1025. {
  1026. User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
  1027. if (user != null)
  1028. {
  1029. //AuthToken foundToken = _dbContext.AuthTokens.Where(d => d.UserId == user.UserId && d.AuthTokenId == tokenId).FirstOrDefault();
  1030. //if (foundToken != null)
  1031. //{
  1032. // _dbContext.AuthTokens.Remove(foundToken);
  1033. // user.AuthTokens.Remove(foundToken);
  1034. // _dbContext.Entry(user).State = EntityState.Modified;
  1035. // _dbContext.SaveChanges();
  1036. // return Json(new { result = true });
  1037. //}
  1038. return Json(new { error = "Authentication Token does not exist" });
  1039. }
  1040. return Json(new { error = "User does not exist" });
  1041. }
  1042. catch (Exception ex)
  1043. {
  1044. return Json(new { error = ex.GetFullMessage(true) });
  1045. }
  1046. }
  1047. [HttpPost]
  1048. [ValidateAntiForgeryToken]
  1049. public async Task<IActionResult> CreateClient(string name, string homepageUrl, string logoUrl, string callbackUrl, [FromServices] ICompositeViewEngine viewEngine)
  1050. {
  1051. try
  1052. {
  1053. if (string.IsNullOrEmpty(name))
  1054. return Json(new { error = "You must enter a client name" });
  1055. if (string.IsNullOrEmpty(callbackUrl))
  1056. return Json(new { error = "You must enter an authorization callback URL" });
  1057. // Validate the code with the identity server
  1058. var result = await IdentityHelper.CreateClient(_config, User.Identity.Name, name, homepageUrl, logoUrl, callbackUrl, "openid", "role", "account-info", "security-info", "teknik-api.read", "teknik-api.write");
  1059. if (result.Success)
  1060. {
  1061. var client = (JObject)result.Data;
  1062. ClientViewModel model = new ClientViewModel();
  1063. model.Id = client["id"].ToString();
  1064. model.Name = name;
  1065. model.HomepageUrl = homepageUrl;
  1066. model.LogoUrl = logoUrl;
  1067. model.CallbackUrl = callbackUrl;
  1068. string renderedView = await RenderPartialViewToString(viewEngine, "~/Areas/User/Views/User/Settings/ClientView.cshtml", model);
  1069. return Json(new { result = true, clientId = client["id"], secret = client["secret"], html = renderedView });
  1070. }
  1071. return Json(new { error = result.Message });
  1072. }
  1073. catch (Exception ex)
  1074. {
  1075. return Json(new { error = ex.GetFullMessage(true) });
  1076. }
  1077. }
  1078. [HttpPost]
  1079. [ValidateAntiForgeryToken]
  1080. public async Task<IActionResult> GetClient(string clientId)
  1081. {
  1082. Client foundClient = await IdentityHelper.GetClient(_config, User.Identity.Name, clientId);
  1083. if (foundClient != null)
  1084. {
  1085. ClientViewModel model = new ClientViewModel()
  1086. {
  1087. Id = foundClient.ClientId,
  1088. Name = foundClient.ClientName,
  1089. HomepageUrl = foundClient.ClientUri,
  1090. LogoUrl = foundClient.LogoUri,
  1091. CallbackUrl = string.Join(',', foundClient.RedirectUris),
  1092. AllowedScopes = foundClient.AllowedScopes
  1093. };
  1094. return Json(new { result = true, client = model });
  1095. }
  1096. return new StatusCodeResult(StatusCodes.Status403Forbidden);
  1097. }
  1098. [HttpPost]
  1099. [ValidateAntiForgeryToken]
  1100. public async Task<IActionResult> EditClient(string clientId, string name, string homepageUrl, string logoUrl, string callbackUrl, [FromServices] ICompositeViewEngine viewEngine)
  1101. {
  1102. try
  1103. {
  1104. if (string.IsNullOrEmpty(name))
  1105. return Json(new { error = "You must enter a client name" });
  1106. if (string.IsNullOrEmpty(callbackUrl))
  1107. return Json(new { error = "You must enter an authorization callback URL" });
  1108. Client foundClient = await IdentityHelper.GetClient(_config, User.Identity.Name, clientId);
  1109. if (foundClient == null)
  1110. return Json(new { error = "Client does not exist" });
  1111. // Validate the code with the identity server
  1112. var result = await IdentityHelper.EditClient(_config, User.Identity.Name, clientId, name, homepageUrl, logoUrl, callbackUrl);
  1113. if (result.Success)
  1114. {
  1115. var client = (JObject)result.Data;
  1116. ClientViewModel model = new ClientViewModel();
  1117. model.Id = clientId;
  1118. model.Name = name;
  1119. model.HomepageUrl = homepageUrl;
  1120. model.LogoUrl = logoUrl;
  1121. model.CallbackUrl = callbackUrl;
  1122. string renderedView = await RenderPartialViewToString(viewEngine, "~/Areas/User/Views/User/Settings/ClientView.cshtml", model);
  1123. return Json(new { result = true, clientId = clientId, html = renderedView });
  1124. }
  1125. return Json(new { error = result.Message });
  1126. }
  1127. catch (Exception ex)
  1128. {
  1129. return Json(new { error = ex.GetFullMessage(true) });
  1130. }
  1131. }
  1132. [HttpPost]
  1133. [ValidateAntiForgeryToken]
  1134. public async Task<IActionResult> DeleteClient(string clientId)
  1135. {
  1136. try
  1137. {
  1138. // Validate the code with the identity server
  1139. var result = await IdentityHelper.DeleteClient(_config, clientId);
  1140. if (result.Success)
  1141. {
  1142. return Json(new { result = true });
  1143. }
  1144. return Json(new { error = result.Message });
  1145. }
  1146. catch (Exception ex)
  1147. {
  1148. return Json(new { error = ex.GetFullMessage(true) });
  1149. }
  1150. }
  1151. [HttpPost]
  1152. [ValidateAntiForgeryToken]
  1153. public IActionResult CreateInviteCodeLink(int inviteCodeId)
  1154. {
  1155. try
  1156. {
  1157. InviteCode code = _dbContext.InviteCodes.Where(c => c.InviteCodeId == inviteCodeId).FirstOrDefault();
  1158. if (code != null)
  1159. {
  1160. if (User.Identity.IsAuthenticated)
  1161. {
  1162. if (code.Owner.Username == User.Identity.Name)
  1163. {
  1164. return Json(new { result = Url.SubRouteUrl("account", "User.Register", new { inviteCode = code.Code }) });
  1165. }
  1166. }
  1167. return Json(new { error = "Invite Code not associated with this user" });
  1168. }
  1169. return Json(new { error = "Invalid Invite Code" });
  1170. }
  1171. catch (Exception ex)
  1172. {
  1173. return Json(new { error = ex.GetFullMessage(true) });
  1174. }
  1175. }
  1176. }
  1177. }