From 9571222f828e63d8b2eb694cd491ea6f5b636484 Mon Sep 17 00:00:00 2001 From: vnugent Date: Wed, 14 Feb 2024 14:27:43 -0500 Subject: Squashed commit of the following: commit 850a60e02bd083a797ffb5f48229fab502e8aede Author: vnugent Date: Mon Feb 12 20:27:53 2024 -0500 refactor: integrate the latest sql library updates commit c70a61bc1bf683c2097e3a2481d9dfb9adbd31ea Author: vnugent Date: Sun Feb 4 01:30:25 2024 -0500 submit pending changes --- .../src/Applications/ApplicationStore.cs | 36 ++++++++++++---------- .../src/Applications/UserAppContext.cs | 4 +-- .../src/Tokens/TokenStore.cs | 20 ++---------- .../src/Endpoints/ApplicationEndpoint.cs | 4 +-- 4 files changed, 27 insertions(+), 37 deletions(-) diff --git a/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/ApplicationStore.cs b/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/ApplicationStore.cs index 17db978..92ced51 100644 --- a/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/ApplicationStore.cs +++ b/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/ApplicationStore.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Plugins.Essentials.Oauth @@ -72,7 +72,11 @@ namespace VNLib.Plugins.Essentials.Oauth.Applications /// Generates a client application secret using the library /// /// The RNG secret - public static PrivateString GenerateSecret(int secretSize = SECRET_SIZE) => (PrivateString)RandomHash.GetRandomHex(secretSize).ToLower(null)!; + public static PrivateString GenerateSecret(int secretSize = SECRET_SIZE) + { + string secret = RandomHash.GetRandomHex(secretSize).ToLower(null)!; + return PrivateString.ToPrivateString(secret, true); + } /// public override IDbContextHandle GetNewContext() => new UserAppContext(ConextOptions); @@ -93,7 +97,7 @@ namespace VNLib.Plugins.Essentials.Oauth.Applications /// The user-id of that owns the application /// The id of the application to update /// A task that resolves to the raw secret that was used to generate the hash, or null if the operation failed - public async Task UpdateSecretAsync(string userId, string appId) + public async Task UpdateSecretAsync(string userId, string appId, CancellationToken cancellation) { /* * Delete open apps first, incase there are any issues, worse case @@ -103,33 +107,34 @@ namespace VNLib.Plugins.Essentials.Oauth.Applications * secret and may lose access to the updated app, not a big deal * but avoidable. */ - await TokenStore.RevokeTokensForAppAsync(appId, CancellationToken.None); + await TokenStore.RevokeTokensForAppAsync(appId, cancellation); + //Generate the new secret PrivateString secret = GenerateSecret(); //Hash the secret using PrivateString secretHash = SecretHashing.Hash(secret); //Open new db context await using UserAppContext Database = new(ConextOptions); - //Open transaction - await Database.OpenTransactionAsync(); + //Get the app to update the secret on UserApplication? app = await (from ap in Database.OAuthApps where ap.UserId == userId && ap.Id == appId select ap) - .SingleOrDefaultAsync(); - if (app == null) + .SingleOrDefaultAsync(cancellation); + if (app is null) { return null; } + //Store the new secret hash app.SecretHash = (string)secretHash; + //Save changes - if (await Database.SaveChangesAsync() <= 0) + if (await Database.SaveAndCloseAsync(true, cancellation) <= 0) { return null; } - //Commit transaction - await Database.CommitTransactionAsync(); + //return the raw secret return secret; } @@ -141,22 +146,21 @@ namespace VNLib.Plugins.Essentials.Oauth.Applications /// The clientid of the application to search /// The secret to compare against /// True if the application was found and the secret matches the stored secret, false if the appliation was not found or the secret does not match - public async Task VerifyAppAsync(string clientId, PrivateString secret) + public async Task VerifyAppAsync(string clientId, PrivateString secret, CancellationToken cancellation) { UserApplication? app; //Open new db context await using (UserAppContext Database = new(ConextOptions)) { - //Open transaction - await Database.OpenTransactionAsync(); //Get the application with its secret app = await (from userApp in Database.OAuthApps where userApp.ClientId == clientId select userApp) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellation); + //commit the transaction - await Database.CommitTransactionAsync(); + await Database.SaveAndCloseAsync(true, cancellation); } //make sure app exists diff --git a/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/UserAppContext.cs b/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/UserAppContext.cs index e4d98e6..cc38800 100644 --- a/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/UserAppContext.cs +++ b/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/UserAppContext.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Plugins.Essentials.Oauth @@ -29,7 +29,7 @@ using VNLib.Plugins.Essentials.Oauth.Tokens; namespace VNLib.Plugins.Essentials.Oauth.Applications { - public class UserAppContext : TransactionalDbContext + public class UserAppContext : DBContextBase { public DbSet OAuthApps { get; set; } diff --git a/Libs/VNLib.Plugins.Essentials.Oauth/src/Tokens/TokenStore.cs b/Libs/VNLib.Plugins.Essentials.Oauth/src/Tokens/TokenStore.cs index 7b07f46..56283c6 100644 --- a/Libs/VNLib.Plugins.Essentials.Oauth/src/Tokens/TokenStore.cs +++ b/Libs/VNLib.Plugins.Essentials.Oauth/src/Tokens/TokenStore.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Plugins.Essentials.Oauth @@ -40,17 +40,8 @@ namespace VNLib.Plugins.Essentials.Oauth.Tokens /// that allows for communicating token information to /// plugins /// - public sealed class TokenStore : ITokenManager + public sealed class TokenStore(DbContextOptions Options) : ITokenManager { - private readonly DbContextOptions Options; - - /// - /// Initializes a new that will make quries against - /// the supplied - /// - /// The DB connection context - public TokenStore(DbContextOptions options) => Options = options; - /// /// Inserts a new token into the table for a specified application id. Also determines if /// the user has reached the maximum number of allowed tokens @@ -68,7 +59,6 @@ namespace VNLib.Plugins.Essentials.Oauth.Tokens public async Task InsertTokenAsync(string token, string appId, string? refreshToken, int maxTokens, CancellationToken cancellation) { await using UserAppContext ctx = new (Options); - await ctx.OpenTransactionAsync(cancellation); //Check active token count int count = await (from t in ctx.OAuthTokens @@ -108,13 +98,12 @@ namespace VNLib.Plugins.Essentials.Oauth.Tokens public async Task RevokeTokenAsync(string token, CancellationToken cancellation) { await using UserAppContext ctx = new (Options); - await ctx.OpenTransactionAsync(cancellation); //Get the token from the db if it exists ActiveToken? at = await (from t in ctx.OAuthTokens where t.Id == token select t) .FirstOrDefaultAsync(cancellation); - if(at == null) + if(at is null) { return; } @@ -133,7 +122,6 @@ namespace VNLib.Plugins.Essentials.Oauth.Tokens public async Task> CleanupExpiredTokensAsync(DateTime validAfter, CancellationToken cancellation) { await using UserAppContext ctx = new (Options); - await ctx.OpenTransactionAsync(cancellation); //Get the token from the db if it exists ActiveToken[] at = await (from t in ctx.OAuthTokens where t.Created < validAfter @@ -151,7 +139,6 @@ namespace VNLib.Plugins.Essentials.Oauth.Tokens public async Task RevokeTokensAsync(IReadOnlyCollection tokens, CancellationToken cancellation = default) { await using UserAppContext ctx = new (Options); - await ctx.OpenTransactionAsync(cancellation); //Get all tokenes that are contained in the collection ActiveToken[] at = await (from t in ctx.OAuthTokens where tokens.Contains(t.Id) @@ -168,7 +155,6 @@ namespace VNLib.Plugins.Essentials.Oauth.Tokens async Task ITokenManager.RevokeTokensForAppAsync(string appId, CancellationToken cancellation) { await using UserAppContext ctx = new (Options); - await ctx.OpenTransactionAsync(cancellation); //Get the token from the db if it exists ActiveToken[] at = await (from t in ctx.OAuthTokens where t.ApplicationId == appId diff --git a/Plugins/OAuth2ClientApplications/src/Endpoints/ApplicationEndpoint.cs b/Plugins/OAuth2ClientApplications/src/Endpoints/ApplicationEndpoint.cs index 4b770ca..ddc83c8 100644 --- a/Plugins/OAuth2ClientApplications/src/Endpoints/ApplicationEndpoint.cs +++ b/Plugins/OAuth2ClientApplications/src/Endpoints/ApplicationEndpoint.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: OAuth2ClientApplications @@ -154,7 +154,7 @@ namespace OAuth2ClientApplications.Endpoints } //Update the app's secret - using PrivateString? secret = await Applications.UpdateSecretAsync(entity.Session.UserID, appId); + using PrivateString? secret = await Applications.UpdateSecretAsync(entity.Session.UserID, appId, entity.EventCancellation); if (webm.Assert(secret != null, "Failed to update the application secret")) { -- cgit