Test: Integrated google auth

This commit is contained in:
Kamigen
2024-04-29 18:30:04 -04:00
parent be1d4cb3b6
commit 025195627c
9 changed files with 22 additions and 127 deletions

View File

@@ -14,6 +14,8 @@
<PackageVersion Include="FluentValidation.DependencyInjectionExtensions" Version="11.8.1" />
<PackageVersion Include="Google.Apis.Oauth2.v2" Version="1.67.0.1869" />
<PackageVersion Include="MediatR" Version="12.2.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Facebook" Version="8.0.4" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Google" Version="8.0.4" />
<PackageVersion Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.3" />

View File

@@ -1,8 +0,0 @@
using Google.Apis.Oauth2.v2.Data;
namespace Hutopy.Application.Common.Interfaces;
public interface IGoogleService
{
Task<Userinfo?> GetUserInfoAsync(string accessToken);
}

View File

@@ -1,20 +0,0 @@
using Hutopy.Application.Common.Interfaces;
namespace Hutopy.Application.Google.Commands;
public record CreateGoogleUserCommand : IRequest<Guid>
{
public required string AccessToken { get; init; }
}
public class CreateGoogleUser(
IApplicationDbContext context
) : IRequestHandler<CreateGoogleUserCommand, Guid>
{
public async Task<Guid> Handle(CreateGoogleUserCommand request, CancellationToken cancellationToken)
{
await context.SaveChangesAsync(cancellationToken);
return Guid.NewGuid();
}
}

View File

@@ -4,6 +4,7 @@
<AssemblyName>Hutopy.Infrastructure</AssemblyName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">

View File

@@ -1,24 +0,0 @@
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Oauth2.v2;
using Google.Apis.Oauth2.v2.Data;
using Hutopy.Application.Common.Interfaces;
namespace Hutopy.Infrastructure.Services;
public class GoogleService : IGoogleService
{
public async Task<Userinfo?> GetUserInfoAsync(string accessToken)
{
var user = GoogleCredential.FromAccessToken(accessToken);
var service = new Oauth2Service(
new BaseClientService.Initializer
{
HttpClientInitializer = user,
ApplicationName = "Hutopy"
});
return await service.Userinfo.Get().ExecuteAsync();
}
}

View File

@@ -1,32 +0,0 @@
using Hutopy.Application.Common.Interfaces;
using Hutopy.Application.Google.Commands;
using Hutopy.Domain.Interfaces;
namespace Hutopy.Web.Endpoints;
public class Google : EndpointGroupBase
{
public override void Map(WebApplication app)
{
app.MapGroup(this)
.MapPost(CreateGoogleUser);
}
public static async Task<Guid> CreateGoogleUser(ISender sender, CreateGoogleUserCommand command, IUserService userService, IGoogleService googleService)
{
var googleUser = await googleService.GetUserInfoAsync(command.AccessToken) ?? throw new Exception("Failed to get user info from Google");
var user = await userService.FindUserByEmailAsync(googleUser.Email);
if (user != null)
{
// TODO: Return login information
return await sender.Send(command);
}
await userService.CreateUserAsync(googleUser);
return await sender.Send(command);
}
}

View File

@@ -6,6 +6,9 @@ using Hutopy.Infrastructure.Data;
using Hutopy.Infrastructure.Services;
using Hutopy.Web;
using Azure.Identity;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.Google;
using Microsoft.AspNetCore.Identity;
var builder = WebApplication.CreateBuilder(args);
@@ -48,8 +51,21 @@ builder.Services.AddApplicationServices();
builder.Services.AddInfrastructureServices(builder.Configuration);
builder.Services.AddWebServices();
// OAuth
builder.Services.AddAuthentication()
.AddGoogle(options =>
{
options.ClientId = builder.Configuration["Google:ClientId"] ?? throw new ArgumentNullException("The Google ClientId is missing.");
options.ClientSecret = builder.Configuration["Google:ClientSecret"] ?? throw new ArgumentNullException("The Google ClientSecret is missing.");
options.CallbackPath = "/api/google/o/signin-callback";
});
/*.AddFacebook(options =>
{
options.AppId = ""; // TODO
options.AppSecret = ""; // TODO
});*/ // We can add a lot more if needed, microsoft, twitter, etc.
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IGoogleService, GoogleService>();
var app = builder.Build();

View File

@@ -14,6 +14,8 @@
<ItemGroup>
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Facebook" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />

View File

@@ -26,39 +26,6 @@
}
}
},
"/api/Google": {
"post": {
"tags": [
"Google"
],
"operationId": "CreateGoogleUser",
"requestBody": {
"x-name": "command",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateGoogleUserCommand"
}
}
},
"required": true,
"x-position": 1
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string",
"format": "guid"
}
}
}
}
}
}
},
"/api/JoinUs": {
"get": {
"tags": [
@@ -682,15 +649,6 @@
}
}
},
"CreateGoogleUserCommand": {
"type": "object",
"additionalProperties": false,
"properties": {
"accessToken": {
"type": "string"
}
}
},
"PaginatedListOfFutureCreatorListDto": {
"type": "object",
"additionalProperties": false,