diff --git a/Controllers/AuthController.cs b/Controllers/AuthController.cs index 511910e..87b3a21 100644 --- a/Controllers/AuthController.cs +++ b/Controllers/AuthController.cs @@ -70,7 +70,7 @@ public class AuthController : ControllerBase if (hashedFormPassword == user.PasswordHash) { // All set - generate the token and return it - var token = guhf.GenerateJwtToken(formUser.Email); + var token = guhf.GenerateJwtToken(user); SuccessfulLoginDTO response = user.ToSuccessfulLoginDTO(token); return Ok(response); diff --git a/Controllers/GeneralUseHelperFunctions.cs b/Controllers/GeneralUseHelperFunctions.cs index deb1ac6..70411b5 100644 --- a/Controllers/GeneralUseHelperFunctions.cs +++ b/Controllers/GeneralUseHelperFunctions.cs @@ -32,11 +32,12 @@ public class GeneralUseHelpers(ApplicationDbContext db, IConfiguration appsettin } } - public string GenerateJwtToken(string username) + public string GenerateJwtToken(User user) { var claims = new[] { - new Claim(JwtRegisteredClaimNames.Sub, username), + new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()), + // new Claim(ClaimTypes.Role, ) new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) }; diff --git a/DTOs/UserInfoDTO.cs b/DTOs/UserInfoDTO.cs index 8c1c416..548168d 100644 --- a/DTOs/UserInfoDTO.cs +++ b/DTOs/UserInfoDTO.cs @@ -5,5 +5,6 @@ public record class UserInfoDTO public int Id { get; set; } required public string Name { get; set; } required public string Email { get; set; } + public int Role { get; set; } }; diff --git a/Entities/User.cs b/Entities/User.cs index d35a09a..dd04b38 100644 --- a/Entities/User.cs +++ b/Entities/User.cs @@ -5,6 +5,7 @@ namespace QuotifyBE.Entities public int Id { get; set; } required public string Name { get; set; } required public string Email { get; set; } + public int Role { get; set; } required public string PasswordHash { get; set; } } } diff --git a/Mapping/UserMapping.cs b/Mapping/UserMapping.cs index 362311b..81dbc15 100644 --- a/Mapping/UserMapping.cs +++ b/Mapping/UserMapping.cs @@ -23,7 +23,8 @@ public static class UserMapping { Id = user.Id, Name = user.Name, - Email = user.Email + Email = user.Email, + Role = user.Role }; } } diff --git a/Migrations/20250717083328_user_roles.Designer.cs b/Migrations/20250717083328_user_roles.Designer.cs new file mode 100644 index 0000000..cac6fd8 --- /dev/null +++ b/Migrations/20250717083328_user_roles.Designer.cs @@ -0,0 +1,183 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using QuotifyBE.Data; + +#nullable disable + +namespace QuotifyBE.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20250717083328_user_roles")] + partial class user_roles + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("QuotifyBE.Entities.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("QuotifyBE.Entities.Image", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Url") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("QuotifyBE.Entities.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Author") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ImageId") + .HasColumnType("integer"); + + b.Property("LastUpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Text") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.HasIndex("UserId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("QuotifyBE.Entities.QuoteCategory", b => + { + b.Property("QuoteId") + .HasColumnType("integer"); + + b.Property("CategoryId") + .HasColumnType("integer"); + + b.HasKey("QuoteId", "CategoryId"); + + b.HasIndex("CategoryId"); + + b.ToTable("QuoteCategories"); + }); + + modelBuilder.Entity("QuotifyBE.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("text"); + + b.Property("Role") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("QuotifyBE.Entities.Quote", b => + { + b.HasOne("QuotifyBE.Entities.Image", "Image") + .WithMany() + .HasForeignKey("ImageId"); + + b.HasOne("QuotifyBE.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Image"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("QuotifyBE.Entities.QuoteCategory", b => + { + b.HasOne("QuotifyBE.Entities.Category", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("QuotifyBE.Entities.Quote", "Quote") + .WithMany("QuoteCategories") + .HasForeignKey("QuoteId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Quote"); + }); + + modelBuilder.Entity("QuotifyBE.Entities.Quote", b => + { + b.Navigation("QuoteCategories"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Migrations/20250717083328_user_roles.cs b/Migrations/20250717083328_user_roles.cs new file mode 100644 index 0000000..6a70d92 --- /dev/null +++ b/Migrations/20250717083328_user_roles.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace QuotifyBE.Migrations +{ + /// + public partial class user_roles : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Role", + table: "Users", + type: "integer", + nullable: false, + defaultValue: 0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Role", + table: "Users"); + } + } +} diff --git a/Migrations/ApplicationDbContextModelSnapshot.cs b/Migrations/ApplicationDbContextModelSnapshot.cs index 0876095..34f29bc 100644 --- a/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/Migrations/ApplicationDbContextModelSnapshot.cs @@ -126,6 +126,9 @@ namespace QuotifyBE.Migrations .IsRequired() .HasColumnType("text"); + b.Property("Role") + .HasColumnType("integer"); + b.HasKey("Id"); b.ToTable("Users");