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.
1345 lines
55 KiB
1345 lines
55 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using Teknik.Areas.Users.Models; |
|
using Teknik.Areas.Users.ViewModels; |
|
using Teknik.Controllers; |
|
using Teknik.Utilities; |
|
using Teknik.Areas.Users.Utility; |
|
using Teknik.Filters; |
|
using QRCoder; |
|
using TwoStepsAuthenticator; |
|
using Teknik.Attributes; |
|
using Teknik.Utilities.Cryptography; |
|
using Microsoft.Extensions.Logging; |
|
using Teknik.Configuration; |
|
using Teknik.Data; |
|
using Microsoft.AspNetCore.Authorization; |
|
using Microsoft.AspNetCore.Mvc; |
|
using Microsoft.EntityFrameworkCore; |
|
using System.Net; |
|
using Microsoft.AspNetCore.Mvc.ViewEngines; |
|
using System.Threading.Tasks; |
|
using Teknik.Logging; |
|
using System.Security.Claims; |
|
using Microsoft.AspNetCore.Authentication.Cookies; |
|
using Microsoft.AspNetCore.Authentication; |
|
using IdentityServer4.Services; |
|
using Microsoft.AspNetCore.Identity; |
|
using IdentityModel.Client; |
|
using System.Net.Http; |
|
using Newtonsoft.Json.Linq; |
|
using Teknik.Security; |
|
using Microsoft.IdentityModel.Tokens; |
|
using IdentityModel; |
|
using System.Security.Cryptography; |
|
using System.IdentityModel.Tokens.Jwt; |
|
using Microsoft.AspNetCore.Http; |
|
using IdentityServer4.Models; |
|
|
|
namespace Teknik.Areas.Users.Controllers |
|
{ |
|
[Authorize] |
|
[Area("User")] |
|
public class UserController : DefaultController |
|
{ |
|
private static readonly UsedCodesManager usedCodesManager = new UsedCodesManager(); |
|
private const string _AuthSessionKey = "AuthenticatedUser"; |
|
|
|
private readonly IHttpContextAccessor _httpContextAccessor; |
|
private ISession _session => _httpContextAccessor.HttpContext.Session; |
|
|
|
public LogoutSessionManager _logoutSessions { get; } |
|
|
|
public UserController(ILogger<Logger> logger, Config config, TeknikEntities dbContext, LogoutSessionManager logoutSessions, IHttpContextAccessor httpContextAccessor) : base(logger, config, dbContext) |
|
{ |
|
_logoutSessions = logoutSessions; |
|
_httpContextAccessor = httpContextAccessor; |
|
} |
|
|
|
[HttpGet] |
|
public IActionResult Login(string returnUrl) |
|
{ |
|
// Let's double check their email and git accounts to make sure they exist |
|
string email = UserHelper.GetUserEmailAddress(_config, User.Identity.Name); |
|
if (_config.EmailConfig.Enabled && !UserHelper.UserEmailExists(_config, email)) |
|
{ |
|
//UserHelper.AddUserEmail(_config, email, model.Password); |
|
} |
|
|
|
if (_config.GitConfig.Enabled && !UserHelper.UserGitExists(_config, User.Identity.Name)) |
|
{ |
|
//UserHelper.AddUserGit(_config, User.Identity.Name, model.Password); |
|
} |
|
|
|
if (!string.IsNullOrEmpty(returnUrl)) |
|
{ |
|
return Redirect(returnUrl); |
|
} |
|
|
|
return Redirect(Url.SubRouteUrl("www", "Home.Index")); |
|
} |
|
|
|
[HttpGet] |
|
public async Task Logout() |
|
{ |
|
await HttpContext.SignOutAsync("Cookies"); |
|
await HttpContext.SignOutAsync("oidc"); |
|
} |
|
|
|
[HttpPost] |
|
[AllowAnonymous] |
|
public async Task<IActionResult> Logout(string logout_token) |
|
{ |
|
Response.Headers.Add("Cache-Control", "no-cache, no-store"); |
|
Response.Headers.Add("Pragma", "no-cache"); |
|
|
|
try |
|
{ |
|
var user = await ValidateLogoutToken(logout_token); |
|
|
|
// these are the sub & sid to signout |
|
var sub = user.FindFirst("sub")?.Value; |
|
var sid = user.FindFirst("sid")?.Value; |
|
|
|
_logoutSessions.Add(sub, sid); |
|
|
|
return Ok(); |
|
} |
|
catch { } |
|
|
|
return BadRequest(); |
|
} |
|
|
|
private async Task<ClaimsPrincipal> ValidateLogoutToken(string logoutToken) |
|
{ |
|
var claims = await ValidateJwt(logoutToken); |
|
|
|
if (claims.FindFirst("sub") == null && claims.FindFirst("sid") == null) throw new Exception("Invalid logout token"); |
|
|
|
var nonce = claims.FindFirstValue("nonce"); |
|
if (!String.IsNullOrWhiteSpace(nonce)) throw new Exception("Invalid logout token"); |
|
|
|
var eventsJson = claims.FindFirst("events")?.Value; |
|
if (String.IsNullOrWhiteSpace(eventsJson)) throw new Exception("Invalid logout token"); |
|
|
|
var events = JObject.Parse(eventsJson); |
|
var logoutEvent = events.TryGetValue("http://schemas.openid.net/event/backchannel-logout"); |
|
if (logoutEvent == null) throw new Exception("Invalid logout token"); |
|
|
|
return claims; |
|
} |
|
|
|
private async Task<ClaimsPrincipal> ValidateJwt(string jwt) |
|
{ |
|
// read discovery document to find issuer and key material |
|
var disco = await DiscoveryClient.GetAsync(_config.UserConfig.IdentityServerConfig.Authority); |
|
|
|
var keys = new List<SecurityKey>(); |
|
foreach (var webKey in disco.KeySet.Keys) |
|
{ |
|
var e = Base64Url.Decode(webKey.E); |
|
var n = Base64Url.Decode(webKey.N); |
|
|
|
var key = new RsaSecurityKey(new RSAParameters { Exponent = e, Modulus = n }) |
|
{ |
|
KeyId = webKey.Kid |
|
}; |
|
|
|
keys.Add(key); |
|
} |
|
|
|
var parameters = new TokenValidationParameters |
|
{ |
|
ValidIssuer = disco.Issuer, |
|
ValidAudience = _config.UserConfig.IdentityServerConfig.ClientId, |
|
IssuerSigningKeys = keys, |
|
|
|
NameClaimType = JwtClaimTypes.Name, |
|
RoleClaimType = JwtClaimTypes.Role |
|
}; |
|
|
|
var handler = new JwtSecurityTokenHandler(); |
|
handler.InboundClaimTypeMap.Clear(); |
|
|
|
var user = handler.ValidateToken(jwt, parameters, out var _); |
|
return user; |
|
} |
|
|
|
[AllowAnonymous] |
|
public IActionResult GetPremium() |
|
{ |
|
ViewBag.Title = "Get a Premium Account - " + _config.Title; |
|
|
|
GetPremiumViewModel model = new GetPremiumViewModel(); |
|
|
|
return View(model); |
|
} |
|
|
|
[HttpGet] |
|
[AllowAnonymous] |
|
public IActionResult Register(string inviteCode, string ReturnUrl) |
|
{ |
|
RegisterViewModel model = new RegisterViewModel(); |
|
model.InviteCode = inviteCode; |
|
model.ReturnUrl = ReturnUrl; |
|
|
|
return View("/Areas/User/Views/User/ViewRegistration.cshtml", model); |
|
} |
|
|
|
[HttpPost] |
|
[AllowAnonymous] |
|
public async Task<IActionResult> Register([Bind(Prefix = "Register")]RegisterViewModel model) |
|
{ |
|
model.Error = false; |
|
model.ErrorMessage = string.Empty; |
|
if (ModelState.IsValid) |
|
{ |
|
if (_config.UserConfig.RegistrationEnabled) |
|
{ |
|
if (!model.Error && !UserHelper.ValidUsername(_config, model.Username)) |
|
{ |
|
model.Error = true; |
|
model.ErrorMessage = "That username is not valid"; |
|
} |
|
if (!model.Error && !(await UserHelper.UsernameAvailable(_dbContext, _config, model.Username))) |
|
{ |
|
model.Error = true; |
|
model.ErrorMessage = "That username is not available"; |
|
} |
|
if (!model.Error && model.Password != model.ConfirmPassword) |
|
{ |
|
model.Error = true; |
|
model.ErrorMessage = "Passwords must match"; |
|
} |
|
|
|
// Validate the Invite Code |
|
if (!model.Error && _config.UserConfig.InviteCodeRequired && string.IsNullOrEmpty(model.InviteCode)) |
|
{ |
|
model.Error = true; |
|
model.ErrorMessage = "An Invite Code is required to register"; |
|
} |
|
if (!model.Error && !string.IsNullOrEmpty(model.InviteCode) && _dbContext.InviteCodes.Where(c => c.Code == model.InviteCode && c.Active && c.ClaimedUser == null).FirstOrDefault() == null) |
|
{ |
|
model.Error = true; |
|
model.ErrorMessage = "Invalid Invite Code"; |
|
} |
|
|
|
if (!model.Error) |
|
{ |
|
try |
|
{ |
|
await UserHelper.CreateAccount(_dbContext, _config, Url, model.Username, model.Password, model.RecoveryEmail, model.InviteCode); |
|
} |
|
catch (Exception ex) |
|
{ |
|
model.Error = true; |
|
model.ErrorMessage = ex.GetFullMessage(true); |
|
} |
|
if (!model.Error) |
|
{ |
|
return Redirect(Url.SubRouteUrl("user", "User.Login", new { returnUrl = model.ReturnUrl })); |
|
} |
|
} |
|
} |
|
if (!model.Error) |
|
{ |
|
model.Error = true; |
|
model.ErrorMessage = "User Registration is Disabled"; |
|
} |
|
} |
|
else |
|
{ |
|
model.Error = true; |
|
model.ErrorMessage = "Missing Required Fields"; |
|
} |
|
return GenerateActionResult(new { error = model.ErrorMessage }, View("/Areas/User/Views/User/ViewRegistration.cshtml", model)); |
|
} |
|
|
|
// GET: Profile/Profile |
|
[AllowAnonymous] |
|
public async Task<IActionResult> ViewProfile(string username) |
|
{ |
|
if (string.IsNullOrEmpty(username)) |
|
{ |
|
username = User.Identity.Name; |
|
} |
|
|
|
ProfileViewModel model = new ProfileViewModel(); |
|
ViewBag.Title = "User Does Not Exist - " + _config.Title; |
|
ViewBag.Description = "The User does not exist"; |
|
|
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, username); |
|
|
|
if (user != null) |
|
{ |
|
ViewBag.Title = username + "'s Profile - " + _config.Title; |
|
ViewBag.Description = "Viewing " + username + "'s Profile"; |
|
|
|
model.UserID = user.UserId; |
|
model.Username = user.Username; |
|
if (_config.EmailConfig.Enabled) |
|
{ |
|
model.Email = string.Format("{0}@{1}", user.Username, _config.EmailConfig.Domain); |
|
} |
|
|
|
// Get the user claims for this user |
|
model.IdentityUserInfo = await IdentityHelper.GetIdentityUserInfo(_config, user.Username); |
|
|
|
model.LastSeen = UserHelper.GetLastAccountActivity(_dbContext, _config, user.Username, model.IdentityUserInfo); |
|
|
|
model.UserSettings = user.UserSettings; |
|
model.BlogSettings = user.BlogSettings; |
|
model.UploadSettings = user.UploadSettings; |
|
|
|
model.Uploads = _dbContext.Uploads.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DateUploaded).ToList(); |
|
|
|
model.Pastes = _dbContext.Pastes.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DatePosted).ToList(); |
|
|
|
model.ShortenedUrls = _dbContext.ShortenedUrls.Where(s => s.UserId == user.UserId).OrderByDescending(s => s.DateAdded).ToList(); |
|
|
|
model.Vaults = _dbContext.Vaults.Where(v => v.UserId == user.UserId).OrderByDescending(v => v.DateCreated).ToList(); |
|
|
|
return View(model); |
|
} |
|
model.Error = true; |
|
model.ErrorMessage = "The user does not exist"; |
|
} |
|
catch (Exception ex) |
|
{ |
|
model.Error = true; |
|
model.ErrorMessage = ex.GetFullMessage(true); |
|
} |
|
return View(model); |
|
} |
|
|
|
public IActionResult ViewServiceData() |
|
{ |
|
string username = User.Identity.Name; |
|
|
|
ViewServiceDataViewModel model = new ViewServiceDataViewModel(); |
|
ViewBag.Title = "User Does Not Exist - " + _config.Title; |
|
ViewBag.Description = "The User does not exist"; |
|
|
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, username); |
|
|
|
if (user != null) |
|
{ |
|
ViewBag.Title = "Service Data - " + _config.Title; |
|
ViewBag.Description = "Viewing all of your service data"; |
|
|
|
model.Uploads = _dbContext.Uploads.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DateUploaded).ToList(); |
|
|
|
model.Pastes = _dbContext.Pastes.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DatePosted).ToList(); |
|
|
|
model.ShortenedUrls = _dbContext.ShortenedUrls.Where(s => s.UserId == user.UserId).OrderByDescending(s => s.DateAdded).ToList(); |
|
|
|
model.Vaults = _dbContext.Vaults.Where(v => v.UserId == user.UserId).OrderByDescending(v => v.DateCreated).ToList(); |
|
|
|
return View(model); |
|
} |
|
model.Error = true; |
|
model.ErrorMessage = "The user does not exist"; |
|
} |
|
catch (Exception ex) |
|
{ |
|
model.Error = true; |
|
model.ErrorMessage = ex.GetFullMessage(true); |
|
} |
|
return View(model); |
|
} |
|
|
|
public IActionResult Settings() |
|
{ |
|
return Redirect(Url.SubRouteUrl("user", "User.ProfileSettings")); |
|
} |
|
|
|
public IActionResult ProfileSettings() |
|
{ |
|
string username = User.Identity.Name; |
|
User user = UserHelper.GetUser(_dbContext, username); |
|
|
|
if (user != null) |
|
{ |
|
ViewBag.Title = "Profile Settings - " + _config.Title; |
|
ViewBag.Description = "Your " + _config.Title + " Profile Settings"; |
|
|
|
ProfileSettingsViewModel model = new ProfileSettingsViewModel(); |
|
model.Page = "Profile"; |
|
model.UserID = user.UserId; |
|
model.Username = user.Username; |
|
model.About = user.UserSettings.About; |
|
model.Quote = user.UserSettings.Quote; |
|
model.Website = user.UserSettings.Website; |
|
|
|
return View("/Areas/User/Views/User/Settings/ProfileSettings.cshtml", model); |
|
} |
|
|
|
return new StatusCodeResult(StatusCodes.Status403Forbidden); |
|
} |
|
|
|
public IActionResult AccountSettings() |
|
{ |
|
string username = User.Identity.Name; |
|
User user = UserHelper.GetUser(_dbContext, username); |
|
|
|
if (user != null) |
|
{ |
|
ViewBag.Title = "Account Settings - " + _config.Title; |
|
ViewBag.Description = "Your " + _config.Title + " Account Settings"; |
|
|
|
AccountSettingsViewModel model = new AccountSettingsViewModel(); |
|
model.Page = "Account"; |
|
model.UserID = user.UserId; |
|
model.Username = user.Username; |
|
|
|
return View("/Areas/User/Views/User/Settings/AccountSettings.cshtml", model); |
|
} |
|
|
|
return new StatusCodeResult(StatusCodes.Status403Forbidden); |
|
} |
|
|
|
public async Task<IActionResult> SecuritySettings() |
|
{ |
|
string username = User.Identity.Name; |
|
User user = UserHelper.GetUser(_dbContext, username); |
|
|
|
if (user != null) |
|
{ |
|
ViewBag.Title = "Security Settings - " + _config.Title; |
|
ViewBag.Description = "Your " + _config.Title + " Security Settings"; |
|
|
|
SecuritySettingsViewModel model = new SecuritySettingsViewModel(); |
|
model.Page = "Security"; |
|
model.UserID = user.UserId; |
|
model.Username = user.Username; |
|
|
|
// Get the user secure info |
|
IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, user.Username); |
|
//model.TrustedDeviceCount = user.TrustedDevices.Count; |
|
//model.AuthTokens = new List<AuthTokenViewModel>(); |
|
//foreach (AuthToken token in user.AuthTokens) |
|
//{ |
|
// AuthTokenViewModel tokenModel = new AuthTokenViewModel(); |
|
// tokenModel.AuthTokenId = token.AuthTokenId; |
|
// tokenModel.Name = token.Name; |
|
// tokenModel.LastDateUsed = token.LastDateUsed; |
|
|
|
// model.AuthTokens.Add(tokenModel); |
|
//} |
|
|
|
model.PgpPublicKey = userInfo.PGPPublicKey; |
|
model.RecoveryEmail = userInfo.RecoveryEmail; |
|
if (userInfo.RecoveryVerified.HasValue) |
|
model.RecoveryVerified = userInfo.RecoveryVerified.Value; |
|
if (userInfo.TwoFactorEnabled.HasValue) |
|
model.TwoFactorEnabled = userInfo.TwoFactorEnabled.Value; |
|
|
|
return View("/Areas/User/Views/User/Settings/SecuritySettings.cshtml", model); |
|
} |
|
|
|
return new StatusCodeResult(StatusCodes.Status403Forbidden); |
|
} |
|
|
|
public async Task<IActionResult> DeveloperSettings() |
|
{ |
|
string username = User.Identity.Name; |
|
User user = UserHelper.GetUser(_dbContext, username); |
|
|
|
if (user != null) |
|
{ |
|
ViewBag.Title = "Developer Settings - " + _config.Title; |
|
ViewBag.Description = "Your " + _config.Title + " Developer Settings"; |
|
|
|
DeveloperSettingsViewModel model = new DeveloperSettingsViewModel(); |
|
model.Page = "Developer"; |
|
model.UserID = user.UserId; |
|
model.Username = user.Username; |
|
|
|
model.AuthTokens = new List<AuthTokenViewModel>(); |
|
model.Clients = new List<ClientViewModel>(); |
|
//foreach (AuthToken token in user.AuthTokens) |
|
//{ |
|
// AuthTokenViewModel tokenModel = new AuthTokenViewModel(); |
|
// tokenModel.AuthTokenId = token.AuthTokenId; |
|
// tokenModel.Name = token.Name; |
|
// tokenModel.LastDateUsed = token.LastDateUsed; |
|
|
|
// model.AuthTokens.Add(tokenModel); |
|
//} |
|
|
|
Client[] clients = await IdentityHelper.GetClients(_config, username); |
|
foreach (Client client in clients) |
|
{ |
|
model.Clients.Add(new ClientViewModel() |
|
{ |
|
Id = client.ClientId, |
|
Name = client.ClientName, |
|
RedirectURI = string.Join(',', client.RedirectUris), |
|
PostLogoutRedirectURI = string.Join(',', client.PostLogoutRedirectUris), |
|
AllowedScopes = client.AllowedScopes |
|
}); |
|
} |
|
|
|
return View("/Areas/User/Views/User/Settings/DeveloperSettings.cshtml", model); |
|
} |
|
|
|
return new StatusCodeResult(StatusCodes.Status403Forbidden); |
|
} |
|
|
|
public IActionResult InviteSettings() |
|
{ |
|
string username = User.Identity.Name; |
|
User user = UserHelper.GetUser(_dbContext, username); |
|
|
|
if (user != null) |
|
{ |
|
ViewBag.Title = "Invite Settings - " + _config.Title; |
|
ViewBag.Description = "Your " + _config.Title + " Invite Settings"; |
|
|
|
InviteSettingsViewModel model = new InviteSettingsViewModel(); |
|
model.Page = "Invite"; |
|
model.UserID = user.UserId; |
|
model.Username = user.Username; |
|
|
|
List<InviteCodeViewModel> availableCodes = new List<InviteCodeViewModel>(); |
|
List<InviteCodeViewModel> claimedCodes = new List<InviteCodeViewModel>(); |
|
if (user.OwnedInviteCodes != null) |
|
{ |
|
foreach (InviteCode inviteCode in user.OwnedInviteCodes.Where(c => c.Active)) |
|
{ |
|
InviteCodeViewModel inviteCodeViewModel = new InviteCodeViewModel(); |
|
inviteCodeViewModel.ClaimedUser = inviteCode.ClaimedUser; |
|
inviteCodeViewModel.Active = inviteCode.Active; |
|
inviteCodeViewModel.Code = inviteCode.Code; |
|
inviteCodeViewModel.InviteCodeId = inviteCode.InviteCodeId; |
|
inviteCodeViewModel.Owner = inviteCode.Owner; |
|
|
|
if (inviteCode.ClaimedUser == null) |
|
availableCodes.Add(inviteCodeViewModel); |
|
|
|
if (inviteCode.ClaimedUser != null) |
|
claimedCodes.Add(inviteCodeViewModel); |
|
} |
|
} |
|
|
|
model.AvailableCodes = availableCodes; |
|
model.ClaimedCodes = claimedCodes; |
|
|
|
return View("/Areas/User/Views/User/Settings/InviteSettings.cshtml", model); |
|
} |
|
|
|
return new StatusCodeResult(StatusCodes.Status403Forbidden); |
|
} |
|
|
|
public IActionResult BlogSettings() |
|
{ |
|
string username = User.Identity.Name; |
|
User user = UserHelper.GetUser(_dbContext, username); |
|
|
|
if (user != null) |
|
{ |
|
ViewBag.Title = "Blog Settings - " + _config.Title; |
|
ViewBag.Description = "Your " + _config.Title + " Blog Settings"; |
|
|
|
BlogSettingsViewModel model = new BlogSettingsViewModel(); |
|
model.Page = "Blog"; |
|
model.UserID = user.UserId; |
|
model.Username = user.Username; |
|
model.Title = user.BlogSettings.Title; |
|
model.Description = user.BlogSettings.Description; |
|
|
|
return View("/Areas/User/Views/User/Settings/BlogSettings.cshtml", model); |
|
} |
|
|
|
return new StatusCodeResult(StatusCodes.Status403Forbidden); |
|
} |
|
|
|
public IActionResult UploadSettings() |
|
{ |
|
string username = User.Identity.Name; |
|
User user = UserHelper.GetUser(_dbContext, username); |
|
|
|
if (user != null) |
|
{ |
|
ViewBag.Title = "Upload Settings - " + _config.Title; |
|
ViewBag.Description = "Your " + _config.Title + " Upload Settings"; |
|
|
|
UploadSettingsViewModel model = new UploadSettingsViewModel(); |
|
model.Page = "Upload"; |
|
model.UserID = user.UserId; |
|
model.Username = user.Username; |
|
model.Encrypt = user.UploadSettings.Encrypt; |
|
|
|
return View("/Areas/User/Views/User/Settings/UploadSettings.cshtml", model); |
|
} |
|
|
|
return new StatusCodeResult(StatusCodes.Status403Forbidden); |
|
} |
|
|
|
[HttpGet] |
|
[AllowAnonymous] |
|
public async Task<IActionResult> ViewRawPGP(string username) |
|
{ |
|
ViewBag.Title = username + "'s Public Key - " + _config.Title; |
|
ViewBag.Description = "The PGP public key for " + username; |
|
|
|
IdentityUserInfo userClaims = await IdentityHelper.GetIdentityUserInfo(_config, username); |
|
if (!string.IsNullOrEmpty(userClaims.PGPPublicKey)) |
|
{ |
|
return Content(userClaims.PGPPublicKey, "text/plain"); |
|
} |
|
return new StatusCodeResult(StatusCodes.Status404NotFound); |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public IActionResult EditBlog(BlogSettingsViewModel settings) |
|
{ |
|
if (ModelState.IsValid) |
|
{ |
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
// Blogs |
|
user.BlogSettings.Title = settings.Title; |
|
user.BlogSettings.Description = settings.Description; |
|
|
|
UserHelper.EditAccount(_dbContext, _config, user); |
|
return Json(new { result = true }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
return Json(new { error = "Invalid Parameters" }); |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public IActionResult EditProfile(ProfileSettingsViewModel settings) |
|
{ |
|
if (ModelState.IsValid) |
|
{ |
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
// Profile Info |
|
user.UserSettings.Website = settings.Website; |
|
user.UserSettings.Quote = settings.Quote; |
|
user.UserSettings.About = settings.About; |
|
|
|
UserHelper.EditAccount(_dbContext, _config, user); |
|
return Json(new { result = true }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
return Json(new { error = "Invalid Parameters" }); |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> EditSecurity(SecuritySettingsViewModel settings) |
|
{ |
|
if (ModelState.IsValid) |
|
{ |
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
// PGP Key valid? |
|
if (!string.IsNullOrEmpty(settings.PgpPublicKey) && !PGP.IsPublicKey(settings.PgpPublicKey)) |
|
{ |
|
return Json(new { error = "Invalid PGP Public Key" }); |
|
} |
|
|
|
// Get the user secure info |
|
IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, user.Username); |
|
|
|
if (userInfo.PGPPublicKey != settings.PgpPublicKey) |
|
{ |
|
var result = await IdentityHelper.UpdatePGPPublicKey(_config, user.Username, settings.PgpPublicKey); |
|
if (!result.Success) |
|
return Json(new { error = result.Message }); |
|
} |
|
|
|
if (userInfo.RecoveryEmail != settings.RecoveryEmail) |
|
{ |
|
var token = await IdentityHelper.UpdateRecoveryEmail(_config, user.Username, settings.RecoveryEmail); |
|
|
|
// If they have a recovery email, let's send a verification |
|
if (!string.IsNullOrEmpty(settings.RecoveryEmail)) |
|
{ |
|
string resetUrl = Url.SubRouteUrl("user", "User.ResetPassword", new { Username = user.Username }); |
|
string verifyUrl = Url.SubRouteUrl("user", "User.VerifyRecoveryEmail", new { Username = user.Username, Code = WebUtility.UrlEncode(token) }); |
|
UserHelper.SendRecoveryEmailVerification(_config, user.Username, settings.RecoveryEmail, resetUrl, verifyUrl); |
|
} |
|
} |
|
|
|
//if (!settings.TwoFactorEnabled && (!userInfo.TwoFactorEnabled.HasValue || userInfo.TwoFactorEnabled.Value)) |
|
//{ |
|
// var result = await IdentityHelper.Disable2FA(_config, user.Username); |
|
// if (!result.Success) |
|
// return Json(new { error = result.Message }); |
|
//} |
|
|
|
//UserHelper.EditAccount(_dbContext, _config, user, changePass, settings.NewPassword); |
|
|
|
|
|
//if (!oldTwoFactor && settings.TwoFactorEnabled) |
|
//{ |
|
// return Json(new { result = new { checkAuth = true, key = newKey, qrUrl = Url.SubRouteUrl("user", "User.Action", new { action = "GenerateAuthQrCode", key = newKey }) } }); |
|
//} |
|
return Json(new { result = true }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
return Json(new { error = "Invalid Parameters" }); |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public IActionResult EditUpload(UploadSettingsViewModel settings) |
|
{ |
|
if (ModelState.IsValid) |
|
{ |
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
// Profile Info |
|
user.UploadSettings.Encrypt = settings.Encrypt; |
|
|
|
UserHelper.EditAccount(_dbContext, _config, user); |
|
return Json(new { result = true }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
return Json(new { error = "Invalid Parameters" }); |
|
} |
|
|
|
public async Task<IActionResult> ChangePassword(AccountSettingsViewModel settings) |
|
{ |
|
|
|
if (ModelState.IsValid) |
|
{ |
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
// Did they enter their old password |
|
if (string.IsNullOrEmpty(settings.CurrentPassword)) |
|
return Json(new { error = "You must enter your current password" }); |
|
// Did they enter a new password |
|
if (string.IsNullOrEmpty(settings.NewPassword) || string.IsNullOrEmpty(settings.NewPasswordConfirm)) |
|
return Json(new { error = "You must enter your new password" }); |
|
// Old Password Valid? |
|
if (!(await UserHelper.UserPasswordCorrect(_config, user.Username, settings.CurrentPassword))) |
|
return Json(new { error = "Invalid Original Password" }); |
|
// The New Password Match? |
|
if (settings.NewPassword != settings.NewPasswordConfirm) |
|
return Json(new { error = "New Password must match confirmation" }); |
|
// Are password resets enabled? |
|
if (!_config.UserConfig.PasswordResetEnabled) |
|
return Json(new { error = "Password resets are disabled" }); |
|
|
|
// Change their password |
|
await UserHelper.ChangeAccountPassword(_dbContext, _config, user.Username, settings.CurrentPassword, settings.NewPassword); |
|
|
|
return Json(new { result = true }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
return Json(new { error = "Invalid Parameters" }); |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> Delete() |
|
{ |
|
if (ModelState.IsValid) |
|
{ |
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
await UserHelper.DeleteAccount(_dbContext, _config, user); |
|
|
|
// Sign Out |
|
await HttpContext.SignOutAsync("Cookies"); |
|
await HttpContext.SignOutAsync("oidc"); |
|
|
|
return Json(new { result = true }); |
|
} |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
return Json(new { error = "Unable to delete user" }); |
|
} |
|
|
|
[HttpGet] |
|
public async Task<IActionResult> VerifyRecoveryEmail(string username, string code) |
|
{ |
|
bool verified = true; |
|
if (string.IsNullOrEmpty(code)) |
|
verified &= false; |
|
|
|
// Is there a code? |
|
if (verified) |
|
{ |
|
var result = await IdentityHelper.VerifyRecoveryEmail(_config, username, WebUtility.UrlDecode(code)); |
|
verified &= result.Success; |
|
} |
|
|
|
RecoveryEmailVerificationViewModel model = new RecoveryEmailVerificationViewModel(); |
|
model.Success = verified; |
|
|
|
return View("/Areas/User/Views/User/ViewRecoveryEmailVerification.cshtml", model); |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> ResendVerifyRecoveryEmail() |
|
{ |
|
if (ModelState.IsValid) |
|
{ |
|
try |
|
{ |
|
IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name); |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
//If they have a recovery email, let's send a verification |
|
if (!string.IsNullOrEmpty(userInfo.RecoveryEmail)) |
|
{ |
|
if (!userInfo.RecoveryVerified.HasValue || !userInfo.RecoveryVerified.Value) |
|
{ |
|
var token = await IdentityHelper.UpdateRecoveryEmail(_config, user.Username, userInfo.RecoveryEmail); |
|
string resetUrl = Url.SubRouteUrl("user", "User.ResetPassword", new { Username = user.Username }); |
|
string verifyUrl = Url.SubRouteUrl("user", "User.VerifyRecoveryEmail", new { Username = user.Username, Code = WebUtility.UrlEncode(token) }); |
|
UserHelper.SendRecoveryEmailVerification(_config, user.Username, userInfo.RecoveryEmail, resetUrl, verifyUrl); |
|
return Json(new { result = true }); |
|
} |
|
return Json(new { error = "The recovery email is already verified" }); |
|
} |
|
} |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
return Json(new { error = "Unable to resend verification" }); |
|
} |
|
|
|
[HttpGet] |
|
[AllowAnonymous] |
|
public IActionResult ResetPassword(string username) |
|
{ |
|
ResetPasswordViewModel model = new ResetPasswordViewModel(); |
|
model.Username = username; |
|
|
|
return View("/Areas/User/Views/User/ResetPassword.cshtml", model); |
|
} |
|
|
|
[HttpPost] |
|
[AllowAnonymous] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> SendResetPasswordVerification(string username) |
|
{ |
|
if (ModelState.IsValid) |
|
{ |
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, username); |
|
if (user != null) |
|
{ |
|
IdentityUserInfo userClaims = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name); |
|
// If they have a recovery email, let's send a verification |
|
if (!string.IsNullOrEmpty(userClaims.RecoveryEmail) && userClaims.RecoveryVerified.HasValue && userClaims.RecoveryVerified.Value) |
|
{ |
|
string verifyCode = await IdentityHelper.GeneratePasswordResetToken(_config, User.Identity.Name); |
|
string resetUrl = Url.SubRouteUrl("user", "User.VerifyResetPassword", new { Username = user.Username, Code = WebUtility.UrlEncode(verifyCode) }); |
|
UserHelper.SendResetPasswordVerification(_config, user.Username, userClaims.RecoveryEmail, resetUrl); |
|
return Json(new { result = true }); |
|
} |
|
return Json(new { error = "The user doesn't have a recovery email specified, or has not been verified." }); |
|
} |
|
return Json(new { error = "The username is not valid" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
return Json(new { error = "Unable to send reset link" }); |
|
} |
|
|
|
[HttpGet] |
|
[AllowAnonymous] |
|
public async Task<IActionResult> VerifyResetPassword(string username, string code) |
|
{ |
|
bool verified = true; |
|
if (string.IsNullOrEmpty(code)) |
|
verified &= false; |
|
|
|
// Is there a code? |
|
if (verified) |
|
{ |
|
// The password reset code is valid, let's get their user account for this session |
|
User user = UserHelper.GetUser(_dbContext, username); |
|
_session.SetString(_AuthSessionKey, user.Username); |
|
_session.SetString("AuthCode", WebUtility.UrlDecode(code)); |
|
|
|
await _session.CommitAsync(); |
|
} |
|
|
|
ResetPasswordVerificationViewModel model = new ResetPasswordVerificationViewModel(); |
|
model.Success = verified; |
|
|
|
return View("/Areas/User/Views/User/ResetPasswordVerification.cshtml", model); |
|
} |
|
|
|
[HttpPost] |
|
[AllowAnonymous] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> SetUserPassword(SetPasswordViewModel passwordViewModel) |
|
{ |
|
if (ModelState.IsValid) |
|
{ |
|
try |
|
{ |
|
await _session.LoadAsync(); |
|
string code = _session.GetString("AuthCode"); |
|
if (!string.IsNullOrEmpty(code)) |
|
{ |
|
string username = _session.GetString(_AuthSessionKey); |
|
if (!string.IsNullOrEmpty(username)) |
|
{ |
|
if (string.IsNullOrEmpty(passwordViewModel.Password)) |
|
{ |
|
return Json(new { error = "Password must not be empty" }); |
|
} |
|
if (passwordViewModel.Password != passwordViewModel.PasswordConfirm) |
|
{ |
|
return Json(new { error = "Passwords must match" }); |
|
} |
|
|
|
try |
|
{ |
|
await UserHelper.ResetAccountPassword(_dbContext, _config, username, code, passwordViewModel.Password); |
|
|
|
_session.Remove(_AuthSessionKey); |
|
_session.Remove("AuthCode"); |
|
|
|
return Json(new { result = true }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.Message }); |
|
} |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
return Json(new { error = "Invalid Code" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
return Json(new { error = "Unable to reset user password" }); |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> Generate2FA() |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
// Get User Identity Info |
|
var userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name); |
|
if (userInfo.TwoFactorEnabled.HasValue && !userInfo.TwoFactorEnabled.Value) |
|
{ |
|
// Validate the code with the identity server |
|
var key = await IdentityHelper.Reset2FAKey(_config, user.Username); |
|
|
|
if (!string.IsNullOrEmpty(key)) |
|
{ |
|
return Json(new { result = true, key = key, qrUrl = Url.SubRouteUrl("user", "User.Action", new { action = "GenerateAuthQrCode", key = key }) }); |
|
} |
|
return Json(new { error = "Unable to generate Two Factor Authentication key" }); |
|
} |
|
return Json(new { error = "User already has Two Factor Authentication enabled" }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> VerifyAuthenticatorCode(string code) |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
// Get User Identity Info |
|
var userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name); |
|
if (userInfo.TwoFactorEnabled.HasValue && !userInfo.TwoFactorEnabled.Value) |
|
{ |
|
// Validate the code with the identity server |
|
var result = await IdentityHelper.Enable2FA(_config, user.Username, code); |
|
|
|
if (result.Any()) |
|
{ |
|
return Json(new { result = true, recoveryCodes = result }); |
|
} |
|
return Json(new { error = "Invalid Authentication Code" }); |
|
} |
|
return Json(new { error = "User already has Two Factor Authentication enabled" }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> ResetRecoveryCodes() |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
// Get User Identity Info |
|
var userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name); |
|
if (userInfo.TwoFactorEnabled.HasValue && userInfo.TwoFactorEnabled.Value) |
|
{ |
|
// Regenerate the recovery codes |
|
var result = await IdentityHelper.GenerateRecoveryCodes(_config, user.Username); |
|
|
|
if (result.Any()) |
|
{ |
|
return Json(new { result = true, recoveryCodes = result }); |
|
} |
|
return Json(new { error = "Invalid Authentication Code" }); |
|
} |
|
return Json(new { error = "User doesn't have Two Factor Authentication enabled" }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> Disable2FA() |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
// Get User Identity Info |
|
var userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name); |
|
if (userInfo.TwoFactorEnabled.HasValue && userInfo.TwoFactorEnabled.Value) |
|
{ |
|
// Validate the code with the identity server |
|
var result = await IdentityHelper.Disable2FA(_config, user.Username); |
|
|
|
if (result.Success) |
|
{ |
|
return Json(new { result = true }); |
|
} |
|
return Json(new { error = result.Message }); |
|
} |
|
return Json(new { error = "User doesn't have Two Factor Authentication enabled" }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
|
|
[HttpGet] |
|
public IActionResult GenerateAuthQrCode(string key) |
|
{ |
|
var ProvisionUrl = string.Format("otpauth://totp/{0}:{1}?secret={2}", _config.Title, User.Identity.Name, key); |
|
|
|
QRCodeGenerator qrGenerator = new QRCodeGenerator(); |
|
QRCodeData qrCodeData = qrGenerator.CreateQrCode(ProvisionUrl, QRCodeGenerator.ECCLevel.Q); |
|
PngByteQRCode qrCode = new PngByteQRCode(qrCodeData); |
|
return File(qrCode.GetGraphic(20), "image/png"); |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public IActionResult ClearTrustedDevices() |
|
{ |
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
//if (user.SecuritySettings.AllowTrustedDevices) |
|
//{ |
|
// // let's clear the trusted devices |
|
// user.TrustedDevices.Clear(); |
|
// List<TrustedDevice> foundDevices = _dbContext.TrustedDevices.Where(d => d.UserId == user.UserId).ToList(); |
|
// if (foundDevices != null) |
|
// { |
|
// foreach (TrustedDevice device in foundDevices) |
|
// { |
|
// _dbContext.TrustedDevices.Remove(device); |
|
// } |
|
// } |
|
// _dbContext.Entry(user).State = EntityState.Modified; |
|
// _dbContext.SaveChanges(); |
|
|
|
// return Json(new { result = true }); |
|
//} |
|
return Json(new { error = "User does not allow trusted devices" }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> GenerateToken(string name, [FromServices] ICompositeViewEngine viewEngine) |
|
{ |
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
//string newTokenStr = UserHelper.GenerateAuthToken(_dbContext, user.Username); |
|
|
|
//if (!string.IsNullOrEmpty(newTokenStr)) |
|
//{ |
|
// AuthToken token = new AuthToken(); |
|
// token.UserId = user.UserId; |
|
// token.HashedToken = SHA256.Hash(newTokenStr); |
|
// token.Name = name; |
|
|
|
// _dbContext.AuthTokens.Add(token); |
|
// _dbContext.SaveChanges(); |
|
|
|
// AuthTokenViewModel model = new AuthTokenViewModel(); |
|
// model.AuthTokenId = token.AuthTokenId; |
|
// model.Name = token.Name; |
|
// model.LastDateUsed = token.LastDateUsed; |
|
|
|
// string renderedView = await RenderPartialViewToString(viewEngine, "~/Areas/User/Views/User/Settings/AuthToken.cshtml", model); |
|
|
|
// return Json(new { result = new { token = newTokenStr, html = renderedView } }); |
|
//} |
|
return Json(new { error = "Unable to generate Auth Token" }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public IActionResult RevokeAllTokens() |
|
{ |
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
//user.AuthTokens.Clear(); |
|
//List<AuthToken> foundTokens = _dbContext.AuthTokens.Where(d => d.UserId == user.UserId).ToList(); |
|
//if (foundTokens != null) |
|
//{ |
|
// foreach (AuthToken token in foundTokens) |
|
// { |
|
// _dbContext.AuthTokens.Remove(token); |
|
// } |
|
//} |
|
_dbContext.Entry(user).State = EntityState.Modified; |
|
_dbContext.SaveChanges(); |
|
|
|
return Json(new { result = true }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public IActionResult EditTokenName(int tokenId, string name) |
|
{ |
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
//AuthToken foundToken = _dbContext.AuthTokens.Where(d => d.UserId == user.UserId && d.AuthTokenId == tokenId).FirstOrDefault(); |
|
//if (foundToken != null) |
|
//{ |
|
// foundToken.Name = name; |
|
// _dbContext.Entry(foundToken).State = EntityState.Modified; |
|
// _dbContext.SaveChanges(); |
|
|
|
// return Json(new { result = new { name = name } }); |
|
//} |
|
return Json(new { error = "Authentication Token does not exist" }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public IActionResult DeleteToken(int tokenId) |
|
{ |
|
try |
|
{ |
|
User user = UserHelper.GetUser(_dbContext, User.Identity.Name); |
|
if (user != null) |
|
{ |
|
//AuthToken foundToken = _dbContext.AuthTokens.Where(d => d.UserId == user.UserId && d.AuthTokenId == tokenId).FirstOrDefault(); |
|
//if (foundToken != null) |
|
//{ |
|
// _dbContext.AuthTokens.Remove(foundToken); |
|
// user.AuthTokens.Remove(foundToken); |
|
// _dbContext.Entry(user).State = EntityState.Modified; |
|
// _dbContext.SaveChanges(); |
|
|
|
// return Json(new { result = true }); |
|
//} |
|
return Json(new { error = "Authentication Token does not exist" }); |
|
} |
|
return Json(new { error = "User does not exist" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> CreateClient(string name, string redirectUri, string logoutUri, [FromServices] ICompositeViewEngine viewEngine) |
|
{ |
|
try |
|
{ |
|
// Validate the code with the identity server |
|
var result = await IdentityHelper.CreateClient(_config, User.Identity.Name, name, redirectUri, logoutUri, "openid", "teknik-api.read", "teknik-api.write"); |
|
|
|
if (result.Success) |
|
{ |
|
var client = (JObject)result.Data; |
|
|
|
ClientViewModel model = new ClientViewModel(); |
|
model.Id = client["id"].ToString(); |
|
model.Name = name; |
|
model.RedirectURI = redirectUri; |
|
model.PostLogoutRedirectURI = logoutUri; |
|
|
|
string renderedView = await RenderPartialViewToString(viewEngine, "~/Areas/User/Views/User/Settings/ClientView.cshtml", model); |
|
|
|
return Json(new { result = true, clientId = client["id"], secret = client["secret"], html = renderedView }); |
|
} |
|
return Json(new { error = result.Message }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public async Task<IActionResult> DeleteClient(string clientId) |
|
{ |
|
try |
|
{ |
|
// Validate the code with the identity server |
|
var result = await IdentityHelper.DeleteClient(_config, clientId); |
|
|
|
if (result.Success) |
|
{ |
|
return Json(new { result = true }); |
|
} |
|
return Json(new { error = result.Message }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
|
|
[HttpPost] |
|
[ValidateAntiForgeryToken] |
|
public IActionResult CreateInviteCodeLink(int inviteCodeId) |
|
{ |
|
try |
|
{ |
|
InviteCode code = _dbContext.InviteCodes.Where(c => c.InviteCodeId == inviteCodeId).FirstOrDefault(); |
|
if (code != null) |
|
{ |
|
if (User.Identity.IsAuthenticated) |
|
{ |
|
if (code.Owner.Username == User.Identity.Name) |
|
{ |
|
return Json(new { result = Url.SubRouteUrl("user", "User.Register", new { inviteCode = code.Code }) }); |
|
} |
|
} |
|
return Json(new { error = "Invite Code not associated with this user" }); |
|
} |
|
return Json(new { error = "Invalid Invite Code" }); |
|
} |
|
catch (Exception ex) |
|
{ |
|
return Json(new { error = ex.GetFullMessage(true) }); |
|
} |
|
} |
|
} |
|
}
|
|
|