Feature: Google OAuth2
This commit is contained in:
@@ -1,8 +1,6 @@
|
|||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using Hutopy.Application.Common.Interfaces;
|
using Hutopy.Application.Common.Interfaces;
|
||||||
using Hutopy.Domain.Entities;
|
|
||||||
using Hutopy.Domain.Interfaces;
|
using Hutopy.Domain.Interfaces;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Hutopy.Application.Users.Commands;
|
namespace Hutopy.Application.Users.Commands;
|
||||||
public record CreateUserCommand : IRequest<Guid>
|
public record CreateUserCommand : IRequest<Guid>
|
||||||
|
|||||||
@@ -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.Interfaces;
|
||||||
using Hutopy.Domain.Models;
|
using Hutopy.Domain.Models;
|
||||||
using Hutopy.Infrastructure.Identity;
|
using Hutopy.Infrastructure.Identity;
|
||||||
@@ -8,6 +10,8 @@ namespace Hutopy.Infrastructure.Services;
|
|||||||
|
|
||||||
public class UserService(UserManager<ApplicationUser> userManager) : IUserService
|
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)
|
public async Task CreateUserAsync(string email, string userName, string firstName, string lastName, string password)
|
||||||
{
|
{
|
||||||
var applicationUser = new ApplicationUser
|
var applicationUser = new ApplicationUser
|
||||||
@@ -22,26 +26,13 @@ public class UserService(UserManager<ApplicationUser> userManager) : IUserServic
|
|||||||
|
|
||||||
if (!response.Succeeded)
|
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)
|
public async Task CreateUserAsync(Userinfo userInfo)
|
||||||
{
|
{
|
||||||
var applicationUser = new ApplicationUser
|
await CreateUserAsync(userInfo.Email, userInfo.GivenName, userInfo.GivenName, userInfo.FamilyName, GeneratePassword(24));
|
||||||
{
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<UserModel?> FindUserByIdAsync(string id)
|
public async Task<UserModel?> FindUserByIdAsync(string id)
|
||||||
@@ -50,7 +41,7 @@ public class UserService(UserManager<ApplicationUser> userManager) : IUserServic
|
|||||||
|
|
||||||
if (response == null) return null;
|
if (response == null) return null;
|
||||||
|
|
||||||
var userModel = new UserModel()
|
var userModel = new UserModel
|
||||||
{
|
{
|
||||||
Id = response.Id,
|
Id = response.Id,
|
||||||
UserName = response.UserName,
|
UserName = response.UserName,
|
||||||
@@ -68,7 +59,7 @@ public class UserService(UserManager<ApplicationUser> userManager) : IUserServic
|
|||||||
|
|
||||||
if (response == null) return null;
|
if (response == null) return null;
|
||||||
|
|
||||||
var userModel = new UserModel()
|
var userModel = new UserModel
|
||||||
{
|
{
|
||||||
Id = response.Id,
|
Id = response.Id,
|
||||||
UserName = response.UserName,
|
UserName = response.UserName,
|
||||||
@@ -79,5 +70,23 @@ public class UserService(UserManager<ApplicationUser> userManager) : IUserServic
|
|||||||
|
|
||||||
return userModel;
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Hutopy.Application;
|
using Hutopy.Application;
|
||||||
|
using Hutopy.Application.Common.Interfaces;
|
||||||
using Hutopy.Domain.Interfaces;
|
using Hutopy.Domain.Interfaces;
|
||||||
using Hutopy.Infrastructure;
|
using Hutopy.Infrastructure;
|
||||||
using Hutopy.Infrastructure.Data;
|
using Hutopy.Infrastructure.Data;
|
||||||
@@ -48,6 +49,7 @@ builder.Services.AddInfrastructureServices(builder.Configuration);
|
|||||||
builder.Services.AddWebServices();
|
builder.Services.AddWebServices();
|
||||||
|
|
||||||
builder.Services.AddScoped<IUserService, UserService>();
|
builder.Services.AddScoped<IUserService, UserService>();
|
||||||
|
builder.Services.AddScoped<IGoogleService, GoogleService>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,39 @@
|
|||||||
"version": "1.0.0"
|
"version": "1.0.0"
|
||||||
},
|
},
|
||||||
"paths": {
|
"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": {
|
"/api/JoinUs": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@@ -559,6 +592,15 @@
|
|||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
"schemas": {
|
"schemas": {
|
||||||
|
"CreateGoogleUserCommand": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"accessToken": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"PaginatedListOfFutureCreatorListDto": {
|
"PaginatedListOfFutureCreatorListDto": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|||||||
Reference in New Issue
Block a user