Split creators out of identity
This commit is contained in:
@@ -17,67 +17,39 @@ public class IdentityService(
|
||||
IAuthorizationService authorizationService,
|
||||
IHttpContextAccessor contextAccessor,
|
||||
IOptionsSnapshot<JwtOptions> jwtOptions
|
||||
)
|
||||
)
|
||||
: IIdentityService
|
||||
{
|
||||
public async Task<string?> GetUserNameAsync(string userId)
|
||||
public async Task<string?> GetUserNameAsync(Guid userId)
|
||||
{
|
||||
var user = await userManager.FindByIdAsync(userId);
|
||||
var user = await userManager.FindByIdAsync(userId.ToString());
|
||||
|
||||
return user?.UserName;
|
||||
}
|
||||
|
||||
|
||||
public async Task<UserModel?> GetUserByUserNameAsync(string userName)
|
||||
{
|
||||
var user = await userManager.FindByNameAsync(userName);
|
||||
|
||||
|
||||
if (user == null) return null;
|
||||
|
||||
return new()
|
||||
{
|
||||
Id = user.Id,
|
||||
CreatorAlias = user.CreatorAlias,
|
||||
UserName = user.UserName ?? string.Empty,
|
||||
UserName = user.UserName!,
|
||||
PhoneNumber = user.PhoneNumber,
|
||||
Email = user.Email,
|
||||
Alias = user.Alias,
|
||||
FirstName = user.FirstName,
|
||||
LastName = user.LastName,
|
||||
Email = user.Email ?? string.Empty,
|
||||
Occupation = user.Occupation,
|
||||
PhoneNumber = user.PhoneNumber ?? string.Empty,
|
||||
BirthDate = user.BirthDate,
|
||||
Country = user.Country,
|
||||
City = user.City,
|
||||
Address = user.Address,
|
||||
About = user.About,
|
||||
Description = user.Description,
|
||||
SocialNetworks = new()
|
||||
{
|
||||
FacebookUrl = user.SocialNetworks.FacebookUrl,
|
||||
InstagramUrl = user.SocialNetworks.InstagramUrl,
|
||||
XUrl = user.SocialNetworks.XUrl,
|
||||
LinkedInUrl = user.SocialNetworks.LinkedInUrl,
|
||||
TikTokUrl = user.SocialNetworks.TikTokUrl,
|
||||
YoutubeUrl = user.SocialNetworks.YoutubeUrl,
|
||||
RedditUrl = user.SocialNetworks.RedditUrl,
|
||||
YourWebsiteUrl = user.SocialNetworks.YourWebsiteUrl,
|
||||
},
|
||||
ProfileColors = new()
|
||||
{
|
||||
BannerTop = user.ProfileColors.BannerTop,
|
||||
BannerBottom = user.ProfileColors.BannerBottom,
|
||||
Accent = user.ProfileColors.Accent,
|
||||
Menu = user.ProfileColors.Menu
|
||||
},
|
||||
StoredDataUrls = new()
|
||||
{
|
||||
ProfilePictureUrl = user.StoredDataUrls.ProfilePictureUrl,
|
||||
BannerPictureUrl = user.StoredDataUrls.BannerPictureUrl,
|
||||
WebsiteIconUrl = user.StoredDataUrls.WebsiteIconUrl,
|
||||
}
|
||||
PortraitUrl = user.PortraitUrl
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<Result<string>> CreateUserAsync(Userinfo userInfo)
|
||||
|
||||
public async Task<Result<Guid>> CreateUserAsync(Userinfo userInfo)
|
||||
{
|
||||
var applicationUser = new ApplicationUser
|
||||
{
|
||||
@@ -86,80 +58,83 @@ public class IdentityService(
|
||||
FirstName = userInfo.GivenName,
|
||||
LastName = userInfo.FamilyName
|
||||
};
|
||||
|
||||
|
||||
var password = Guid.NewGuid().ToString("N")[..32];
|
||||
|
||||
var identityResult = await userManager.CreateAsync(applicationUser, password);
|
||||
|
||||
var applicationResult = identityResult.ToApplicationResult();
|
||||
|
||||
var result = new Result<string>(applicationUser.Id, applicationResult.Succeeded, applicationResult.Errors);
|
||||
|
||||
var result = new Result<Guid>(applicationUser.Id, applicationResult.Succeeded, applicationResult.Errors);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Result<string>> CreateUserAsync(string email, string userName, string firstName, string lastName, string password)
|
||||
|
||||
public async Task<Result<Guid>> CreateUserAsync(string email, string userName, string firstName, string lastName,
|
||||
string password)
|
||||
{
|
||||
var applicationUser = new ApplicationUser
|
||||
{
|
||||
UserName = userName,
|
||||
Email = email,
|
||||
FirstName = firstName,
|
||||
LastName = lastName
|
||||
UserName = userName, Email = email, FirstName = firstName, LastName = lastName
|
||||
};
|
||||
|
||||
var response = await userManager.CreateAsync(applicationUser, password);
|
||||
|
||||
var result = new Result<string>(applicationUser.Id, response.Succeeded, response.ToApplicationResult().Errors);
|
||||
|
||||
var result = new Result<Guid>(applicationUser.Id, response.Succeeded, response.ToApplicationResult().Errors);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Result<string>> UpdateCurrentUserAsync(UserModel userModel)
|
||||
public async Task<Result<Guid>> UpdateCurrentUserAsync(UserModel userModel)
|
||||
{
|
||||
var applicationUser = await userManager.FindByIdAsync(userModel.Id);
|
||||
var applicationUser = await userManager.FindByIdAsync(userModel.Id.ToString());
|
||||
|
||||
if (applicationUser is null) return Result<string>.Failure("", new[] { "User not found." });
|
||||
if (applicationUser is null) return Result<Guid>.Failure(Guid.Empty, new[] { "User not found." });
|
||||
|
||||
applicationUser.Id = userModel.Id;
|
||||
applicationUser.Email = userModel.Email;
|
||||
applicationUser.PhoneNumber = userModel.PhoneNumber;
|
||||
applicationUser.Alias = userModel.Alias;
|
||||
applicationUser.FirstName = userModel.FirstName;
|
||||
applicationUser.LastName = userModel.LastName;
|
||||
applicationUser.Occupation = userModel.Occupation;
|
||||
applicationUser.PhoneNumber = userModel.PhoneNumber;
|
||||
applicationUser.BirthDate = userModel.BirthDate;
|
||||
applicationUser.Country = userModel.Country;
|
||||
applicationUser.City = userModel.City;
|
||||
applicationUser.Address = userModel.Address;
|
||||
applicationUser.About = userModel.About;
|
||||
applicationUser.Description = userModel.Description;
|
||||
applicationUser.SocialNetworks = new()
|
||||
{
|
||||
FacebookUrl = userModel.SocialNetworks.FacebookUrl,
|
||||
InstagramUrl = userModel.SocialNetworks.InstagramUrl,
|
||||
XUrl = userModel.SocialNetworks.XUrl,
|
||||
LinkedInUrl = userModel.SocialNetworks.LinkedInUrl,
|
||||
TikTokUrl = userModel.SocialNetworks.TikTokUrl,
|
||||
YoutubeUrl = userModel.SocialNetworks.YoutubeUrl,
|
||||
RedditUrl = userModel.SocialNetworks.RedditUrl,
|
||||
YourWebsiteUrl = userModel.SocialNetworks.YourWebsiteUrl
|
||||
};
|
||||
applicationUser.ProfileColors = new()
|
||||
{
|
||||
BannerTop = userModel.ProfileColors.BannerTop,
|
||||
BannerBottom = userModel.ProfileColors.BannerBottom,
|
||||
Accent = userModel.ProfileColors.Accent,
|
||||
Menu = userModel.ProfileColors.Menu
|
||||
};
|
||||
applicationUser.PortraitUrl = userModel.PortraitUrl;
|
||||
|
||||
var response = await userManager.UpdateAsync(applicationUser);
|
||||
|
||||
var applicationResult = response.ToApplicationResult();
|
||||
|
||||
var result = new Result<string>(userModel.Id, applicationResult.Succeeded,
|
||||
var result = new Result<Guid>(
|
||||
userModel.Id,
|
||||
applicationResult.Succeeded,
|
||||
applicationResult.Errors);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static UserModel BuildModelFrom(ApplicationUser response)
|
||||
{
|
||||
var userModel = new UserModel
|
||||
{
|
||||
Id = response.Id,
|
||||
UserName = response.UserName ?? string.Empty,
|
||||
PhoneNumber = response.PhoneNumber ?? string.Empty,
|
||||
Email = response.Email ?? string.Empty,
|
||||
PortraitUrl = response.PortraitUrl,
|
||||
Alias = response.Alias,
|
||||
FirstName = response.FirstName,
|
||||
LastName = response.LastName,
|
||||
Occupation = response.Occupation,
|
||||
BirthDate = response.BirthDate,
|
||||
Address = response.Address,
|
||||
};
|
||||
|
||||
return userModel;
|
||||
}
|
||||
|
||||
public async Task<UserModel?> FindUserByIdAsync(string id)
|
||||
{
|
||||
var user = await userManager.FindByIdAsync(id);
|
||||
@@ -170,64 +145,6 @@ public class IdentityService(
|
||||
|
||||
return userModel;
|
||||
}
|
||||
|
||||
public async Task<UserModel?> FindUserByCreatorAliasAsync(string creatorAlias, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var user = await userManager.FindByCreatorAliasAsync(creatorAlias, cancellationToken);
|
||||
|
||||
if (user == null) return null;
|
||||
|
||||
var userModel = BuildModelFrom(user);
|
||||
|
||||
return userModel;
|
||||
}
|
||||
|
||||
private static UserModel BuildModelFrom(ApplicationUser response)
|
||||
{
|
||||
var userModel = new UserModel
|
||||
{
|
||||
Id = response.Id,
|
||||
CreatorAlias = response.CreatorAlias,
|
||||
UserName = response.UserName ?? string.Empty,
|
||||
Alias = response.Alias,
|
||||
FirstName = response.FirstName,
|
||||
LastName = response.LastName,
|
||||
Email = response.Email ?? string.Empty,
|
||||
Occupation = response.Occupation,
|
||||
PhoneNumber = response.PhoneNumber ?? string.Empty,
|
||||
BirthDate = response.BirthDate,
|
||||
Country = response.Country,
|
||||
City = response.City,
|
||||
Address = response.Address,
|
||||
About = response.About,
|
||||
Description = response.Description,
|
||||
SocialNetworks = new()
|
||||
{
|
||||
FacebookUrl = response.SocialNetworks.FacebookUrl,
|
||||
InstagramUrl = response.SocialNetworks.InstagramUrl,
|
||||
XUrl = response.SocialNetworks.XUrl,
|
||||
LinkedInUrl = response.SocialNetworks.LinkedInUrl,
|
||||
TikTokUrl = response.SocialNetworks.TikTokUrl,
|
||||
YoutubeUrl = response.SocialNetworks.YoutubeUrl,
|
||||
RedditUrl = response.SocialNetworks.RedditUrl,
|
||||
YourWebsiteUrl = response.SocialNetworks.YourWebsiteUrl,
|
||||
},
|
||||
ProfileColors = new()
|
||||
{
|
||||
BannerTop = response.ProfileColors.BannerTop,
|
||||
BannerBottom = response.ProfileColors.BannerBottom,
|
||||
Accent = response.ProfileColors.Accent,
|
||||
Menu = response.ProfileColors.Menu
|
||||
},
|
||||
StoredDataUrls = new()
|
||||
{
|
||||
ProfilePictureUrl = response.StoredDataUrls.ProfilePictureUrl,
|
||||
BannerPictureUrl = response.StoredDataUrls.BannerPictureUrl,
|
||||
WebsiteIconUrl = response.StoredDataUrls.WebsiteIconUrl,
|
||||
}
|
||||
};
|
||||
return userModel;
|
||||
}
|
||||
|
||||
public async Task<UserModel?> FindUserByEmailAsync(string email)
|
||||
{
|
||||
@@ -235,51 +152,9 @@ public class IdentityService(
|
||||
|
||||
if (response == null) return null;
|
||||
|
||||
var userModel = new UserModel
|
||||
{
|
||||
Id = response.Id,
|
||||
CreatorAlias = response.CreatorAlias,
|
||||
UserName = response.UserName ?? string.Empty,
|
||||
FirstName = response.FirstName,
|
||||
LastName = response.LastName,
|
||||
Email = response.Email ?? string.Empty,
|
||||
Occupation = response.Occupation,
|
||||
PhoneNumber = response.PhoneNumber ?? string.Empty,
|
||||
BirthDate = response.BirthDate,
|
||||
Country = response.Country,
|
||||
City = response.City,
|
||||
Address = response.Address,
|
||||
About = response.About,
|
||||
Description = response.Description,
|
||||
SocialNetworks = new()
|
||||
{
|
||||
FacebookUrl = response.SocialNetworks.FacebookUrl,
|
||||
InstagramUrl = response.SocialNetworks.InstagramUrl,
|
||||
XUrl = response.SocialNetworks.XUrl,
|
||||
LinkedInUrl = response.SocialNetworks.LinkedInUrl,
|
||||
TikTokUrl = response.SocialNetworks.TikTokUrl,
|
||||
YoutubeUrl = response.SocialNetworks.YoutubeUrl,
|
||||
RedditUrl = response.SocialNetworks.RedditUrl,
|
||||
YourWebsiteUrl = response.SocialNetworks.YourWebsiteUrl,
|
||||
},
|
||||
ProfileColors = new()
|
||||
{
|
||||
BannerTop = response.ProfileColors.BannerTop,
|
||||
BannerBottom = response.ProfileColors.BannerBottom,
|
||||
Accent = response.ProfileColors.Accent,
|
||||
Menu = response.ProfileColors.Menu
|
||||
},
|
||||
StoredDataUrls = new()
|
||||
{
|
||||
ProfilePictureUrl = response.StoredDataUrls.ProfilePictureUrl,
|
||||
BannerPictureUrl = response.StoredDataUrls.BannerPictureUrl,
|
||||
WebsiteIconUrl = response.StoredDataUrls.WebsiteIconUrl,
|
||||
}
|
||||
};
|
||||
|
||||
return userModel;
|
||||
return BuildModelFrom(response);
|
||||
}
|
||||
|
||||
|
||||
public async Task<UserModel?> GetCurrentUserAsync()
|
||||
{
|
||||
var currentUserId = contextAccessor.HttpContext?.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
||||
@@ -291,69 +166,38 @@ public class IdentityService(
|
||||
return await FindUserByIdAsync(currentUserId);
|
||||
}
|
||||
|
||||
public async Task<Result> UpdateCurrentUserBannerPictureUrlAsync(string url)
|
||||
public async Task<Result> UpdateCurrentUserPortraitUrlAsync(string url)
|
||||
{
|
||||
var userModel = await GetCurrentUserAsync();
|
||||
if (userModel is null) return Result.Failure(new[] { "User not found." });
|
||||
|
||||
var applicationUser = await userManager.FindByIdAsync(userModel.Id);
|
||||
if (applicationUser is null) return Result.Failure(new[] { "ApplicationUser not found." });
|
||||
var applicationUser = await userManager.FindByIdAsync(userModel.Id.ToString());
|
||||
if (applicationUser is null) return Result.Failure(["ApplicationUser not found."]);
|
||||
|
||||
applicationUser.PortraitUrl = url;
|
||||
|
||||
applicationUser.StoredDataUrls.BannerPictureUrl = url;
|
||||
|
||||
var response = await userManager.UpdateAsync(applicationUser);
|
||||
|
||||
return response.ToApplicationResult();
|
||||
}
|
||||
|
||||
public async Task<Result> UpdateCurrentUserProfilePictureUrlAsync(string url)
|
||||
public async Task<bool> IsInRoleAsync(Guid userId, string role)
|
||||
{
|
||||
var userModel = await GetCurrentUserAsync();
|
||||
if (userModel is null) return Result.Failure(new[] { "User not found." });
|
||||
|
||||
var applicationUser = await userManager.FindByIdAsync(userModel.Id);
|
||||
if (applicationUser is null) return Result.Failure(new[] { "ApplicationUser not found." });
|
||||
|
||||
applicationUser.StoredDataUrls.ProfilePictureUrl = url;
|
||||
|
||||
var response = await userManager.UpdateAsync(applicationUser);
|
||||
|
||||
return response.ToApplicationResult();
|
||||
}
|
||||
|
||||
public async Task<Result> UpdateCurrentUserWebsiteIconUrlAsync(string url)
|
||||
{
|
||||
var userModel = await GetCurrentUserAsync();
|
||||
if (userModel is null) return Result.Failure(new[] { "User not found." });
|
||||
|
||||
var applicationUser = await userManager.FindByIdAsync(userModel.Id);
|
||||
if (applicationUser is null) return Result.Failure(new[] { "ApplicationUser not found." });
|
||||
|
||||
applicationUser.StoredDataUrls.WebsiteIconUrl = url;
|
||||
|
||||
var response = await userManager.UpdateAsync(applicationUser);
|
||||
|
||||
return response.ToApplicationResult();
|
||||
}
|
||||
|
||||
public async Task<bool> IsInRoleAsync(string userId, string role)
|
||||
{
|
||||
var user = await userManager.FindByIdAsync(userId);
|
||||
var user = await userManager.FindByIdAsync(userId.ToString());
|
||||
|
||||
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 ?? "");
|
||||
var currentUser = await userManager.FindByIdAsync(currentUserModel.Id.ToString());
|
||||
|
||||
return currentUser != null && await userManager.IsInRoleAsync(currentUser, role);
|
||||
}
|
||||
|
||||
public async Task<bool> AuthorizeAsync(string userId, string policyName)
|
||||
public async Task<bool> AuthorizeAsync(Guid userId, string policyName)
|
||||
{
|
||||
var user = await userManager.FindByIdAsync(userId);
|
||||
var user = await userManager.FindByIdAsync(userId.ToString());
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
@@ -380,44 +224,45 @@ 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."});
|
||||
|
||||
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."});
|
||||
|
||||
|
||||
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 currentUser = await userManager.FindByIdAsync(currentUserModel.Id.ToString());
|
||||
|
||||
if (currentUser is null) return [];
|
||||
|
||||
var userRoles = await userManager.GetRolesAsync(currentUser);
|
||||
|
||||
return userRoles;
|
||||
}
|
||||
|
||||
|
||||
public async Task<string?> LoginAsync(string userName, string password)
|
||||
{
|
||||
var result = await signInManager.PasswordSignInAsync(userName, password, isPersistent: false, lockoutOnFailure: false);
|
||||
|
||||
var result =
|
||||
await signInManager.PasswordSignInAsync(userName, password, isPersistent: false, lockoutOnFailure: false);
|
||||
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
var user = await GetUserByUserNameAsync(userName);
|
||||
|
||||
if (user is null) throw new InvalidOperationException();
|
||||
@@ -427,12 +272,12 @@ public class IdentityService(
|
||||
issuer: jwtOptions.Value.Issuer,
|
||||
audience: jwtOptions.Value.Audience,
|
||||
key: jwtOptions.Value.Key,
|
||||
userId: user.Id,
|
||||
userId: user.Id.ToString(),
|
||||
email: user.Email,
|
||||
alias: user.Alias,
|
||||
firstname: user.FirstName,
|
||||
lastname: user.LastName,
|
||||
profilePictureUrl: user.StoredDataUrls.ProfilePictureUrl);
|
||||
portraitUrl: user.PortraitUrl);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user