aboutsummaryrefslogtreecommitdiff
path: root/VNLib.Plugins.Essentials.SocialOauth
diff options
context:
space:
mode:
Diffstat (limited to 'VNLib.Plugins.Essentials.SocialOauth')
-rw-r--r--VNLib.Plugins.Essentials.SocialOauth/Endpoints/Auth0.cs45
-rw-r--r--VNLib.Plugins.Essentials.SocialOauth/Endpoints/DiscordOauth.cs30
-rw-r--r--VNLib.Plugins.Essentials.SocialOauth/Endpoints/GitHubOauth.cs37
-rw-r--r--VNLib.Plugins.Essentials.SocialOauth/OauthClientConfig.cs14
-rw-r--r--VNLib.Plugins.Essentials.SocialOauth/SocialOauthBase.cs6
-rw-r--r--VNLib.Plugins.Essentials.SocialOauth/VNLib.Plugins.Essentials.SocialOauth.csproj2
6 files changed, 72 insertions, 62 deletions
diff --git a/VNLib.Plugins.Essentials.SocialOauth/Endpoints/Auth0.cs b/VNLib.Plugins.Essentials.SocialOauth/Endpoints/Auth0.cs
index 8518ea0..c7512b7 100644
--- a/VNLib.Plugins.Essentials.SocialOauth/Endpoints/Auth0.cs
+++ b/VNLib.Plugins.Essentials.SocialOauth/Endpoints/Auth0.cs
@@ -40,46 +40,51 @@ using VNLib.Plugins.Essentials.Accounts;
using VNLib.Plugins.Extensions.Loading;
using VNLib.Plugins.Extensions.Loading.Users;
-#nullable enable
-
namespace VNLib.Plugins.Essentials.SocialOauth.Endpoints
{
[ConfigurationName("auth0")]
- internal class Auth0 : SocialOauthBase
+ internal sealed class Auth0 : SocialOauthBase
{
+
protected override OauthClientConfig Config { get; }
- private readonly Task<JsonDocument> RsaCertificate;
+ private readonly Task<JsonDocument> Auth0VerificationJwk;
- public Auth0(PluginBase plugin, IReadOnlyDictionary<string, JsonElement> config)
+ public Auth0(PluginBase plugin, IReadOnlyDictionary<string, JsonElement> config) : base()
{
- //Get id/secret
- Task<string?> secret = plugin.TryGetSecretAsync("auth0_client_secret");
- Task<string?> clientId = plugin.TryGetSecretAsync("auth0_client_id");
+ string keyUrl = config["key_url"].GetString() ?? throw new KeyNotFoundException("Missing Auth0 'key_url' from config");
- //Wait sync
- Task.WaitAll(secret, clientId);
+ Uri keyUri = new(keyUrl);
+
+ //Get certificate on background thread
+ Auth0VerificationJwk = Task.Run(() => GetRsaCertificate(keyUri));
Config = new("auth0", config)
{
- //get gh client secret and id
- ClientID = clientId.Result ?? throw new KeyNotFoundException("Missing Auth0 client id from config or vault"),
- ClientSecret = secret.Result ?? throw new KeyNotFoundException("Missing Auth0 client secret from config or vault"),
-
Passwords = plugin.GetPasswords(),
Users = plugin.GetUserManager(),
};
- string keyUrl = config["key_url"].GetString() ?? throw new KeyNotFoundException("Missing Auth0 'key_url' from config");
+ InitPathAndLog(Config.EndpointPath, plugin.Log);
- Uri keyUri = new(keyUrl);
+ //Load secrets
+ _ = plugin.DeferTask(async () =>
+ {
+ //Get id/secret
+ Task<SecretResult?> secretTask = plugin.TryGetSecretAsync("auth0_client_secret");
+ Task<SecretResult?> clientIdTask = plugin.TryGetSecretAsync("auth0_client_id");
- //Get certificate on background thread
- RsaCertificate = Task.Run(() => GetRsaCertificate(keyUri));
+ await Task.WhenAll(secretTask, clientIdTask);
- InitPathAndLog(Config.EndpointPath, plugin.Log);
+ using SecretResult? secret = await secretTask;
+ using SecretResult? clientId = await clientIdTask;
+
+ Config.ClientID = clientId?.Result.ToString() ?? throw new KeyNotFoundException("Missing Auth0 client id from config or vault");
+ Config.ClientSecret = secret?.Result.ToString() ?? throw new KeyNotFoundException("Missing the Auth0 client secret from config or vault");
+
+ }, 100);
}
@@ -154,7 +159,7 @@ namespace VNLib.Plugins.Essentials.SocialOauth.Endpoints
using JsonWebToken jwt = JsonWebToken.Parse(clientAccess.IdToken);
//Verify the token against the first signing key
- if (!jwt.VerifyFromJwk(RsaCertificate.Result.RootElement.GetProperty("keys").EnumerateArray().First()))
+ if (!jwt.VerifyFromJwk(Auth0VerificationJwk.Result.RootElement.GetProperty("keys").EnumerateArray().First()))
{
return EmptyLoginData;
}
diff --git a/VNLib.Plugins.Essentials.SocialOauth/Endpoints/DiscordOauth.cs b/VNLib.Plugins.Essentials.SocialOauth/Endpoints/DiscordOauth.cs
index 6ee7683..d8b2394 100644
--- a/VNLib.Plugins.Essentials.SocialOauth/Endpoints/DiscordOauth.cs
+++ b/VNLib.Plugins.Essentials.SocialOauth/Endpoints/DiscordOauth.cs
@@ -39,7 +39,6 @@ using VNLib.Plugins.Essentials.Accounts;
using VNLib.Plugins.Extensions.Loading;
using VNLib.Plugins.Extensions.Loading.Users;
-#nullable enable
namespace VNLib.Plugins.Essentials.SocialOauth.Endpoints
{
@@ -50,26 +49,33 @@ namespace VNLib.Plugins.Essentials.SocialOauth.Endpoints
public DiscordOauth(PluginBase plugin, IReadOnlyDictionary<string, JsonElement> config) : base()
{
- //Get id/secret
- Task<string?> secret = plugin.TryGetSecretAsync("discord_client_secret");
- Task<string?> clientId = plugin.TryGetSecretAsync("discord_client_id");
-
- //Wait sync
- Task.WaitAll(secret, clientId);
-
Config = new("discord", config)
{
- //get gh client secret and id
- ClientID = clientId.Result ?? throw new KeyNotFoundException("Missing Discord client id from config or vault"),
- ClientSecret = secret.Result ?? throw new KeyNotFoundException("Missing the Discord client secret from config or vault"),
-
Passwords = plugin.GetPasswords(),
Users = plugin.GetUserManager(),
};
InitPathAndLog(Config.EndpointPath, plugin.Log);
+
+ //Load secrets
+ _ = plugin.DeferTask(async () =>
+ {
+ //Get id/secret
+ Task<SecretResult?> clientIdTask = plugin.TryGetSecretAsync("discord_client_id");
+ Task<SecretResult?> secretTask = plugin.TryGetSecretAsync("discord_client_secret");
+
+ await Task.WhenAll(secretTask, clientIdTask);
+
+ using SecretResult? secret = await secretTask;
+ using SecretResult? clientId = await clientIdTask;
+
+ Config.ClientID = clientId?.Result.ToString() ?? throw new KeyNotFoundException("Missing Discord client id from config or vault");
+ Config.ClientSecret = secret?.Result.ToString() ?? throw new KeyNotFoundException("Missing the Discord client secret from config or vault");
+
+ }, 100);
}
+
private static string GetUserIdFromPlatform(string userName)
{
return ManagedHash.ComputeHash($"discord|{userName}", HashAlg.SHA1, HashEncodingMode.Hexadecimal);
diff --git a/VNLib.Plugins.Essentials.SocialOauth/Endpoints/GitHubOauth.cs b/VNLib.Plugins.Essentials.SocialOauth/Endpoints/GitHubOauth.cs
index 0b4fc0f..676f2bb 100644
--- a/VNLib.Plugins.Essentials.SocialOauth/Endpoints/GitHubOauth.cs
+++ b/VNLib.Plugins.Essentials.SocialOauth/Endpoints/GitHubOauth.cs
@@ -39,8 +39,6 @@ using VNLib.Plugins.Essentials.Accounts;
using VNLib.Plugins.Extensions.Loading;
using VNLib.Plugins.Extensions.Loading.Users;
-#nullable enable
-
namespace VNLib.Plugins.Essentials.SocialOauth.Endpoints
{
[ConfigurationName("github")]
@@ -49,32 +47,38 @@ namespace VNLib.Plugins.Essentials.SocialOauth.Endpoints
private const string GITHUB_V3_ACCEPT = "application/vnd.github.v3+json";
private readonly string UserEmailUrl;
-
+
protected override OauthClientConfig Config { get; }
public GitHubOauth(PluginBase plugin, IReadOnlyDictionary<string, JsonElement> config) : base()
{
- //Get id/secret
- Task<string?> secret = plugin.TryGetSecretAsync("github_client_secret");
- Task<string?> clientId = plugin.TryGetSecretAsync("github_client_id");
-
- //Wait sync
- Task.WaitAll(secret, clientId);
+
+ UserEmailUrl = config["user_email_url"].GetString() ?? throw new KeyNotFoundException("Missing required key 'user_email_url' for github configuration");
- Config = new(configName: "github", config)
+ Config = new("github", config)
{
- //get gh client secret and id
- ClientID = clientId.Result ?? throw new KeyNotFoundException("Missing Github client id from config or vault"),
- ClientSecret = secret.Result ?? throw new KeyNotFoundException("Missing Github client secret from config or vault"),
-
Passwords = plugin.GetPasswords(),
Users = plugin.GetUserManager(),
};
+ InitPathAndLog(Config.EndpointPath, plugin.Log);
- UserEmailUrl = config["user_email_url"].GetString() ?? throw new KeyNotFoundException("Missing required key 'user_email_url' for github configuration");
+ //Load secrets
+ _ = plugin.DeferTask(async () =>
+ {
+ //Get id/secret
+ Task<SecretResult?> clientIdTask = plugin.TryGetSecretAsync("github_client_id");
+ Task<SecretResult?> secretTask = plugin.TryGetSecretAsync("github_client_secret");
- InitPathAndLog(Config.EndpointPath, plugin.Log);
+ await Task.WhenAll(secretTask, clientIdTask);
+
+ using SecretResult? secret = await secretTask;
+ using SecretResult? clientId = await clientIdTask;
+
+ Config.ClientID = clientId?.Result.ToString() ?? throw new KeyNotFoundException("Missing Github client id from config or vault");
+ Config.ClientSecret = secret?.Result.ToString() ?? throw new KeyNotFoundException("Missing the Github client secret from config or vault");
+
+ }, 100);
}
protected override void StaticClientPoolInitializer(RestClient client)
@@ -211,6 +215,5 @@ namespace VNLib.Plugins.Essentials.SocialOauth.Endpoints
return accountData;
}
-
}
} \ No newline at end of file
diff --git a/VNLib.Plugins.Essentials.SocialOauth/OauthClientConfig.cs b/VNLib.Plugins.Essentials.SocialOauth/OauthClientConfig.cs
index 6e30802..9caf705 100644
--- a/VNLib.Plugins.Essentials.SocialOauth/OauthClientConfig.cs
+++ b/VNLib.Plugins.Essentials.SocialOauth/OauthClientConfig.cs
@@ -29,9 +29,7 @@ using System.Collections.Generic;
using VNLib.Utils.Extensions;
using VNLib.Plugins.Essentials.Users;
using VNLib.Plugins.Essentials.Accounts;
-using VNLib.Net.Rest.Client;
-#nullable enable
namespace VNLib.Plugins.Essentials.SocialOauth
{
@@ -61,15 +59,13 @@ namespace VNLib.Plugins.Essentials.SocialOauth
NonceByteSize = config["nonce_size"].GetUInt32();
RandomPasswordSize = config["password_size"].GetInt32();
}
+
-
- public RestClientPool ClientPool { get; }
-
- public string ClientID { get; init; }
+ public string ClientID { get; set; } = string.Empty;
- public string ClientSecret { get; init; }
+ public string ClientSecret { get; set; } = string.Empty;
+
-
/// <summary>
/// The user-account origin value. Specifies that the user account
/// was created outside of the local account system
@@ -96,7 +92,7 @@ namespace VNLib.Plugins.Essentials.SocialOauth
/// <summary>
/// The user store to create/get users from
/// </summary>
- public IUserManager Users { get; init; }
+ public IUserManager Users { get; init; }
public PasswordHashing Passwords { get; init; }
diff --git a/VNLib.Plugins.Essentials.SocialOauth/SocialOauthBase.cs b/VNLib.Plugins.Essentials.SocialOauth/SocialOauthBase.cs
index 5728992..6815bf3 100644
--- a/VNLib.Plugins.Essentials.SocialOauth/SocialOauthBase.cs
+++ b/VNLib.Plugins.Essentials.SocialOauth/SocialOauthBase.cs
@@ -75,7 +75,7 @@ namespace VNLib.Plugins.Essentials.SocialOauth
* Disable cross site checking because the OAuth2 flow requires
* cross site when redirecting the client back
*/
- CrossSiteDenied = false
+ DisableCrossSiteDenied = true
};
/// <summary>
@@ -283,7 +283,7 @@ namespace VNLib.Plugins.Essentials.SocialOauth
return VfReturnType.VirtualSkip;
}
//Try to get the claim from the state parameter
- if (ClaimStore.TryGetOrEvictRecord(state, out LoginClaim claim) < 1)
+ if (ClaimStore.TryGetOrEvictRecord(state, out LoginClaim? claim) < 1)
{
entity.Redirect(RedirectType.Temporary, $"{Path}?result=expired");
return VfReturnType.VirtualSkip;
@@ -361,7 +361,7 @@ namespace VNLib.Plugins.Essentials.SocialOauth
return VfReturnType.VirtualSkip;
}
//Recover the access token
- if (AuthorizationStore.TryGetOrEvictRecord(base32Nonce!, out OAuthAccessState token) < 1)
+ if (AuthorizationStore.TryGetOrEvictRecord(base32Nonce!, out OAuthAccessState? token) < 1)
{
webm.Result = AUTH_ERROR_MESSAGE;
entity.CloseResponse(webm);
diff --git a/VNLib.Plugins.Essentials.SocialOauth/VNLib.Plugins.Essentials.SocialOauth.csproj b/VNLib.Plugins.Essentials.SocialOauth/VNLib.Plugins.Essentials.SocialOauth.csproj
index bbe9185..56e3068 100644
--- a/VNLib.Plugins.Essentials.SocialOauth/VNLib.Plugins.Essentials.SocialOauth.csproj
+++ b/VNLib.Plugins.Essentials.SocialOauth/VNLib.Plugins.Essentials.SocialOauth.csproj
@@ -32,7 +32,7 @@
<AnalysisLevel>latest-all</AnalysisLevel>
</PropertyGroup>
<ItemGroup>
- <ProjectReference Include="..\..\..\VNLib\Essentials\VNLib.Plugins.Essentials.csproj" />
+ <ProjectReference Include="..\..\..\VNLib\Essentials\src\VNLib.Plugins.Essentials.csproj" />
<ProjectReference Include="..\..\Extensions\VNLib.Plugins.Extensions.Loading\VNLib.Plugins.Extensions.Loading.csproj" />
<ProjectReference Include="..\..\Extensions\VNLib.Plugins.Extensions.Validation\VNLib.Plugins.Extensions.Validation.csproj" />
<ProjectReference Include="..\..\PluginBase\VNLib.Plugins.PluginBase.csproj" />