Add PortraitUrl to User

This commit is contained in:
Jonathan Bourdon
2024-07-01 03:55:13 -04:00
parent 5282fcfd49
commit ecaaaaad33
9 changed files with 614 additions and 42 deletions

View File

@@ -12,7 +12,8 @@ public interface IIdentityService
Task<Result<string>> UpdateCurrentUserAsync(string id, string firstName, string lastName, string occupation, Task<Result<string>> UpdateCurrentUserAsync(string id, string firstName, string lastName, string occupation,
string phoneNumber, string birthDate, string country, string city, string address, string about, string phoneNumber, string birthDate, string country, string city, string address, string about,
string description, string description,
SocialNetworksModel socialNetworks); SocialNetworksModel socialNetworks,
string? portraitUrl);
Task<IList<string>> GetCurrentUserRolesAsync(); Task<IList<string>> GetCurrentUserRolesAsync();
Task<UserModel?> FindUserByIdAsync(string id); Task<UserModel?> FindUserByIdAsync(string id);
Task<UserModel?> FindUserByEmailAsync(string email); Task<UserModel?> FindUserByEmailAsync(string email);

View File

@@ -16,9 +16,10 @@ public class UpdateCurrentUserCommand : IRequest<string>
public required string About { get; init; } public required string About { get; init; }
public required string Description { get; init; } public required string Description { get; init; }
public required SocialNetworksModel SocialNetworks { get; init; } public required SocialNetworksModel SocialNetworks { get; init; }
public required string PortraitUrl { get; init; }
} }
public class UpdateCurrentUserCommandHandler(IApplicationDbContext context, IIdentityService identityService) : public class UpdateCurrentUserCommandHandler(IApplicationDbContext context, IIdentityService identityService) :
IRequestHandler<UpdateCurrentUserCommand, string> IRequestHandler<UpdateCurrentUserCommand, string>
{ {
public async Task<string> Handle(UpdateCurrentUserCommand request, CancellationToken cancellationToken) public async Task<string> Handle(UpdateCurrentUserCommand request, CancellationToken cancellationToken)
@@ -26,15 +27,24 @@ public class UpdateCurrentUserCommandHandler(IApplicationDbContext context, IIde
var identityUser = await identityService.GetCurrentUserAsync(); var identityUser = await identityService.GetCurrentUserAsync();
if (identityUser?.Id is null) return string.Empty; if (identityUser?.Id is null) return string.Empty;
var result = await identityService.UpdateCurrentUserAsync(identityUser.Id, request.FirstName, request.LastName, var result = await identityService.UpdateCurrentUserAsync(
request.Occupation, request.PhoneNumber, request.BirthDate, identityUser.Id,
request.Country, request.City, request.Address, request.About, request.FirstName,
request.Description, request.SocialNetworks); request.LastName,
request.Occupation,
request.PhoneNumber,
request.BirthDate,
request.Country,
request.City,
request.Address,
request.About,
request.Description,
request.SocialNetworks,
request.PortraitUrl);
await context.SaveChangesAsync(cancellationToken); await context.SaveChangesAsync(cancellationToken);
return result.GetValueOrDefault(); return result.GetValueOrDefault();
} }
} }

View File

