diff options
author | vman <public@vaughnnugent.com> | 2022-11-18 16:08:51 -0500 |
---|---|---|
committer | vman <public@vaughnnugent.com> | 2022-11-18 16:08:51 -0500 |
commit | 526c2364b9ad685d1c000fc8a168bf1305aaa8b7 (patch) | |
tree | a2bc01607320a6a75e1a869d5bd34e79fd63c595 /VNLib.Plugins.Essentials.Accounts.Admin | |
parent | 2080400119be00bdc354f3121d84ec2f89606ac7 (diff) |
Add project files.
Diffstat (limited to 'VNLib.Plugins.Essentials.Accounts.Admin')
7 files changed, 294 insertions, 0 deletions
diff --git a/VNLib.Plugins.Essentials.Accounts.Admin/AccountAdminEntry.cs b/VNLib.Plugins.Essentials.Accounts.Admin/AccountAdminEntry.cs new file mode 100644 index 0000000..008307c --- /dev/null +++ b/VNLib.Plugins.Essentials.Accounts.Admin/AccountAdminEntry.cs @@ -0,0 +1,67 @@ +using System; +using System.Text.Json; +using System.Runtime.CompilerServices; + +using VNLib.Utils.Logging; +using VNLib.Plugins.Essentials.Sessions; + +namespace VNLib.Plugins.Essentials.Accounts.Admin +{ + + internal static class Constants + { + public const ushort ADMIN_GROUP_ID = 0x1fff; + [Flags] + enum AdminLevelMask + { + + } + /// <summary> + /// Determines if the current session belongs to an admin account + /// </summary> + /// <param name="session"></param> + /// <returns>True if the current user has administrator permissions</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsAdmin(this in SessionInfo session) => session.HasGroup(ADMIN_GROUP_ID); + + /// <summary> + /// Gets the plugin config local-only flag + /// </summary> + /// <param name="plugin"></param> + /// <returns>True if the config demands all requests happen on the local network only</returns> + public static bool LocalOnlyEnabled(this PluginBase plugin) + { + return plugin.PluginConfig.TryGetProperty("local_only", out JsonElement el) && el.GetBoolean(); + } + } + + public sealed class AccountAdminEntry : PluginBase + { + public override string PluginName => "Essentials.Admin"; + + protected override void OnLoad() + { + try + { + + } + catch (KeyNotFoundException knf) + { + Log.Error("Missing required account configuration variables {mess}", knf.Message); + return; + } + //Write loaded to log + Log.Information("Plugin loaded"); + } + + protected override void OnUnLoad() + { + Log.Information("Plugin unloaded"); + } + + protected override void ProcessHostCommand(string cmd) + { + Log.Debug(cmd); + } + } +}
\ No newline at end of file diff --git a/VNLib.Plugins.Essentials.Accounts.Admin/Endpoints/UsersEndpoint.cs b/VNLib.Plugins.Essentials.Accounts.Admin/Endpoints/UsersEndpoint.cs new file mode 100644 index 0000000..9f29a29 --- /dev/null +++ b/VNLib.Plugins.Essentials.Accounts.Admin/Endpoints/UsersEndpoint.cs @@ -0,0 +1,77 @@ +using System; +using System.Linq; +using System.Net; +using System.Text.Json; + +using VNLib.Utils; +using VNLib.Plugins.Essentials.Users; +using VNLib.Plugins.Essentials.Extensions; +using VNLib.Plugins.Essentials.Accounts.Admin.Model; +using VNLib.Plugins.Extensions.Data; +using VNLib.Plugins.Extensions.Loading.Sql; +using VNLib.Plugins.Extensions.Loading.Users; +using VNLib.Plugins.Essentials.Accounts.Admin.Helpers; +using VNLib.Plugins.Extensions.Loading; + +namespace VNLib.Plugins.Essentials.Accounts.Admin.Endpoints +{ + [ConfigurationName("users")] + internal class UsersEndpoint : LocalNetworkProtectedEndpoint + { + + readonly IUserManager Manager; + readonly UserStore UserStore; + + public UsersEndpoint(PluginBase plugin, Dictionary<string, JsonElement> config) + { + this.LocalOnly = plugin.LocalOnlyEnabled(); + string? path = config["path"].GetString(); + //Store user-manager + Manager = plugin.GetUserManager(); + //Create the indirect user context store + UserStore = new(plugin.GetContextOptions()); + + InitPathAndLog(path, plugin.Log); + } + + + protected override ERRNO PreProccess(HttpEntity entity) + { + return base.PreProccess(entity) && entity.Session.IsAdmin(); + } + + protected override async ValueTask<VfReturnType> GetAsync(HttpEntity entity) + { + //Get single account + if(entity.QueryArgs.TryGetNonEmptyValue("id", out string? userId)) + { + //Load account + using IUser? user = await Manager.GetUserFromIDAsync(userId); + AccountData? acc = user?.GetProfile(); + //If account not found, return 404 + if(acc == null) + { + entity.CloseResponse(HttpStatusCode.NotFound); + } + else + { + entity.CloseResponseJson(HttpStatusCode.OK, acc); + } + } + else + { + //Get a user page + int page = entity.QueryArgs.GetPageOrDefault(0); + int limit = entity.QueryArgs.GetLimitOrDefault(50, 0, 200); + //Rent list and get the requested page + List<User> rental = UserStore.ListRental.Rent(); + _ = await UserStore.GetPageAsync(rental, page, limit); + //Set response + entity.CloseResponseJson(HttpStatusCode.OK, rental); + //Return list to store + UserStore.ListRental.Return(rental); + } + return VfReturnType.VirtualSkip; + } + } +} diff --git a/VNLib.Plugins.Essentials.Accounts.Admin/Helpers/LocalNetworkProtectedEndpoint.cs b/VNLib.Plugins.Essentials.Accounts.Admin/Helpers/LocalNetworkProtectedEndpoint.cs new file mode 100644 index 0000000..3812337 --- /dev/null +++ b/VNLib.Plugins.Essentials.Accounts.Admin/Helpers/LocalNetworkProtectedEndpoint.cs @@ -0,0 +1,30 @@ +using System; + +using VNLib.Utils; +using VNLib.Plugins.Essentials.Endpoints; + +namespace VNLib.Plugins.Essentials.Accounts.Admin.Helpers +{ + /// <summary> + /// Provides an endpoint that provides optional protection against requests outside the local network + /// </summary> + internal abstract class LocalNetworkProtectedEndpoint : ProtectedWebEndpoint + { + private bool _localOnly; + + /// <summary> + /// Specifies if requests outside of the local network are allowed. + /// </summary> + protected bool LocalOnly + { + get => _localOnly; + set => _localOnly = value; + } + + protected override ERRNO PreProccess(HttpEntity entity) + { + return (!_localOnly || entity.IsLocalConnection) && base.PreProccess(entity); + } + + } +} diff --git a/VNLib.Plugins.Essentials.Accounts.Admin/Model/User.cs b/VNLib.Plugins.Essentials.Accounts.Admin/Model/User.cs new file mode 100644 index 0000000..866cff1 --- /dev/null +++ b/VNLib.Plugins.Essentials.Accounts.Admin/Model/User.cs @@ -0,0 +1,26 @@ +using System; +using System.ComponentModel.DataAnnotations.Schema; + +using VNLib.Plugins.Extensions.Data; +using VNLib.Plugins.Extensions.Data.Abstractions; + +namespace VNLib.Plugins.Essentials.Accounts.Admin.Model +{ + internal class User : DbModelBase, IUserEntity + { + public string? UserId { get; set; } + //Users's do not have unique id values + [NotMapped] + public override string Id + { + get => UserId!; + set => UserId = value; + } + public override DateTime Created { get; set; } + //Do not map the last modified, user table does not have a last modified field. + [NotMapped] + public override DateTime LastModified { get; set; } + + public ulong Privilages { get; set; } + } +} diff --git a/VNLib.Plugins.Essentials.Accounts.Admin/Model/UserContext.cs b/VNLib.Plugins.Essentials.Accounts.Admin/Model/UserContext.cs new file mode 100644 index 0000000..6409b7d --- /dev/null +++ b/VNLib.Plugins.Essentials.Accounts.Admin/Model/UserContext.cs @@ -0,0 +1,17 @@ + +using Microsoft.EntityFrameworkCore; + +using VNLib.Plugins.Extensions.Data; + +namespace VNLib.Plugins.Essentials.Accounts.Admin.Model +{ + internal class UserContext : TransactionalDbContext + { + public DbSet<User> Users { get; set; } +#nullable disable + public UserContext(DbContextOptions options):base(options) + { + + } + } +} diff --git a/VNLib.Plugins.Essentials.Accounts.Admin/Model/UserStore.cs b/VNLib.Plugins.Essentials.Accounts.Admin/Model/UserStore.cs new file mode 100644 index 0000000..b3e5c23 --- /dev/null +++ b/VNLib.Plugins.Essentials.Accounts.Admin/Model/UserStore.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Microsoft.EntityFrameworkCore; + +using VNLib.Plugins.Extensions.Data; + +namespace VNLib.Plugins.Essentials.Accounts.Admin.Model +{ + + internal class UserStore : DbStore<User> + { + private readonly DbContextOptions Options; + + public UserStore(DbContextOptions options) + { + this.Options = options; + } + + //Item id's are not used + public override string RecordIdBuilder => ""; + + protected override IQueryable<User> GetCollectionQueryBuilder(TransactionalDbContext context, params string[] constraints) + { + return (from user in context.Set<User>() + orderby user.Created descending + select user); + } + + protected override IQueryable<User> GetSingleQueryBuilder(TransactionalDbContext context, params string[] constraints) + { + string userId = constraints[0]; + return (from user in context.Set<User>() + where user.UserId == userId + select user); + } + + public override TransactionalDbContext NewContext() => new UserContext(Options); + + protected override void OnRecordUpdate(User newRecord, User currentRecord) + { + currentRecord.Privilages = currentRecord.Privilages; + } + } +} diff --git a/VNLib.Plugins.Essentials.Accounts.Admin/VNLib.Plugins.Essentials.Accounts.Admin.csproj b/VNLib.Plugins.Essentials.Accounts.Admin/VNLib.Plugins.Essentials.Accounts.Admin.csproj new file mode 100644 index 0000000..6dbd219 --- /dev/null +++ b/VNLib.Plugins.Essentials.Accounts.Admin/VNLib.Plugins.Essentials.Accounts.Admin.csproj @@ -0,0 +1,29 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>net6.0</TargetFramework> + <ImplicitUsings>enable</ImplicitUsings> + <Nullable>enable</Nullable> + <PlatformTarget>x64</PlatformTarget> + <Platforms>AnyCPU;x64</Platforms> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="ErrorProne.NET.CoreAnalyzers" Version="0.1.2"> + <PrivateAssets>all</PrivateAssets> + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> + </PackageReference> + <PackageReference Include="ErrorProne.NET.Structs" Version="0.1.2"> + <PrivateAssets>all</PrivateAssets> + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> + </PackageReference> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\..\..\VNLib\Essentials\VNLib.Plugins.Essentials.csproj" /> + <ProjectReference Include="..\..\Extensions\VNLib.Plugins.Extensions.Data\VNLib.Plugins.Extensions.Data.csproj" /> + <ProjectReference Include="..\..\Extensions\VNLib.Plugins.Extensions.Loading.Sql\VNLib.Plugins.Extensions.Loading.Sql.csproj" /> + <ProjectReference Include="..\..\PluginBase\VNLib.Plugins.PluginBase.csproj" /> + </ItemGroup> + +</Project> |