aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-03-09 01:48:39 -0500
committerLibravatar vnugent <public@vaughnnugent.com>2023-03-09 01:48:39 -0500
commitdbe97d1130238e93413a6fa466996feed13e93c8 (patch)
tree84f3e7efb78599d8f913e01d8389f13a99187498
parent3bfc707c736e4be22aa8ab6e9ff72d9d20387687 (diff)
Omega cache, session, and account provider complete overhaul
-rw-r--r--Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/ApplicationStore.cs6
-rw-r--r--Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/UserApplication.cs4
-rw-r--r--Plugins/OAuth2ClientApplications/src/Endpoints/ApplicationEndpoint.cs88
3 files changed, 42 insertions, 56 deletions
diff --git a/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/ApplicationStore.cs b/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/ApplicationStore.cs
index 659bea8..d02d2e1 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) 2022 Vaughn Nugent
+* Copyright (c) 2023 Vaughn Nugent
*
* Library: VNLib
* Package: VNLib.Plugins.Essentials.Oauth
@@ -48,7 +48,7 @@ namespace VNLib.Plugins.Essentials.Oauth.Applications
public const int SECRET_SIZE = 32;
public const int CLIENT_ID_SIZE = 16;
- private readonly PasswordHashing SecretHashing;
+ private readonly IPasswordHashingProvider SecretHashing;
private readonly DbContextOptions ConextOptions;
private readonly ITokenManager TokenStore;
@@ -58,7 +58,7 @@ namespace VNLib.Plugins.Essentials.Oauth.Applications
/// </summary>
/// <param name="conextOptions">EFCore context options for connecting to a remote data-store</param>
/// <param name="secretHashing">A <see cref="PasswordHashing"/> structure for hashing client secrets</param>
- public ApplicationStore(DbContextOptions conextOptions, PasswordHashing secretHashing)
+ public ApplicationStore(DbContextOptions conextOptions, IPasswordHashingProvider secretHashing)
{
this.ConextOptions = conextOptions;
this.SecretHashing = secretHashing;
diff --git a/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/UserApplication.cs b/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/UserApplication.cs
index e18f76d..9c2f543 100644
--- a/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/UserApplication.cs
+++ b/Libs/VNLib.Plugins.Essentials.Oauth/src/Applications/UserApplication.cs
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022 Vaughn Nugent
+* Copyright (c) 2023 Vaughn Nugent
*
* Library: VNLib
* Package: VNLib.Plugins.Essentials.Oauth
@@ -118,7 +118,7 @@ namespace VNLib.Plugins.Essentials.Oauth.Applications
/// </summary>
/// <param name="appEl">The application JWT payalod element</param>
/// <returns>The recovered application</returns>
- public static UserApplication FromJwtDoc(in JsonElement appEl)
+ public static UserApplication FromJwtDoc(JsonElement appEl)
{
return new()
{
diff --git a/Plugins/OAuth2ClientApplications/src/Endpoints/ApplicationEndpoint.cs b/Plugins/OAuth2ClientApplications/src/Endpoints/ApplicationEndpoint.cs
index 5ecce63..057b1d3 100644
--- a/Plugins/OAuth2ClientApplications/src/Endpoints/ApplicationEndpoint.cs
+++ b/Plugins/OAuth2ClientApplications/src/Endpoints/ApplicationEndpoint.cs
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022 Vaughn Nugent
+* Copyright (c) 2023 Vaughn Nugent
*
* Library: VNLib
* Package: OAuth2ClientApplications
@@ -50,35 +50,21 @@ namespace OAuth2ClientApplications.Endpoints
[ConfigurationName("applications")]
internal sealed class ApplicationEndpoint : ProtectedWebEndpoint
{
- private sealed class ApplicationMessage
- {
- [JsonPropertyName("name")]
- public string? ApplicationName { get; set; }
- [JsonPropertyName("description")]
- public string? Description { get; set; }
- [JsonPropertyName("client_id")]
- public string? ClientID { get; set; }
- [JsonPropertyName("raw_secret")]
- public string? RawSecret { get; set; }
- [JsonPropertyName("Id")]
- public string? ApplicationID { get; set; }
- [JsonPropertyName("permissions")]
- public string? Permissions { get; set; }
- }
-
+
private readonly ApplicationStore Applications;
private readonly int MaxAppsPerUser;
- private readonly string MaxAppOverloadMessage;
+ private readonly string MaxAppOverloadMessage;
private static readonly UserAppValidator Validator = new();
- public ApplicationEndpoint(PluginBase plugin, IReadOnlyDictionary<string, JsonElement> config)
+ public ApplicationEndpoint(PluginBase plugin, IConfigScope config)
{
//Get configuration variables from plugin
string? path = config["path"].GetString();
MaxAppsPerUser = config["max_apps_per_user"].GetInt32();
InitPathAndLog(path, plugin.Log);
+
//Load apps
Applications = new(plugin.GetContextOptions(), plugin.GetPasswords());
@@ -124,6 +110,7 @@ namespace OAuth2ClientApplications.Endpoints
}
}
}
+
protected override async ValueTask<VfReturnType> PostAsync(HttpEntity entity)
{
//Default response
@@ -153,27 +140,12 @@ namespace OAuth2ClientApplications.Endpoints
//Update message will include a challenge and an app id
string? appId = update.RootElement.GetPropString("Id");
- string? challenge = update.RootElement.GetPropString("challenge");
if (string.IsNullOrWhiteSpace(appId))
{
return VfReturnType.NotFound;
}
- /*
- * A secret update requires a client challenge because
- * it can log-out active sessions and break access to
- * other applications
- */
-
- if (string.IsNullOrWhiteSpace(challenge) || !entity.Session.VerifyChallenge(challenge))
- {
- //return unauthorized
- webm.Result = "Please check your password";
- entity.CloseResponseJson(HttpStatusCode.Unauthorized, webm);
- return VfReturnType.VirtualSkip;
- }
-
//Update the app's secret
using PrivateString? secret = await Applications.UpdateSecretAsync(entity.Session.UserID, appId);
@@ -195,6 +167,7 @@ namespace OAuth2ClientApplications.Endpoints
//Send raw secret
RawSecret = (string)secret
};
+
//Must write response while password is in scope
entity.CloseResponseJson(HttpStatusCode.OK, result);
return VfReturnType.VirtualSkip;
@@ -210,26 +183,13 @@ namespace OAuth2ClientApplications.Endpoints
}
//Update message will include a challenge and an app id
- string? appId = update.RootElement.GetPropString("Id");
- string? challenge = update.RootElement.GetPropString("challenge");
+ string? appId = update.RootElement.GetPropString("Id");
if (string.IsNullOrWhiteSpace(appId))
{
return VfReturnType.NotFound;
- }
-
- /*
- * A secret update requires a client challenge because
- * it can log-out active sessions and break access to
- * other applications
- */
- if (string.IsNullOrWhiteSpace(challenge) || !entity.Session.VerifyChallenge(challenge))
- {
- webm.Result = "Please check your password";
- //return unauthorized
- entity.CloseResponseJson(HttpStatusCode.Unauthorized, webm);
- return VfReturnType.VirtualSkip;
- }
+ }
+
//Try to delete the app
if (await Applications.DeleteAsync(appId, entity.Session.UserID))
{
@@ -245,6 +205,7 @@ namespace OAuth2ClientApplications.Endpoints
}
return VfReturnType.BadRequest;
}
+
protected override async ValueTask<VfReturnType> PutAsync(HttpEntity entity)
{
ValErrWebMessage webm = new();
@@ -354,9 +315,13 @@ namespace OAuth2ClientApplications.Endpoints
ApplicationName = newApp.AppName,
RawSecret = (string)secret,
ClientID = newApp.ClientId,
- Description = newApp.AppDescription
+ Description = newApp.AppDescription,
+ CreatedTime = newApp.Created.ToString("O"),
+ LastUpdatedTime = newApp.LastModified.ToString("O")
};
+ UserApplication ap;
+
//Must write response while the secret is in scope
entity.CloseResponseJson(HttpStatusCode.Created, mess);
return VfReturnType.VirtualSkip;
@@ -376,5 +341,26 @@ namespace OAuth2ClientApplications.Endpoints
//return the string
return builder.ToString();
}
+
+ private sealed class ApplicationMessage
+ {
+ [JsonPropertyName("name")]
+ public string? ApplicationName { get; set; }
+ [JsonPropertyName("description")]
+ public string? Description { get; set; }
+ [JsonPropertyName("client_id")]
+ public string? ClientID { get; set; }
+ [JsonPropertyName("raw_secret")]
+ public string? RawSecret { get; set; }
+ [JsonPropertyName("Id")]
+ public string? ApplicationID { get; set; }
+ [JsonPropertyName("permissions")]
+ public string? Permissions { get; set; }
+ [JsonPropertyName("Created")]
+ public string? CreatedTime { get; set; }
+ [JsonPropertyName("LastModified")]
+ public string? LastUpdatedTime { get; set; }
+ }
+
}
} \ No newline at end of file