@@ -65,7 +65,12 @@ public class ApplicationDbContextInitializer(
} }
// Default users // Default users
var administrator = new ApplicationUser { UserName = "administrator@localhost", Email = "administrator@localhost" }; var administrator = new ApplicationUser
{
UserName = "administrator@localhost",
Email = "administrator@localhost",
PortraitUrl = "images/usersmedia/anonyme/profilepictures/profilePascal.jpg"
};
if (userManager.Users.All(u => u.UserName != administrator.UserName)) if (userManager.Users.All(u => u.UserName != administrator.UserName))
{ {

View File

@@ -15,4 +15,5 @@ public class ApplicationUser : IdentityUser
public string About { get; set; } = string.Empty; public string About { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty; public string Description { get; set; } = string.Empty;
public SocialNetworks SocialNetworks { get; set; } = new(); public SocialNetworks SocialNetworks { get; set; } = new();
public string? PortraitUrl { get; set; }
} }

View File

@@ -20,7 +20,7 @@ public class IdentityService(
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
IHttpContextAccessor contextAccessor, IHttpContextAccessor contextAccessor,
IConfiguration configuration IConfiguration configuration
) )
: IIdentityService : IIdentityService
{ {
public async Task<string?> GetUserNameAsync(string userId) public async Task<string?> GetUserNameAsync(string userId)
@@ -29,11 +29,11 @@ public class IdentityService(
return user?.UserName; return user?.UserName;
} }
public async Task<UserModel?> GetUserByUserNameAsync(string userName) public async Task<UserModel?> GetUserByUserNameAsync(string userName)
{ {
var response = await userManager.FindByNameAsync(userName); var response = await userManager.FindByNameAsync(userName);
if (response == null) return null; if (response == null) return null;
var userModel = new UserModel() var userModel = new UserModel()
@@ -42,12 +42,13 @@ public class IdentityService(
UserName = response.UserName, UserName = response.UserName,
FirstName = response.FirstName, FirstName = response.FirstName,
LastName = response.LastName, LastName = response.LastName,
Email = response.Email, Email = response.Email,
PortraitUrl = response.PortraitUrl,
}; };
return userModel; return userModel;
} }
public async Task<Result<string>> CreateUserAsync(Userinfo userInfo) public async Task<Result<string>> CreateUserAsync(Userinfo userInfo)
{ {
var applicationUser = new ApplicationUser var applicationUser = new ApplicationUser
@@ -57,7 +58,7 @@ public class IdentityService(
FirstName = userInfo.GivenName, FirstName = userInfo.GivenName,
LastName = userInfo.FamilyName LastName = userInfo.FamilyName
}; };
var password = Guid.NewGuid().ToString("N")[..32]; var password = Guid.NewGuid().ToString("N")[..32];
var identityResult = await userManager.CreateAsync(applicationUser, password); var identityResult = await userManager.CreateAsync(applicationUser, password);
@@ -65,13 +66,14 @@ public class IdentityService(
var applicationResult = identityResult.ToApplicationResult(); var applicationResult = identityResult.ToApplicationResult();
var result = new Result<string>(applicationResult.Succeeded, applicationResult.Errors); var result = new Result<string>(applicationResult.Succeeded, applicationResult.Errors);
result.Value = applicationUser.Id; result.Value = applicationUser.Id;
return result; return result;
} }
public async Task<Result<string>> CreateUserAsync(string email, string userName, string firstName, string lastName, string password) public async Task<Result<string>> CreateUserAsync(string email, string userName, string firstName, string lastName,
string password)
{ {
var applicationUser = new ApplicationUser var applicationUser = new ApplicationUser
{ {
@@ -82,16 +84,24 @@ public class IdentityService(
}; };
var response = await userManager.CreateAsync(applicationUser, password); var response = await userManager.CreateAsync(applicationUser, password);
var result = new Result<string>(response.Succeeded, response.ToApplicationResult().Errors); var result = new Result<string>(response.Succeeded, response.ToApplicationResult().Errors);
result.Value = applicationUser.Id; result.Value = applicationUser.Id;
return result; return result;
} }
public async Task<Result<string>> UpdateCurrentUserAsync(string id, string firstName, string lastName, string occupation, public async Task<Result<string>> UpdateCurrentUserAsync(string id, string firstName, string lastName,
string phoneNumber, string birthDate, string country, string city, string address, string about, string description, string occupation,
SocialNetworksModel socialNetworks) string phoneNumber,
string birthDate,
string country,
string city,
string address,
string about,
string description,
SocialNetworksModel socialNetworks,
string? portraitUrl)
{ {
var applicationUser = await userManager.FindByIdAsync(id); var applicationUser = await userManager.FindByIdAsync(id);
@@ -107,6 +117,7 @@ public class IdentityService(
applicationUser.Address = address; applicationUser.Address = address;
applicationUser.About = about; applicationUser.About = about;
applicationUser.Description = description; applicationUser.Description = description;
applicationUser.PortraitUrl = portraitUrl;
applicationUser.SocialNetworks = new SocialNetworks() applicationUser.SocialNetworks = new SocialNetworks()
{ {
FacebookUrl = socialNetworks.FacebookUrl, FacebookUrl = socialNetworks.FacebookUrl,
@@ -130,7 +141,7 @@ public class IdentityService(
return result; return result;
} }
public async Task<UserModel?> FindUserByIdAsync(string id) public async Task<UserModel?> FindUserByIdAsync(string id)
{ {
var response = await userManager.FindByIdAsync(id); var response = await userManager.FindByIdAsync(id);
@@ -152,6 +163,7 @@ public class IdentityService(
Address = response.Address, Address = response.Address,
About = response.About, About = response.About,
Description = response.Description, Description = response.Description,
PortraitUrl = response.PortraitUrl,
SocialNetworks = new SocialNetworksModel SocialNetworks = new SocialNetworksModel
{ {
FacebookUrl = response.SocialNetworks.FacebookUrl, FacebookUrl = response.SocialNetworks.FacebookUrl,
@@ -167,7 +179,7 @@ public class IdentityService(
return userModel; return userModel;
} }
public async Task<UserModel?> GetCurrentUserAsync() public async Task<UserModel?> GetCurrentUserAsync()
{ {
var currentUserId = contextAccessor.HttpContext?.User.FindFirst(ClaimTypes.NameIdentifier)?.Value; var currentUserId = contextAccessor.HttpContext?.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
@@ -203,7 +215,7 @@ public class IdentityService(
return user != null && await userManager.IsInRoleAsync(user, role); return user != null && await userManager.IsInRoleAsync(user, role);
} }
public async Task<bool> CurrentUserIsInRoleAsync(string role) public async Task<bool> CurrentUserIsInRoleAsync(string role)
{ {
var currentUserModel = await GetCurrentUserAsync(); var currentUserModel = await GetCurrentUserAsync();
@@ -241,44 +253,45 @@ public class IdentityService(
return result.ToApplicationResult(); return result.ToApplicationResult();
} }
public async Task<Result> AddRoleAsync(string userId, string role) public async Task<Result> AddRoleAsync(string userId, string role)
{ {
var hasAdminAccess = await CurrentUserIsInRoleAsync("Administrator"); 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); 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); var result = await userManager.AddToRoleAsync(user, role);
return result.ToApplicationResult(); return result.ToApplicationResult();
} }
public async Task<IList<string>> GetCurrentUserRolesAsync() public async Task<IList<string>> GetCurrentUserRolesAsync()
{ {
var currentUserModel = await GetCurrentUserAsync(); var currentUserModel = await GetCurrentUserAsync();
var currentUser = await userManager.FindByIdAsync(currentUserModel?.Id ?? ""); var currentUser = await userManager.FindByIdAsync(currentUserModel?.Id ?? "");
if (currentUser is null) return []; if (currentUser is null) return [];
var userRoles = await userManager.GetRolesAsync(currentUser); var userRoles = await userManager.GetRolesAsync(currentUser);
return userRoles; return userRoles;
} }
public async Task<string?> LoginAsync(string userName, string password) 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) if (!result.Succeeded)
{ {
return null; return null;
} }
var user = await GetUserByUserNameAsync(userName); var user = await GetUserByUserNameAsync(userName);
if (user is null) throw new InvalidOperationException(); if (user is null) throw new InvalidOperationException();
@@ -298,3 +311,6 @@ public class IdentityService(
return token; return token;
} }
} }
public class ConfigurationMissingException(string ConfigurationKey)
: Exception;

View File

@@ -0,0 +1,500 @@
// <auto-generated />
using System;
using Hutopy.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Hutopy.Infrastructure.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20240701072549_AddPortraitUrlToUser")]
partial class AddPortraitUrlToUser
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("Hutopy.Domain.Entities.FutureCreator", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTimeOffset>("Created")
.HasColumnType("datetimeoffset");
b.Property<string>("CreatedBy")
.HasColumnType("nvarchar(max)");
b.Property<string>("EmailAddress")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTimeOffset>("LastModified")
.HasColumnType("datetimeoffset");
b.Property<string>("LastModifiedBy")
.HasColumnType("nvarchar(max)");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PhoneNumber")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ReasonToJoin")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("SocialNetworkAccount")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("FutureCreators");
});
modelBuilder.Entity("Hutopy.Domain.Entities.UserTransaction", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<decimal>("Amount")
.HasPrecision(18, 2)
.HasColumnType("decimal(18,2)");
b.Property<string>("ApplicationUserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.Property<DateTimeOffset>("Created")
.HasColumnType("datetimeoffset");
b.Property<string>("CreatedBy")
.HasColumnType("nvarchar(max)");
b.Property<string>("Currency")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsConfirmed")
.HasColumnType("bit");
b.Property<DateTimeOffset>("LastModified")
.HasColumnType("datetimeoffset");
b.Property<string>("LastModifiedBy")
.HasColumnType("nvarchar(max)");
b.Property<bool>("Paid")
.HasColumnType("bit");
b.Property<string>("StripeBillingDetailEmail")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripeBillingDetailName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripeChargeId")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripeEventId")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripePaymentIntent")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripePaymentMethod")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripeReceiptUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("TipMessage")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("ApplicationUserId");
b.ToTable("UserTransactions");
});
modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<string>("About")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("Address")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("BirthDate")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("City")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Country")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("bit");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("bit");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("Occupation")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PasswordHash")
.HasColumnType("nvarchar(max)");
b.Property<string>("PhoneNumber")
.HasColumnType("nvarchar(max)");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("bit");
b.Property<string>("PortraitUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("SecurityStamp")
.HasColumnType("nvarchar(max)");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("bit");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex")
.HasFilter("[NormalizedUserName] IS NOT NULL");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex")
.HasFilter("[NormalizedName] IS NOT NULL");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(450)");
b.Property<string>("ProviderKey")
.HasColumnType("nvarchar(450)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("RoleId")
.HasColumnType("nvarchar(450)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(450)");
b.Property<string>("Name")
.HasColumnType("nvarchar(450)");
b.Property<string>("Value")
.HasColumnType("nvarchar(max)");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Hutopy.Domain.Entities.UserTransaction", b =>
{
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("ApplicationUserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b =>
{
b.OwnsOne("Hutopy.Infrastructure.Identity.OwnedEntities.SocialNetworks", "SocialNetworks", b1 =>
{
b1.Property<string>("ApplicationUserId")
.HasColumnType("nvarchar(450)");
b1.Property<string>("FacebookUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("InstagramUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("LinkedInUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("RedditUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("TikTokUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("XUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("YourWebsiteUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("YoutubeUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.HasKey("ApplicationUserId");
b1.ToTable("ApplicationUser_SocialNetworks", (string)null);
b1.WithOwner()
.HasForeignKey("ApplicationUserId");
});
b.Navigation("SocialNetworks")
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Hutopy.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class AddPortraitUrlToUser : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "PortraitUrl",
table: "AspNetUsers",
type: "nvarchar(max)",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "PortraitUrl",
table: "AspNetUsers");
}
}
}

View File

@@ -222,6 +222,9 @@ namespace Hutopy.Infrastructure.Migrations
b.Property<bool>("PhoneNumberConfirmed") b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("bit"); .HasColumnType("bit");
b.Property<string>("PortraitUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("SecurityStamp") b.Property<string>("SecurityStamp")
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");

View File

@@ -7,8 +7,15 @@ namespace Hutopy.Infrastructure.Utils;
public static class JwtTokenHelper public static class JwtTokenHelper
{ {
public static string GenerateJwtToken(string issuer, string audience, string key, string? userId, string? email, public static string GenerateJwtToken(
string? firstname, string? lastname, string? portraitUrl) string issuer,
string audience,
string key,
string? userId,
string? email,
string? firstname,
string? lastname,
string? portraitUrl)
{ {
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)); var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
@@ -19,7 +26,8 @@ public static class JwtTokenHelper
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, userId), new Claim(ClaimTypes.NameIdentifier, userId),
new Claim(ClaimTypes.Email, email), new Claim(ClaimTypes.Email, email),
new Claim(ClaimTypes.GivenName, firstname), new Claim(ClaimTypes.Name, email),
new Claim(ClaimTypes.GivenName, firstname),
new Claim(ClaimTypes.Surname, lastname), new Claim(ClaimTypes.Surname, lastname),
}); });