Merge remote-tracking branch 'origin/master' into feature/oauth

# Conflicts:
#	src/Application/Common/Interfaces/IIdentityService.cs
#	src/Application/Users/Commands/CreateUser.cs
#	src/Infrastructure/Identity/IdentityService.cs
#	src/Infrastructure/Services/UserService.cs
#	src/Web/Program.cs
This commit is contained in:
Dominic Villemure
2024-06-09 18:05:49 -04:00
21 changed files with 259 additions and 61 deletions

View File

@@ -1,7 +1,9 @@
using Google.Apis.Oauth2.v2.Data;
using System.Security.Claims;
using Hutopy.Application.Common.Interfaces;
using Hutopy.Application.Common.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
namespace Hutopy.Infrastructure.Identity;
@@ -9,7 +11,9 @@ namespace Hutopy.Infrastructure.Identity;
public class IdentityService(
UserManager<ApplicationUser> userManager,
IUserClaimsPrincipalFactory<ApplicationUser> userClaimsPrincipalFactory,
IAuthorizationService authorizationService)
IAuthorizationService authorizationService,
IHttpContextAccessor contextAccessor
)
: IIdentityService
{
public async Task<string?> GetUserNameAsync(string userId)
@@ -18,6 +22,24 @@ public class IdentityService(
return user?.UserName;
}
public async Task<UserModel?> GetUserByUserNameAsync(string userName)
{
var response = await userManager.FindByNameAsync(userName);
if (response == null) return null;
var userModel = new UserModel()
{
Id = response.Id,
UserName = response.UserName,
FirstName = response.FirstName,
LastName = response.LastName,
Email = response.Email,
};
return userModel;
}
public async Task<(Result Result, string UserId)> CreateUserAsync(string userName, string password)
{
@@ -48,6 +70,68 @@ public class IdentityService(
return (result.ToApplicationResult(), user.Id);
}
public async Task<Result> CreateUserAsync(string email, string userName, string firstName, string lastName, string password)
{
var applicationUser = new ApplicationUser
{
UserName = userName,
Email = email,
FirstName = firstName,
LastName = lastName
};
var response = await userManager.CreateAsync(applicationUser, password);
return response.ToApplicationResult();
}
public async Task<UserModel?> FindUserByIdAsync(string id)
{
var response = await userManager.FindByIdAsync(id);
if (response == null) return null;
var userModel = new UserModel()
{
Id = response.Id,
UserName = response.UserName,
FirstName = response.FirstName,
LastName = response.LastName,
Email = response.Email,
};
return userModel;
}
public async Task<UserModel?> GetCurrentUserAsync()
{
var currentUserId = contextAccessor.HttpContext?.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (string.IsNullOrEmpty(currentUserId))
{
return null;
}
return await FindUserByIdAsync(currentUserId);
}
public async Task<UserModel?> FindUserByEmailAsync(string email)
{
var response = await userManager.FindByEmailAsync(email);
if (response == null) return null;
var userModel = new UserModel
{
Id = response.Id,
UserName = response.UserName,
FirstName = response.FirstName,
LastName = response.LastName,
Email = response.Email
};
return userModel;
}
public async Task<bool> IsInRoleAsync(string userId, string role)
{
@@ -55,6 +139,14 @@ public class IdentityService(
return user != null && await userManager.IsInRoleAsync(user, role);
}
public async Task<bool> CurrentUserIsInRoleAsync(string role)
{
var currentUserModel = await GetCurrentUserAsync();
var currentUser = await userManager.FindByIdAsync(currentUserModel?.Id ?? "");
return currentUser != null && await userManager.IsInRoleAsync(currentUser, role);
}
public async Task<bool> AuthorizeAsync(string userId, string policyName)
{
@@ -85,4 +177,32 @@ public class IdentityService(
return result.ToApplicationResult();
}
public async Task<Result> AddRoleAsync(string userId, string role)
{
var hasAdminAccess = await CurrentUserIsInRoleAsync("Administrator");
if (!hasAdminAccess) return Result.Failure(new []{"Only administrator can assign new roles to a user."});
var user = await userManager.FindByIdAsync(userId);
if (user is null) return Result.Failure(new []{"User not found."});
var result = await userManager.AddToRoleAsync(user, role);
return result.ToApplicationResult();
}
public async Task<IList<string>> GetCurrentUserRolesAsync()
{
var currentUserModel = await GetCurrentUserAsync();
var currentUser = await userManager.FindByIdAsync(currentUserModel?.Id ?? "");
if (currentUser is null) return [];
var userRoles = await userManager.GetRolesAsync(currentUser);
return userRoles;
}
}