From 526c2364b9ad685d1c000fc8a168bf1305aaa8b7 Mon Sep 17 00:00:00 2001 From: vman Date: Fri, 18 Nov 2022 16:08:51 -0500 Subject: Add project files. --- .../Endpoints/ProfileEndpoint.cs | 108 +++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 VNLib.Plugins.Essentials.Accounts/Endpoints/ProfileEndpoint.cs (limited to 'VNLib.Plugins.Essentials.Accounts/Endpoints/ProfileEndpoint.cs') diff --git a/VNLib.Plugins.Essentials.Accounts/Endpoints/ProfileEndpoint.cs b/VNLib.Plugins.Essentials.Accounts/Endpoints/ProfileEndpoint.cs new file mode 100644 index 0000000..c0d86b6 --- /dev/null +++ b/VNLib.Plugins.Essentials.Accounts/Endpoints/ProfileEndpoint.cs @@ -0,0 +1,108 @@ +using System; +using System.Net; +using System.Text.Json; +using System.Threading.Tasks; +using System.Collections.Generic; + +using VNLib.Utils.Logging; +using VNLib.Plugins.Essentials.Users; +using VNLib.Plugins.Essentials.Endpoints; +using VNLib.Plugins.Essentials.Extensions; +using VNLib.Plugins.Extensions.Validation; +using VNLib.Plugins.Extensions.Loading; +using VNLib.Plugins.Extensions.Loading.Users; +using static VNLib.Plugins.Essentials.Statics; + + +namespace VNLib.Plugins.Essentials.Accounts.Endpoints +{ + /// + /// Provides an http endpoint for user account profile access + /// + [ConfigurationName("profile_endpoint")] + internal sealed class ProfileEndpoint : ProtectedWebEndpoint + { + private readonly IUserManager Users; + + public ProfileEndpoint(PluginBase pbase, IReadOnlyDictionary config) + { + string? path = config["path"].GetString(); + + InitPathAndLog(path, pbase.Log); + //Store user system + Users = pbase.GetUserManager(); + } + + protected override async ValueTask GetAsync(HttpEntity entity) + { + //get user data from database + using IUser? user = await Users.GetUserFromIDAsync(entity.Session.UserID); + //Make sure the account exists + if (user == null || user.Status != UserStatus.Active) + { + //Account was not found + entity.CloseResponse(HttpStatusCode.NotFound); + return VfReturnType.VirtualSkip; + } + //Get the stored profile + AccountData? profile = user.GetProfile(); + //No profile found, so return an empty "profile" + profile ??= new() + { + //set email address + EmailAddress = user.EmailAddress, + //created time in rfc1123 gmt time + Created = user.Created.ToString("R") + }; + //Serialize the profile and return to user + entity.CloseResponseJson(HttpStatusCode.OK, profile); + return VfReturnType.VirtualSkip; + } + protected override async ValueTask PostAsync(HttpEntity entity) + { + ValErrWebMessage webm = new(); + try + { + //Recover the update message form the client + AccountData? updateMessage = await entity.GetJsonFromFileAsync(SR_OPTIONS); + if (webm.Assert(updateMessage != null, "Malformatted payload")) + { + entity.CloseResponseJson(HttpStatusCode.BadRequest, webm); + return VfReturnType.VirtualSkip; + } + //Validate the new account data + if (!AccountValidations.AccountDataValidator.Validate(updateMessage, webm)) + { + entity.CloseResponseJson(HttpStatusCode.UnprocessableEntity, webm); + return VfReturnType.VirtualSkip; + } + //Get the user from database + using IUser? user = await Users.GetUserFromIDAsync(entity.Session.UserID); + //Make sure the user exists + if (webm.Assert(user != null, "Account does not exist")) + { + //Should probably log the user out here + entity.CloseResponseJson(HttpStatusCode.NotFound, webm); + return VfReturnType.VirtualSkip; + } + //Overwite the current profile data (will also sanitize inputs) + user.SetProfile(updateMessage); + //Update the user only if successful + await user.ReleaseAsync(); + webm.Result = "Successfully updated account"; + webm.Success = true; + entity.CloseResponse(webm); + return VfReturnType.VirtualSkip; + } + //Catch an account update exception + catch (UserUpdateException uue) + { + Log.Error(uue, "An error occured while the user account is being updated"); + //Return message to client + webm.Result = "An error occured while updating your account, try again later"; + entity.CloseResponseJson(HttpStatusCode.InternalServerError, webm); + return VfReturnType.VirtualSkip; + } + } + } +} \ No newline at end of file -- cgit