Commit 00408ab3 authored by Almouhannad's avatar Almouhannad

(B) Add identity classes, link them to DB

parent 1c65ec94
using Domain.Primitives;
namespace Domain.Entities.Identity.UserRoles;
public sealed class Role : Entity
{
#region Private ctor
private Role(int id) : base(id)
{
}
private Role(int id, string name) : base(id)
{
Name = name;
}
#endregion
#region Properties
public string Name { get; private set; } = null!;
#endregion
#region Methods
#region Static factory
internal static Role Create(int id, string name)
{
return new Role(id, name);
}
#endregion
#endregion
}
namespace Domain.Entities.Identity.UserRoles;
public static class Roles
{
#region Constant values
public static int Count => 3;
public static Role Admin => Role.Create(1, "admin");
public static Role Doctor => Role.Create(2, "doctor");
public static Role Receptionist => Role.Create(3, "receptionist");
public static List<Role> GetAll()
{
List<Role> roles = new();
roles.Add(Admin);
roles.Add(Doctor);
roles.Add(Receptionist);
return roles;
}
#endregion
}
using Domain.Entities.Identity.UserRoles;
using Domain.Entities.People.Doctors;
using Domain.Primitives;
using Domain.Shared;
namespace Domain.Entities.Identity.Users;
public sealed class DoctorUser : Entity
{
#region Private ctor
private DoctorUser(int id) : base(id)
{
}
private DoctorUser(int id, User user, Doctor doctor) : base(id)
{
User = user;
Doctor = doctor;
}
#endregion
#region Properties
public User User { get; private set; } = null!;
public Doctor Doctor { get; private set; } = null!;
#endregion
#region Methods
#region Static factory
public static Result<DoctorUser> Create (
string username, string hashedPassword, // User details
string firstName, string middleName, string lastName // Doctor details
)
{
Result<Doctor> doctorResult = Doctor.Create(firstName, middleName, lastName);
if (doctorResult.IsFailure)
return Result.Failure<DoctorUser>(doctorResult.Error);
Result<User> userResult = User.Create(username, hashedPassword, Roles.Doctor.Name);
if (userResult.IsFailure)
return Result.Failure<DoctorUser>(userResult.Error);
return new DoctorUser(0, userResult.Value, doctorResult.Value);
}
#endregion
#endregion
}
using Domain.Entities.Identity.UserRoles;
using Domain.Entities.People.Shared;
using Domain.Primitives;
using Domain.Shared;
namespace Domain.Entities.Identity.Users;
public sealed class ReceptionistUser : Entity
{
#region Private ctor
private ReceptionistUser(int id) : base(id)
{
}
private ReceptionistUser(int id, User user, PersonalInfo personalInfo) : base(id)
{
User = user;
PersonalInfo = personalInfo;
}
#endregion
#region Properties
public User User { get; private set; } = null!;
public PersonalInfo PersonalInfo { get; private set; } = null!;
#endregion
#region Methods
#region Static factory
public static Result<ReceptionistUser> Create(
string userName, string hashedPassword,
string firstName, string middleName, string lastName
)
{
Result<PersonalInfo> personalInfoResult = PersonalInfo.Create(firstName, middleName, lastName);
if (personalInfoResult.IsFailure)
return Result.Failure<ReceptionistUser>(personalInfoResult.Error);
Result<User> userResult = User.Create(userName, hashedPassword, Roles.Receptionist.Name);
if (userResult.IsFailure)
return Result.Failure<ReceptionistUser>(userResult.Error);
return new ReceptionistUser(0, userResult.Value, personalInfoResult.Value);
}
#endregion
#endregion
}
using Domain.Entities.Identity.UserRoles;
using Domain.Errors;
using Domain.Primitives;
using Domain.Shared;
namespace Domain.Entities.Identity.Users;
public sealed class User : Entity
{
#region Private ctor
private User(int id) : base(id)
{
}
private User(int id, string userName, string hashedPassword, Role role) : base(id)
{
UserName = userName;
HashedPassword = hashedPassword;
Role = role;
}
#endregion
#region Properties
public string UserName { get; private set; } = null!;
public string HashedPassword { get; private set; } = null!;
public Role Role { get; private set; } = null!;
#endregion
#region Methods
public static Result<User> Create(string userName, string hashedPassword, string role)
{
if (userName is null || hashedPassword is null || role is null)
{
return Result.Failure<User>(DomainErrors.InvalidValuesError);
}
#region Check role
Result<Role> selectedRole = Result.Failure<Role>(IdentityErrors.InvalidRole);
List<Role> roles = Roles.GetAll();
foreach (Role roleItem in roles)
{
if (roleItem.Name == role)
selectedRole = roleItem;
}
if (selectedRole.IsFailure)
return Result.Failure<User>(selectedRole.Error);
#endregion
return new User(0, userName, hashedPassword, selectedRole.Value);
}
#endregion
}
using Domain.Shared;
namespace Domain.Errors;
public static class IdentityErrors
{
public static Error InvalidRole => new("Identity.InvalidRole", "Role specified for user is invalid");
}
using Domain.Entities.Identity.UserRoles;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Persistence.Configurations.Identity.Roles;
public class RoleConfiguration : IEntityTypeConfiguration<Role>
{
public void Configure(EntityTypeBuilder<Role> builder)
{
builder.ToTable(nameof(Role));
builder.Property(role => role.Name)
.HasMaxLength(50);
builder.HasIndex(role => role.Name)
.IsUnique();
}
}
using Domain.Entities.Identity.Users;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Persistence.Configurations.Identity.Users;
public class DoctorUserConfiguration : IEntityTypeConfiguration<DoctorUser>
{
public void Configure(EntityTypeBuilder<DoctorUser> builder)
{
builder.ToTable(nameof(DoctorUser));
builder.Property(doctorUser => doctorUser.Id).ValueGeneratedOnAdd();
builder.HasOne(doctorUser => doctorUser.User)
.WithOne()
.HasForeignKey<DoctorUser>(doctorUser => doctorUser.Id)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(doctorUser => doctorUser.Doctor)
.WithOne()
.HasForeignKey<DoctorUser>("DoctorId")
.OnDelete(DeleteBehavior.NoAction);
}
}
using Domain.Entities.Identity.Users;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Persistence.Configurations.Identity.Users;
public class ReceptionistUserConfiguration : IEntityTypeConfiguration<ReceptionistUser>
{
public void Configure(EntityTypeBuilder<ReceptionistUser> builder)
{
builder.ToTable(nameof(ReceptionistUser));
builder.Property(receptionistUser => receptionistUser.Id).ValueGeneratedOnAdd();
builder.HasOne(receptionistUser => receptionistUser.User)
.WithOne()
.HasForeignKey<ReceptionistUser>(receptionistUser => receptionistUser.Id)
.OnDelete(DeleteBehavior.NoAction);
builder.HasOne(receptionistUser => receptionistUser.PersonalInfo)
.WithOne()
.HasForeignKey<ReceptionistUser>("PersonalInfoId")
.OnDelete(DeleteBehavior.NoAction);
}
}
using Domain.Entities.Identity.Users;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Persistence.Configurations.Identity.Users;
public class UserConfiguration : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
builder.ToTable(nameof(User));
builder.HasIndex(user => user.UserName)
.IsUnique();
builder.HasOne(user => user.Role)
.WithMany()
.HasForeignKey("RoleId");
}
}
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Persistence.Migrations
{
/// <inheritdoc />
public partial class Add_Identity : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Role",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Role", x => x.Id);
});
migrationBuilder.CreateTable(
name: "User",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
UserName = table.Column<string>(type: "nvarchar(450)", nullable: false),
HashedPassword = table.Column<string>(type: "nvarchar(max)", nullable: false),
RoleId = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_User", x => x.Id);
table.ForeignKey(
name: "FK_User_Role_RoleId",
column: x => x.RoleId,
principalTable: "Role",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "DoctorUser",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false),
DoctorId = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DoctorUser", x => x.Id);
table.ForeignKey(
name: "FK_DoctorUser_Doctor_DoctorId",
column: x => x.DoctorId,
principalTable: "Doctor",
principalColumn: "Id");
table.ForeignKey(
name: "FK_DoctorUser_User_Id",
column: x => x.Id,
principalTable: "User",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "ReceptionistUser",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false),
PersonalInfoId = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ReceptionistUser", x => x.Id);
table.ForeignKey(
name: "FK_ReceptionistUser_PersonalInfo_PersonalInfoId",
column: x => x.PersonalInfoId,
principalTable: "PersonalInfo",
principalColumn: "Id");
table.ForeignKey(
name: "FK_ReceptionistUser_User_Id",
column: x => x.Id,
principalTable: "User",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_DoctorUser_DoctorId",
table: "DoctorUser",
column: "DoctorId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_ReceptionistUser_PersonalInfoId",
table: "ReceptionistUser",
column: "PersonalInfoId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Role_Name",
table: "Role",
column: "Name",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_User_RoleId",
table: "User",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "IX_User_UserName",
table: "User",
column: "UserName",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "DoctorUser");
migrationBuilder.DropTable(
name: "ReceptionistUser");
migrationBuilder.DropTable(
name: "User");
migrationBuilder.DropTable(
name: "Role");
}
}
}
...@@ -22,6 +22,90 @@ namespace Persistence.Migrations ...@@ -22,6 +22,90 @@ namespace Persistence.Migrations
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("Domain.Entities.Identity.UserRoles.Role", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Role", (string)null);
});
modelBuilder.Entity("Domain.Entities.Identity.Users.DoctorUser", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("DoctorId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("DoctorId")
.IsUnique();
b.ToTable("DoctorUser", (string)null);
});
modelBuilder.Entity("Domain.Entities.Identity.Users.ReceptionistUser", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("PersonalInfoId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("PersonalInfoId")
.IsUnique();
b.ToTable("ReceptionistUser", (string)null);
});
modelBuilder.Entity("Domain.Entities.Identity.Users.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("HashedPassword")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("RoleId")
.HasColumnType("int");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.HasIndex("UserName")
.IsUnique();
b.ToTable("User", (string)null);
});
modelBuilder.Entity("Domain.Entities.Medicals.Diseases.Disease", b => modelBuilder.Entity("Domain.Entities.Medicals.Diseases.Disease", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
...@@ -624,6 +708,55 @@ namespace Persistence.Migrations ...@@ -624,6 +708,55 @@ namespace Persistence.Migrations
b.ToTable("EmployeeEmployee"); b.ToTable("EmployeeEmployee");
}); });
modelBuilder.Entity("Domain.Entities.Identity.Users.DoctorUser", b =>
{
b.HasOne("Domain.Entities.People.Doctors.Doctor", "Doctor")
.WithOne()
.HasForeignKey("Domain.Entities.Identity.Users.DoctorUser", "DoctorId")
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
b.HasOne("Domain.Entities.Identity.Users.User", "User")
.WithOne()
.HasForeignKey("Domain.Entities.Identity.Users.DoctorUser", "Id")
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
b.Navigation("Doctor");
b.Navigation("User");
});
modelBuilder.Entity("Domain.Entities.Identity.Users.ReceptionistUser", b =>
{
b.HasOne("Domain.Entities.Identity.Users.User", "User")
.WithOne()
.HasForeignKey("Domain.Entities.Identity.Users.ReceptionistUser", "Id")
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
b.HasOne("Domain.Entities.People.Shared.PersonalInfo", "PersonalInfo")
.WithOne()
.HasForeignKey("Domain.Entities.Identity.Users.ReceptionistUser", "PersonalInfoId")
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
b.Navigation("PersonalInfo");
b.Navigation("User");
});
modelBuilder.Entity("Domain.Entities.Identity.Users.User", b =>
{
b.HasOne("Domain.Entities.Identity.UserRoles.Role", "Role")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Role");
});
modelBuilder.Entity("Domain.Entities.Medicals.Medicines.Medicine", b => modelBuilder.Entity("Domain.Entities.Medicals.Medicines.Medicine", b =>
{ {
b.HasOne("Domain.Entities.Medicals.Medicines.MedicineFormValues.MedicineForm", "MedicineForm") b.HasOne("Domain.Entities.Medicals.Medicines.MedicineFormValues.MedicineForm", "MedicineForm")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment