Init
This commit is contained in:
commit
07531425f2
19
.gitignore
vendored
Normal file
19
.gitignore
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
ApplicationHub/bin
|
||||||
|
ApplicationHub/obj
|
||||||
|
ApplicationHub/*.db
|
||||||
|
|
||||||
|
ApplicationHub.Data.EF/bin
|
||||||
|
ApplicationHub.Data.EF/obj
|
||||||
|
ApplicationHub.Data.EF/*.db
|
||||||
|
|
||||||
|
ApplicationHub.Data.InMemory/bin
|
||||||
|
ApplicationHub.Data.InMemory/obj
|
||||||
|
|
||||||
|
ApplicationHub.Domain/bin
|
||||||
|
ApplicationHub.Domain/obj
|
||||||
|
|
||||||
|
ApplicationHub.Domain.Contracts/bin
|
||||||
|
ApplicationHub.Domain.Contracts/obj
|
||||||
24
ApplicationHub.Data.EF/ApplicationHub.Data.EF.csproj
Normal file
24
ApplicationHub.Data.EF/ApplicationHub.Data.EF.csproj
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AutoMapper" Version="12.0.1" />
|
||||||
|
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.8">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="9.0.8" />
|
||||||
|
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\ApplicationHub.Domain.Contracts\ApplicationHub.Domain.Contracts.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
using ApplicationHub.Data.EF.Authentication.Entities;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Authentication;
|
||||||
|
|
||||||
|
public class AuthenticationDataContext(DbContextOptions options) : DbContext(options)
|
||||||
|
{
|
||||||
|
public DbSet<UserEntity> Users { get; set; }
|
||||||
|
public DbSet<GroupEntity> Groups { get; set; }
|
||||||
|
public DbSet<RightEntity> Rights { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Design;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Authentication;
|
||||||
|
|
||||||
|
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<AuthenticationDataContext>
|
||||||
|
{
|
||||||
|
public AuthenticationDataContext CreateDbContext(string[] args)
|
||||||
|
{
|
||||||
|
var optionsBuilder = new DbContextOptionsBuilder<AuthenticationDataContext>();
|
||||||
|
optionsBuilder.UseSqlite("Data Source=Authentication.db");
|
||||||
|
return new AuthenticationDataContext(optionsBuilder.Options);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Authentication.Entities;
|
||||||
|
|
||||||
|
public class GroupEntity
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
[MaxLength(255)]
|
||||||
|
public required string Name { get; set; }
|
||||||
|
public List<RightEntity>? Rights { get; set; }
|
||||||
|
public List<UserEntity>? Users { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Authentication.Entities;
|
||||||
|
|
||||||
|
public class RightEntity
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
[MaxLength(255)]
|
||||||
|
public required string Name { get; set; }
|
||||||
|
public List<GroupEntity>? Groups { get; set; }
|
||||||
|
}
|
||||||
16
ApplicationHub.Data.EF/Authentication/Entities/UserEntity.cs
Normal file
16
ApplicationHub.Data.EF/Authentication/Entities/UserEntity.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Authentication.Entities;
|
||||||
|
|
||||||
|
public class UserEntity
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
[MaxLength(255)]
|
||||||
|
public required string UserName { get; set; }
|
||||||
|
[MaxLength(255)]
|
||||||
|
public required string Email { get; set; }
|
||||||
|
[MaxLength(255)]
|
||||||
|
public string? PasswordHash { get; set; }
|
||||||
|
public bool Active { get; set; }
|
||||||
|
public List<GroupEntity>? Groups { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
using ApplicationHub.Domain.Contracts.Authentication;
|
||||||
|
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
|
using AutoMapper;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Authentication.Repositories;
|
||||||
|
|
||||||
|
public class UserRepository(AuthenticationDataContext authenticationDataContext, IMapper mapper) : IUserRepository
|
||||||
|
{
|
||||||
|
public User? GetUserByUserName(string userName)
|
||||||
|
{
|
||||||
|
return mapper.Map<List<User>>(
|
||||||
|
authenticationDataContext.Users
|
||||||
|
.Include(x => x.Groups)
|
||||||
|
.Where(x => x.UserName == userName && x.Active)
|
||||||
|
.ToList()
|
||||||
|
)
|
||||||
|
.FirstOrDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
20
ApplicationHub.Data.EF/Configuration/MappingProfile.cs
Normal file
20
ApplicationHub.Data.EF/Configuration/MappingProfile.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using ApplicationHub.Data.EF.Authentication.Entities;
|
||||||
|
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Configuration;
|
||||||
|
|
||||||
|
public class MappingProfile : Profile
|
||||||
|
{
|
||||||
|
public MappingProfile()
|
||||||
|
{
|
||||||
|
CreateMap<User, UserEntity>();
|
||||||
|
CreateMap<UserEntity, User>();
|
||||||
|
|
||||||
|
CreateMap<Group, GroupEntity>();
|
||||||
|
CreateMap<GroupEntity, Group>();
|
||||||
|
|
||||||
|
CreateMap<Right, RightEntity>();
|
||||||
|
CreateMap<RightEntity, Right>();
|
||||||
|
}
|
||||||
|
}
|
||||||
145
ApplicationHub.Data.EF/Migrations/20250809103237_InitDB.Designer.cs
generated
Normal file
145
ApplicationHub.Data.EF/Migrations/20250809103237_InitDB.Designer.cs
generated
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using ApplicationHub.Data.EF.Authentication;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(AuthenticationDataContext))]
|
||||||
|
[Migration("20250809103237_InitDB")]
|
||||||
|
partial class InitDB
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "9.0.8");
|
||||||
|
|
||||||
|
modelBuilder.Entity("ApplicationHub.Data.EF.Authentication.Entities.GroupEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Groups");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ApplicationHub.Data.EF.Authentication.Entities.RightEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Rights");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ApplicationHub.Data.EF.Authentication.Entities.UserEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("GroupEntityRightEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("GroupsId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<Guid>("RightsId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("GroupsId", "RightsId");
|
||||||
|
|
||||||
|
b.HasIndex("RightsId");
|
||||||
|
|
||||||
|
b.ToTable("GroupEntityRightEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("GroupEntityUserEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("GroupsId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<Guid>("UsersId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("GroupsId", "UsersId");
|
||||||
|
|
||||||
|
b.HasIndex("UsersId");
|
||||||
|
|
||||||
|
b.ToTable("GroupEntityUserEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("GroupEntityRightEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("ApplicationHub.Data.EF.Authentication.Entities.GroupEntity", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("ApplicationHub.Data.EF.Authentication.Entities.RightEntity", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RightsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("GroupEntityUserEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("ApplicationHub.Data.EF.Authentication.Entities.GroupEntity", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("ApplicationHub.Data.EF.Authentication.Entities.UserEntity", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UsersId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
158
ApplicationHub.Data.EF/Migrations/20250809103237_InitDB.cs
Normal file
158
ApplicationHub.Data.EF/Migrations/20250809103237_InitDB.cs
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class InitDB : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Groups",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
Name = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Groups", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Rights",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
Name = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Rights", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Users",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
UserName = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false),
|
||||||
|
Email = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false),
|
||||||
|
PasswordHash = table.Column<string>(type: "TEXT", maxLength: 255, nullable: true),
|
||||||
|
Active = table.Column<bool>(type: "INTEGER", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Users", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "GroupEntityRightEntity",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
GroupsId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
RightsId = table.Column<Guid>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_GroupEntityRightEntity", x => new { x.GroupsId, x.RightsId });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_GroupEntityRightEntity_Groups_GroupsId",
|
||||||
|
column: x => x.GroupsId,
|
||||||
|
principalTable: "Groups",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_GroupEntityRightEntity_Rights_RightsId",
|
||||||
|
column: x => x.RightsId,
|
||||||
|
principalTable: "Rights",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "GroupEntityUserEntity",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
GroupsId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
UsersId = table.Column<Guid>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_GroupEntityUserEntity", x => new { x.GroupsId, x.UsersId });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_GroupEntityUserEntity_Groups_GroupsId",
|
||||||
|
column: x => x.GroupsId,
|
||||||
|
principalTable: "Groups",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_GroupEntityUserEntity_Users_UsersId",
|
||||||
|
column: x => x.UsersId,
|
||||||
|
principalTable: "Users",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_GroupEntityRightEntity_RightsId",
|
||||||
|
table: "GroupEntityRightEntity",
|
||||||
|
column: "RightsId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_GroupEntityUserEntity_UsersId",
|
||||||
|
table: "GroupEntityUserEntity",
|
||||||
|
column: "UsersId");
|
||||||
|
|
||||||
|
var userAdminId = Guid.NewGuid();
|
||||||
|
var groupAdminId = Guid.NewGuid();
|
||||||
|
var groupUserId = Guid.NewGuid();
|
||||||
|
var groupGuestId = Guid.NewGuid();
|
||||||
|
var readRightId = Guid.NewGuid();
|
||||||
|
var writeRightId = Guid.NewGuid();
|
||||||
|
var deleteRightId = Guid.NewGuid();
|
||||||
|
|
||||||
|
migrationBuilder.InsertData("Rights", ["Id", "Name"], [readRightId, "READ"]);
|
||||||
|
migrationBuilder.InsertData("Rights", ["Id", "Name"], [writeRightId, "WRITE"]);
|
||||||
|
migrationBuilder.InsertData("Rights", ["Id", "Name"], [deleteRightId, "DELETE"]);
|
||||||
|
|
||||||
|
migrationBuilder.InsertData("Groups", ["Id", "Name"], [groupAdminId, "Group_Name_Administrator"]);
|
||||||
|
migrationBuilder.InsertData("Groups", ["Id", "Name"], [groupUserId, "Group_Name_User"]);
|
||||||
|
migrationBuilder.InsertData("Groups", ["Id", "Name"], [groupGuestId, "Group_Name_Guest"]);
|
||||||
|
|
||||||
|
migrationBuilder.InsertData("Users", ["Id", "UserName", "Email", "PasswordHash", "Active"], [userAdminId, "admin", "admin@example.de", "AQAAAAIAAYagAAAAEFTsFQQz1Yp6d2zw5iQ4AzNhQQ7QuvdhK3Y2kN/7wp97OXgB2fTrabYqGDYdFSMMkQ==", true]);
|
||||||
|
|
||||||
|
migrationBuilder.InsertData("GroupEntityRightEntity", ["GroupsId", "RightsId"], [groupAdminId, readRightId]);
|
||||||
|
migrationBuilder.InsertData("GroupEntityRightEntity", ["GroupsId", "RightsId"], [groupAdminId, writeRightId]);
|
||||||
|
migrationBuilder.InsertData("GroupEntityRightEntity", ["GroupsId", "RightsId"], [groupAdminId, deleteRightId]);
|
||||||
|
migrationBuilder.InsertData("GroupEntityRightEntity", ["GroupsId", "RightsId"], [groupUserId, readRightId]);
|
||||||
|
migrationBuilder.InsertData("GroupEntityRightEntity", ["GroupsId", "RightsId"], [groupUserId, writeRightId]);
|
||||||
|
migrationBuilder.InsertData("GroupEntityRightEntity", ["GroupsId", "RightsId"], [groupGuestId, readRightId]);
|
||||||
|
|
||||||
|
migrationBuilder.InsertData("GroupEntityUserEntity", ["GroupsId", "UsersId"], [groupAdminId, userAdminId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "GroupEntityRightEntity");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "GroupEntityUserEntity");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Rights");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Groups");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Users");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,142 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using ApplicationHub.Data.EF.Authentication;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(AuthenticationDataContext))]
|
||||||
|
partial class AuthenticationDataContextModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "9.0.8");
|
||||||
|
|
||||||
|
modelBuilder.Entity("ApplicationHub.Data.EF.Authentication.Entities.GroupEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Groups");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ApplicationHub.Data.EF.Authentication.Entities.RightEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Rights");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ApplicationHub.Data.EF.Authentication.Entities.UserEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("GroupEntityRightEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("GroupsId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<Guid>("RightsId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("GroupsId", "RightsId");
|
||||||
|
|
||||||
|
b.HasIndex("RightsId");
|
||||||
|
|
||||||
|
b.ToTable("GroupEntityRightEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("GroupEntityUserEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("GroupsId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<Guid>("UsersId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("GroupsId", "UsersId");
|
||||||
|
|
||||||
|
b.HasIndex("UsersId");
|
||||||
|
|
||||||
|
b.ToTable("GroupEntityUserEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("GroupEntityRightEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("ApplicationHub.Data.EF.Authentication.Entities.GroupEntity", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("ApplicationHub.Data.EF.Authentication.Entities.RightEntity", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RightsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("GroupEntityUserEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("ApplicationHub.Data.EF.Authentication.Entities.GroupEntity", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("ApplicationHub.Data.EF.Authentication.Entities.UserEntity", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UsersId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\ApplicationHub.Domain.Contracts\ApplicationHub.Domain.Contracts.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AutoMapper" Version="12.0.1" />
|
||||||
|
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.InMemory.Authentication.Entities;
|
||||||
|
|
||||||
|
public class GroupDto
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
public List<RightDto> Rights { get; set; } = new();
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.InMemory.Authentication.Entities;
|
||||||
|
|
||||||
|
public class RightDto
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.InMemory.Authentication.Entities;
|
||||||
|
|
||||||
|
public class UserDto
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string UserName { get; set; } = "";
|
||||||
|
public string Email { get; set; } = "";
|
||||||
|
public string PasswordHash { get; set; } = "";
|
||||||
|
public bool Active { get; set; }
|
||||||
|
public List<GroupDto> Groups { get; set; } = new();
|
||||||
|
}
|
||||||
76
ApplicationHub.Data.InMemory/Authentication/Sources.cs
Normal file
76
ApplicationHub.Data.InMemory/Authentication/Sources.cs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
using ApplicationHub.Data.InMemory.Authentication.Entities;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.InMemory.Authentication;
|
||||||
|
|
||||||
|
internal static class RightData
|
||||||
|
{
|
||||||
|
public static List<RightDto> Source = new()
|
||||||
|
{
|
||||||
|
new RightDto
|
||||||
|
{
|
||||||
|
Id = Guid.Parse("5558D82C-B73B-42AD-9454-EF6FAB2E73EB"),
|
||||||
|
Name = "READ",
|
||||||
|
},
|
||||||
|
new RightDto
|
||||||
|
{
|
||||||
|
Id = Guid.Parse("5558D82C-B73B-42AD-9454-EF7FAB2E73EB"),
|
||||||
|
Name = "WRITE",
|
||||||
|
},
|
||||||
|
new RightDto
|
||||||
|
{
|
||||||
|
Id = Guid.Parse("5558D82C-B74B-42AD-9454-EF6FAB5E73EB"),
|
||||||
|
Name = "DELETE",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class GroupData
|
||||||
|
{
|
||||||
|
public static List<GroupDto> Source = new()
|
||||||
|
{
|
||||||
|
new GroupDto
|
||||||
|
{
|
||||||
|
Id = Guid.Parse("8888D82C-B73B-42AD-9454-EF6FAB2E73EB"),
|
||||||
|
Name = "Group_Name_Administrator",
|
||||||
|
Rights = RightData.Source
|
||||||
|
},
|
||||||
|
new GroupDto
|
||||||
|
{
|
||||||
|
Id = Guid.Parse("8588D82C-B73B-42AD-9454-EF6FAB2E73EB"),
|
||||||
|
Name = "Group_Name_User",
|
||||||
|
Rights = new List<RightDto>
|
||||||
|
{
|
||||||
|
RightData.Source.First(x => x.Name == "READ"),
|
||||||
|
RightData.Source.First(x => x.Name == "WRITE"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new GroupDto
|
||||||
|
{
|
||||||
|
Id = Guid.Parse("8845D82C-B73B-42AD-9454-EF6FAB2E73EB"),
|
||||||
|
Name = "Group_Name_Guest",
|
||||||
|
Rights = new List<RightDto>
|
||||||
|
{
|
||||||
|
RightData.Source.First(x => x.Name == "READ"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class UserData
|
||||||
|
{
|
||||||
|
public static List<UserDto> Source = new()
|
||||||
|
{
|
||||||
|
new UserDto
|
||||||
|
{
|
||||||
|
Id = Guid.Parse("9998D82C-B73B-42AD-9454-EF6FAB2E73EB"),
|
||||||
|
UserName = "admin",
|
||||||
|
Email = "admin@example.de",
|
||||||
|
PasswordHash = "AQAAAAIAAYagAAAAEFTsFQQz1Yp6d2zw5iQ4AzNhQQ7QuvdhK3Y2kN/7wp97OXgB2fTrabYqGDYdFSMMkQ==",
|
||||||
|
Active = true,
|
||||||
|
Groups = new List<GroupDto>
|
||||||
|
{
|
||||||
|
GroupData.Source.First(x => x.Name == "Group_Name_Administrator"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
using ApplicationHub.Domain.Contracts.Authentication;
|
||||||
|
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.InMemory.Authentication;
|
||||||
|
|
||||||
|
public class UserDataContext(IMapper mapper) : IUserRepository
|
||||||
|
{
|
||||||
|
public User? GetUserByUserName(string userName)
|
||||||
|
{
|
||||||
|
var result = UserData.Source
|
||||||
|
.Where(x => x.UserName == userName && x.Active)
|
||||||
|
.ToList();
|
||||||
|
return mapper.Map<List<User>>(result).FirstOrDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
20
ApplicationHub.Data.InMemory/Configuration/MappingProfile.cs
Normal file
20
ApplicationHub.Data.InMemory/Configuration/MappingProfile.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using ApplicationHub.Data.InMemory.Authentication.Entities;
|
||||||
|
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.InMemory.Configuration;
|
||||||
|
|
||||||
|
public class MappingProfile : Profile
|
||||||
|
{
|
||||||
|
public MappingProfile()
|
||||||
|
{
|
||||||
|
CreateMap<UserDto, User>();
|
||||||
|
CreateMap<User, UserDto>();
|
||||||
|
|
||||||
|
CreateMap<GroupDto, Group>();
|
||||||
|
CreateMap<Group, GroupDto>();
|
||||||
|
|
||||||
|
CreateMap<RightDto, Right>();
|
||||||
|
CreateMap<Right, RightDto>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Domain.Contracts.Authentication;
|
||||||
|
|
||||||
|
public interface IUserRepository
|
||||||
|
{
|
||||||
|
public User? GetUserByUserName(string userName);
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
|
|
||||||
|
public class Group
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
public IEnumerable<Right> Rights { get; set; } = new List<Right>();
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
|
|
||||||
|
public class Right
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
|
|
||||||
|
public class User
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string UserName { get; set; } = "";
|
||||||
|
public string Email { get; set; } = "";
|
||||||
|
public string PasswordHash { get; set; } = "";
|
||||||
|
public bool Active { get; set; }
|
||||||
|
public IEnumerable<Group> Groups { get; set; } = new List<Group>();
|
||||||
|
}
|
||||||
14
ApplicationHub.Domain/ApplicationHub.Domain.csproj
Normal file
14
ApplicationHub.Domain/ApplicationHub.Domain.csproj
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<RootNamespace>Adapter</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\ApplicationHub.Domain.Contracts\ApplicationHub.Domain.Contracts.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
using ApplicationHub.Domain.Contracts.Authentication;
|
||||||
|
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
|
|
||||||
|
namespace Adapter.Authentication.Services;
|
||||||
|
|
||||||
|
public class AuthenticationService(IUserRepository userRepository)
|
||||||
|
{
|
||||||
|
public User? GetUserByUserName(string userName)
|
||||||
|
{
|
||||||
|
return userRepository.GetUserByUserName(userName);
|
||||||
|
}
|
||||||
|
}
|
||||||
40
ApplicationHub.sln
Normal file
40
ApplicationHub.sln
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApplicationHub", "ApplicationHub\ApplicationHub.csproj", "{B7069D37-4899-44E1-BD11-2F8C66F49FF6}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApplicationHub.Domain", "ApplicationHub.Domain\ApplicationHub.Domain.csproj", "{D9E2D5BA-6543-4390-A6B1-C41A5FEED4AE}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApplicationHub.Data.InMemory", "ApplicationHub.Data.InMemory\ApplicationHub.Data.InMemory.csproj", "{E6D45245-FE75-4654-84DA-E6C630ADBD80}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApplicationHub.Domain.Contracts", "ApplicationHub.Domain.Contracts\ApplicationHub.Domain.Contracts.csproj", "{B81B0BC0-5FE4-4CA8-A28E-75203D08C941}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApplicationHub.Data.EF", "ApplicationHub.Data.EF\ApplicationHub.Data.EF.csproj", "{2E422B18-FBD8-4AEA-83F5-7BD6622D7DC4}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{B7069D37-4899-44E1-BD11-2F8C66F49FF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B7069D37-4899-44E1-BD11-2F8C66F49FF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B7069D37-4899-44E1-BD11-2F8C66F49FF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B7069D37-4899-44E1-BD11-2F8C66F49FF6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D9E2D5BA-6543-4390-A6B1-C41A5FEED4AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D9E2D5BA-6543-4390-A6B1-C41A5FEED4AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D9E2D5BA-6543-4390-A6B1-C41A5FEED4AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D9E2D5BA-6543-4390-A6B1-C41A5FEED4AE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{E6D45245-FE75-4654-84DA-E6C630ADBD80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{E6D45245-FE75-4654-84DA-E6C630ADBD80}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E6D45245-FE75-4654-84DA-E6C630ADBD80}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E6D45245-FE75-4654-84DA-E6C630ADBD80}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B81B0BC0-5FE4-4CA8-A28E-75203D08C941}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B81B0BC0-5FE4-4CA8-A28E-75203D08C941}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B81B0BC0-5FE4-4CA8-A28E-75203D08C941}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B81B0BC0-5FE4-4CA8-A28E-75203D08C941}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{2E422B18-FBD8-4AEA-83F5-7BD6622D7DC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{2E422B18-FBD8-4AEA-83F5-7BD6622D7DC4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2E422B18-FBD8-4AEA-83F5-7BD6622D7DC4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{2E422B18-FBD8-4AEA-83F5-7BD6622D7DC4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
21
ApplicationHub/ApplicationHub.csproj
Normal file
21
ApplicationHub/ApplicationHub.csproj
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\ApplicationHub.Data.EF\ApplicationHub.Data.EF.csproj" />
|
||||||
|
<ProjectReference Include="..\ApplicationHub.Data.InMemory\ApplicationHub.Data.InMemory.csproj" />
|
||||||
|
<ProjectReference Include="..\ApplicationHub.Domain\ApplicationHub.Domain.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.8" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.8" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
25
ApplicationHub/Configuration/AdapterConfiguration.cs
Normal file
25
ApplicationHub/Configuration/AdapterConfiguration.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using ApplicationHub.Data.EF.Authentication.Entities;
|
||||||
|
using ApplicationHub.Data.EF.Authentication.Repositories;
|
||||||
|
using ApplicationHub.Data.InMemory.Authentication;
|
||||||
|
using ApplicationHub.Data.InMemory.Authentication.Entities;
|
||||||
|
using ApplicationHub.Domain.Contracts.Authentication;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Configuration;
|
||||||
|
|
||||||
|
public static class AdapterConfiguration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Setup the used Adapter for this Application
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">the Web Application Builder from ASP .NET</param>
|
||||||
|
public static void Configure(WebApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
// use EF implementation
|
||||||
|
builder.Services.AddAutoMapper(typeof(UserEntity));
|
||||||
|
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
||||||
|
|
||||||
|
// use InMemory implementation
|
||||||
|
// builder.Services.AddScoped<IUserRepository, UserDataContext>();
|
||||||
|
// builder.Services.AddAutoMapper(typeof(UserDto));
|
||||||
|
}
|
||||||
|
}
|
||||||
34
ApplicationHub/Configuration/AuthenticationConfiguration.cs
Normal file
34
ApplicationHub/Configuration/AuthenticationConfiguration.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using System.Text;
|
||||||
|
using ApplicationHub.Models;
|
||||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Configuration;
|
||||||
|
|
||||||
|
public static class AuthenticationConfiguration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enable the JWT Authentication for the ASP .NET Service
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">the Web Application Builder from ASP .NET</param>
|
||||||
|
public static void Configure(WebApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
var jwtSettings = builder.Configuration.GetSection("JwtSettings");
|
||||||
|
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(x =>
|
||||||
|
{
|
||||||
|
x.TokenValidationParameters = new TokenValidationParameters
|
||||||
|
{
|
||||||
|
ValidIssuer = jwtSettings["Issuer"],
|
||||||
|
ValidAudience = jwtSettings["Audience"],
|
||||||
|
ValidateAudience = true,
|
||||||
|
ValidateIssuer = true,
|
||||||
|
ValidateIssuerSigningKey = true,
|
||||||
|
ValidateLifetime = true,
|
||||||
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["Key"] ?? "notSecure"))
|
||||||
|
};
|
||||||
|
});
|
||||||
|
builder.Services.AddAuthorization();
|
||||||
|
builder.Services.AddSingleton<IPasswordHasher<UserLogin>, PasswordHasher<UserLogin>>();
|
||||||
|
}
|
||||||
|
}
|
||||||
15
ApplicationHub/Configuration/ConfigFileConfiguration.cs
Normal file
15
ApplicationHub/Configuration/ConfigFileConfiguration.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using ApplicationHub.Models;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Configuration;
|
||||||
|
|
||||||
|
public static class ConfigFileConfiguration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Add some Configuration Values to the Dependency Injection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">the Web Application Builder from ASP .NET</param>
|
||||||
|
public static void Configure(WebApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
builder.Services.Configure<JwtSettings>(builder.Configuration.GetSection("JwtSettings"));
|
||||||
|
}
|
||||||
|
}
|
||||||
28
ApplicationHub/Configuration/DataContextConfiguration.cs
Normal file
28
ApplicationHub/Configuration/DataContextConfiguration.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using ApplicationHub.Data.EF.Authentication;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Configuration;
|
||||||
|
|
||||||
|
public static class DataContextConfiguration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Set the DataContexts for Dependency Injection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">the Web Application Builder from ASP .NET</param>
|
||||||
|
public static void Configure(WebApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
builder.Services.AddDbContext<AuthenticationDataContext>(o => o.UseSqlite(builder.Configuration.GetConnectionString("AuthenticationConnection")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs the DB Migrations <br/><br/>
|
||||||
|
/// Note: please run this after WebApplicationBuilder was build and before the Run of the WebApplication was called!
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="app">the builded WebApplication from ASP .NET</param>
|
||||||
|
public static void Migrate(WebApplication app)
|
||||||
|
{
|
||||||
|
using var scope = app.Services.CreateScope();
|
||||||
|
var db = scope.ServiceProvider.GetRequiredService<AuthenticationDataContext>();
|
||||||
|
db.Database.Migrate();
|
||||||
|
}
|
||||||
|
}
|
||||||
15
ApplicationHub/Configuration/ServiceConfiguration.cs
Normal file
15
ApplicationHub/Configuration/ServiceConfiguration.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Adapter.Authentication.Services;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Configuration;
|
||||||
|
|
||||||
|
public static class ServiceConfiguration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Add the Services from Domain the the Dependency Injection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">the Web Application Builder from ASP .NET</param>
|
||||||
|
public static void Configure(WebApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
builder.Services.AddScoped<AuthenticationService>();
|
||||||
|
}
|
||||||
|
}
|
||||||
58
ApplicationHub/Controllers/Authentication/LoginController.cs
Normal file
58
ApplicationHub/Controllers/Authentication/LoginController.cs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text;
|
||||||
|
using Adapter.Authentication.Services;
|
||||||
|
using ApplicationHub.Models;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Controllers.Authentication;
|
||||||
|
|
||||||
|
[Route("/api/login")]
|
||||||
|
[ApiController]
|
||||||
|
public class LoginController(AuthenticationService authenticationService, IOptions<JwtSettings> jwtSettings, IPasswordHasher<UserLogin> passwordHasher)
|
||||||
|
{
|
||||||
|
[HttpPost]
|
||||||
|
public string Login([FromBody] UserLogin login)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var foundUser = authenticationService.GetUserByUserName(login.UserName);
|
||||||
|
if (foundUser == null ||
|
||||||
|
passwordHasher.VerifyHashedPassword(login, foundUser.PasswordHash, login.Password) ==
|
||||||
|
PasswordVerificationResult.Failed)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(login), $"login password not matches or is invalid {foundUser?.PasswordHash ?? "<null>"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return GenerateJwtToken(login.UserName);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GenerateJwtToken(string username)
|
||||||
|
{
|
||||||
|
var claims = new[]
|
||||||
|
{
|
||||||
|
new Claim(JwtRegisteredClaimNames.Sub, username),
|
||||||
|
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
|
||||||
|
};
|
||||||
|
|
||||||
|
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Value.Key));
|
||||||
|
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
||||||
|
|
||||||
|
var token = new JwtSecurityToken(
|
||||||
|
issuer: jwtSettings.Value.Issuer,
|
||||||
|
audience: jwtSettings.Value.Audience,
|
||||||
|
claims: claims,
|
||||||
|
expires: DateTime.Now.AddMinutes(60),
|
||||||
|
signingCredentials: creds);
|
||||||
|
|
||||||
|
return new JwtSecurityTokenHandler().WriteToken(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
ApplicationHub/Controllers/Message/GreeterController.cs
Normal file
22
ApplicationHub/Controllers/Message/GreeterController.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Controllers.Message;
|
||||||
|
|
||||||
|
[Route("/api/greet")]
|
||||||
|
[ApiController]
|
||||||
|
public class GreeterController
|
||||||
|
{
|
||||||
|
[HttpGet("{name}")]
|
||||||
|
public string Greet(string name)
|
||||||
|
{
|
||||||
|
return $"Hello, {name}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
|
[HttpGet("internal")]
|
||||||
|
public string SecureGreet()
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
8
ApplicationHub/Models/JwtSettings.cs
Normal file
8
ApplicationHub/Models/JwtSettings.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace ApplicationHub.Models;
|
||||||
|
|
||||||
|
public class JwtSettings
|
||||||
|
{
|
||||||
|
public string Issuer { get; set; } = "";
|
||||||
|
public string Audience { get; set; } = "";
|
||||||
|
public string Key { get; set; } = "";
|
||||||
|
}
|
||||||
7
ApplicationHub/Models/UserLogin.cs
Normal file
7
ApplicationHub/Models/UserLogin.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace ApplicationHub.Models;
|
||||||
|
|
||||||
|
public class UserLogin
|
||||||
|
{
|
||||||
|
public string UserName { get; set; } = "";
|
||||||
|
public string Password { get; set; } = "";
|
||||||
|
}
|
||||||
32
ApplicationHub/Program.cs
Normal file
32
ApplicationHub/Program.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using ApplicationHub.Configuration;
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
|
ConfigFileConfiguration.Configure(builder);
|
||||||
|
DataContextConfiguration.Configure(builder);
|
||||||
|
AuthenticationConfiguration.Configure(builder);
|
||||||
|
AdapterConfiguration.Configure(builder);
|
||||||
|
ServiceConfiguration.Configure(builder);
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
DataContextConfiguration.Migrate(app);
|
||||||
|
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
app.UseCors();
|
||||||
|
|
||||||
|
app.UseAuthentication();
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
app.Run();
|
||||||
23
ApplicationHub/Properties/launchSettings.json
Normal file
23
ApplicationHub/Properties/launchSettings.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": false,
|
||||||
|
"applicationUrl": "http://localhost:5066",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": false,
|
||||||
|
"applicationUrl": "https://localhost:7121;http://localhost:5066",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
ApplicationHub/appsettings.Development.json
Normal file
16
ApplicationHub/appsettings.Development.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"AuthenticationConnection": "Data Source=DevAuthentication.db"
|
||||||
|
},
|
||||||
|
"JwtSettings": {
|
||||||
|
"Issuer": "https://deine-api.com",
|
||||||
|
"Audience": "https://deine-app.com",
|
||||||
|
"Key": "DeinLangerGeheimerSchluesselFuerJWT"
|
||||||
|
}
|
||||||
|
}
|
||||||
17
ApplicationHub/appsettings.json
Normal file
17
ApplicationHub/appsettings.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"AuthenticationConnection": "Data Source=Authentication.db"
|
||||||
|
},
|
||||||
|
"JwtSettings": {
|
||||||
|
"Issuer": "https://deine-api.com",
|
||||||
|
"Audience": "https://deine-app.com",
|
||||||
|
"Key": "DeinLangerGeheimerSchluesselFuerJWT"
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user