Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/SocialiteNET/Abstractions/ISocialite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,18 @@ public interface ISocialite
/// <returns>Provider instance</returns>
/// <exception cref="ArgumentNullException">Thrown when config is null</exception>
/// <exception cref="ArgumentException">Thrown when required config properties are missing</exception>
IProvider BuildProvider(string provider, ProviderConfig config);
[Obsolete("Please use the GetProvider(ProviderEnum provider, ProviderConfig config) method")] IProvider BuildProvider(string provider, ProviderConfig config);

/// <summary>
/// Builds an OAuth provider with custom configuration
/// </summary>
/// <param name="provider">Provider type</param>
/// <param name="config">Provider configuration</param>
/// <returns>Provider instance</returns>
/// <exception cref="ArgumentNullException">Thrown when config is null</exception>
/// <exception cref="ArgumentException">Thrown when required config properties are missing</exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown when provider is not supported</exception>
IProvider BuildProvider(ProviderEnum provider, ProviderConfig config);

/// <summary>
/// Adds a custom driver
Expand Down
17 changes: 17 additions & 0 deletions src/SocialiteNET/Abstractions/ProviderEnum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace SocialiteNET.Abstractions;

/// <summary>
/// Enumeration of supported providers
/// </summary>
public enum ProviderEnum
{
/// <summary>
/// Google authentication provider. Default provider.
/// </summary>
Google,

/// <summary>
/// GitHub authentication provider.
/// </summary>
Github,
}
67 changes: 67 additions & 0 deletions src/SocialiteNET/Core/SocialiteManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using System.Net.Http;
using Microsoft.Extensions.DependencyInjection;
using SocialiteNET.Abstractions;
using SocialiteNET.Providers.Github;
using SocialiteNET.Providers.Google;

namespace SocialiteNET.Core;

Expand Down Expand Up @@ -107,6 +109,71 @@ public IProvider BuildProvider(string provider, ProviderConfig config)
return providerInstance;
}

/// <inheritdoc />
public IProvider BuildProvider(ProviderEnum provider, ProviderConfig config)
{
ArgumentNullException.ThrowIfNull(config);

config.Validate();

using HttpClient httpClient = this.services.GetRequiredService<IHttpClientFactory>().CreateClient();

switch (provider)
{
case ProviderEnum.Google:
GoogleProvider googleProvider = new GoogleProvider(
httpClient,
config.ClientId,
config.ClientSecret,
config.RedirectUrl
);

if (config.Stateless)
{
googleProvider.Stateless();
}

if (config.UsesPkce)
{
googleProvider.WithPkce();
}

if (config.Parameters.Count > 0)
{
googleProvider.With(config.Parameters);
}

return googleProvider;

case ProviderEnum.Github:
GitHubProvider githubProvider = new GitHubProvider(
httpClient,
config.ClientId,
config.ClientSecret,
config.RedirectUrl
);

if (config.Stateless)
{
githubProvider.Stateless();
}

if (config.UsesPkce)
{
githubProvider.WithPkce();
}

if (config.Parameters.Count > 0)
{
githubProvider.With(config.Parameters);
}

return githubProvider;
default:
throw new ArgumentOutOfRangeException(nameof(provider), provider, "Unsupported provider, please register a custom driver.");
}
}

/// <inheritdoc />
public ISocialite Extend(string driver, Func<IServiceProvider, IProvider> factory)
{
Expand Down
33 changes: 33 additions & 0 deletions tests/SocialiteNET.UnitTests/Core/SocialiteManagerGoogleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,39 @@ public void BuildProvider_WithGoogleProviderConfig_ReturnsConfiguredGoogleProvid
exception.Message.ShouldBe("Provider [Google] could not be resolved.");
}

[Fact]
public void BuildProvider_WithTypedGoogleProviderConfig_ReturnsConfiguredGoogleProvider()
{
// Arrange
ServiceCollection services = [];

IHttpClientFactory? httpClientFactory = Substitute.For<IHttpClientFactory>();
httpClientFactory.CreateClient().Returns(new HttpClient());
services.AddSingleton(httpClientFactory);

ServiceProvider serviceProvider = services.BuildServiceProvider();
SocialiteManager manager = new(serviceProvider);

ProviderConfig config = new()
{
ClientId = "test-client-id",
ClientSecret = "test-client-secret",
RedirectUrl = "https://example.com/callback",
Stateless = true,
UsesPkce = true
};
config.Scopes.Add("drive");
config.Parameters.Add("access_type", "offline");

// Act - This would typically fail in a real test as we can't create the type dynamically
// In a real test environment, we would need to mock or use real provider registration
var exception = Should.Throw<InvalidOperationException>(() =>
manager.BuildProvider(ProviderEnum.Google, config));

// Assert
exception.Message.ShouldBe("Provider [Google] could not be resolved.");
}

[Fact]
public void Extend_WithGoogleProviderFactory_RegistersCustomDriver()
{
Expand Down