Feature: Google OAuth2

This commit is contained in:
Kamigen
2024-04-22 16:43:20 -04:00
parent e3d570722e
commit 5f92998663
4 changed files with 71 additions and 20 deletions

View File

@@ -1,8 +1,6 @@
using System.Dynamic;
using Hutopy.Application.Common.Interfaces;
using Hutopy.Domain.Entities;
using Hutopy.Domain.Interfaces;
using Microsoft.EntityFrameworkCore;
namespace Hutopy.Application.Users.Commands;
public record CreateUserCommand : IRequest<Guid>

View File

@@ -1,4 +1,6 @@
using Google.Apis.Oauth2.v2.Data;
using System.Security.Cryptography;
using System.Text;
using Google.Apis.Oauth2.v2.Data;
using Hutopy.Domain.Interfaces;
using Hutopy.Domain.Models;
using Hutopy.Infrastructure.Identity;
@@ -8,6 +10,8 @@ namespace Hutopy.Infrastructure.Services;
public class UserService(UserManager<ApplicationUser> userManager) : IUserService
{
private readonly Random _random = new(DateTime.Now.Millisecond);
public async Task CreateUserAsync(string email, string userName, string firstName, string lastName, string password)
{
var applicationUser = new ApplicationUser
@@ -22,26 +26,13 @@ public class UserService(UserManager<ApplicationUser> userManager) : IUserServic
if (!response.Succeeded)
{
throw new Exception("Failed to create user");
throw new Exception("Failed to create user", new AggregateException(response.Errors.Select(e => new Exception(e.Description))));
}
}
public async Task CreateUserAsync(Userinfo userInfo)
{
var applicationUser = new ApplicationUser
{
UserName = userInfo.Name,
Email = userInfo.Email,
FirstName = userInfo.GivenName,
LastName = userInfo.FamilyName
};
var response = await userManager.CreateAsync(applicationUser, Guid.NewGuid().ToString("N")[..32]);
if (!response.Succeeded)
{
throw new Exception("Failed to create user");
}
await CreateUserAsync(userInfo.Email, userInfo.GivenName, userInfo.GivenName, userInfo.FamilyName, GeneratePassword(24));
}
public async Task<UserModel?> FindUserByIdAsync(string id)
@@ -50,7 +41,7 @@ public class UserService(UserManager<ApplicationUser> userManager) : IUserServic
if (response == null) return null;
var userModel = new UserModel()
var userModel = new UserModel
{
Id = response.Id,
UserName = response.UserName,
@@ -68,7 +59,7 @@ public class UserService(UserManager<ApplicationUser> userManager) : IUserServic
if (response == null) return null;
var userModel = new UserModel()
var userModel = new UserModel
{
Id = response.Id,
UserName = response.UserName,
@@ -79,5 +70,23 @@ public class UserService(UserManager<ApplicationUser> userManager) : IUserServic
return userModel;
}
private const string Characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private const string SpecialCharacters = "!@#$%^&*()_+";
private String GeneratePassword(int length)
{
// Using a string builder has additional overhead, maybe we can find something else
var password = new StringBuilder();
for (var i = 0; i < length; i++)
{
password.Append(Characters[_random.Next(Characters.Length)]);
}
password.Append(SpecialCharacters[_random.Next(SpecialCharacters.Length)]);
return password.ToString();
}
}

View File

@@ -1,4 +1,5 @@
using Hutopy.Application;
using Hutopy.Application.Common.Interfaces;
using Hutopy.Domain.Interfaces;
using Hutopy.Infrastructure;
using Hutopy.Infrastructure.Data;
@@ -48,6 +49,7 @@ builder.Services.AddInfrastructureServices(builder.Configuration);
builder.Services.AddWebServices();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IGoogleService, GoogleService>();
var app = builder.Build();

View File

@@ -6,6 +6,39 @@
"version": "1.0.0"
},
"paths": {
"/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": [
@@ -559,6 +592,15 @@
},
"components": {
"schemas": {
"CreateGoogleUserCommand": {
"type": "object",
"additionalProperties": false,
"properties": {
"accessToken": {
"type": "string"
}
}
},
"PaginatedListOfFutureCreatorListDto": {
"type": "object",
"additionalProperties": false,