reorganization of database layer
This commit is contained in:
parent
2a86c16b85
commit
110663456d
@ -0,0 +1,73 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace UserService.DatabaseLayer.DataModels
|
||||||
|
{
|
||||||
|
public static class ModelBuilderExtensions
|
||||||
|
{
|
||||||
|
public static void Seed(this ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
var groups = new OrganizationUnit { CommonName = "Groups", Id = -1 };
|
||||||
|
var users = new OrganizationUnit { CommonName = "Users", Id = -2 };
|
||||||
|
var germany = new OrganizationUnit{CommonName = "Germany", Id = -6, ParentId = -2};
|
||||||
|
var usa = new OrganizationUnit{CommonName = "USA", Id = -5, ParentId = -2};
|
||||||
|
var arizona = new OrganizationUnit{CommonName = "Arizona" , Id = -4, ParentId = -5 };
|
||||||
|
var france = new OrganizationUnit{CommonName = "France" , Id = -3, ParentId = -2 };
|
||||||
|
modelBuilder.Entity<OrganizationUnit>().HasData(users, groups, germany, usa, arizona, france);
|
||||||
|
var user = new User { CommonName = "holger", IsActive = true, Id = -7, ParentId = germany.Id };
|
||||||
|
modelBuilder.Entity<User>().HasData(user);
|
||||||
|
var secGroup = new SecurityGroup { CommonName = "Global Admin", Id = -8, ParentId = groups.Id };
|
||||||
|
modelBuilder.Entity<SecurityGroup>().HasData(secGroup);
|
||||||
|
|
||||||
|
modelBuilder.Entity<UserMember>()
|
||||||
|
.HasData(new UserMember { MemberId = secGroup.Id, UserId = user.Id });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateRelations(this ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
modelBuilder.Entity<UserMember>()
|
||||||
|
.HasKey(bc => new { bc.MemberId, bc.UserId });
|
||||||
|
modelBuilder.Entity<UserMember>()
|
||||||
|
.HasOne(bc => bc.User)
|
||||||
|
.WithMany(b => b!.MemberOf)
|
||||||
|
.HasForeignKey(bc => bc.UserId);
|
||||||
|
modelBuilder.Entity<UserMember>()
|
||||||
|
.HasOne(bc => bc.Member)
|
||||||
|
.WithMany(c => c!.Members)
|
||||||
|
.HasForeignKey(bc => bc.MemberId);
|
||||||
|
|
||||||
|
modelBuilder.Entity<Node>()
|
||||||
|
.HasMany(c => c.Children)
|
||||||
|
.WithOne(e => e.Parent!)
|
||||||
|
.HasForeignKey(bc => bc.ParentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class UserExtensions
|
||||||
|
{
|
||||||
|
public static IEnumerable<SecurityGroup> GetSecurityGroups(this User user)
|
||||||
|
{
|
||||||
|
foreach (var userMember in user.MemberOf)
|
||||||
|
{
|
||||||
|
if (userMember.Member is SecurityGroup securityGroup)
|
||||||
|
{
|
||||||
|
yield return securityGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SecurityGroupExtensions
|
||||||
|
{
|
||||||
|
public static IEnumerable<User> GetUsers(this SecurityGroup securityGroup)
|
||||||
|
{
|
||||||
|
foreach (var userMember in securityGroup.Members)
|
||||||
|
{
|
||||||
|
if (userMember.User is null) continue;
|
||||||
|
yield return userMember.User;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace UserService.DataModels
|
namespace UserService.DatabaseLayer.DataModels
|
||||||
{
|
{
|
||||||
public class OrganizationUnit : Node
|
public class OrganizationUnit : Node
|
||||||
{
|
{
|
||||||
@ -23,24 +24,7 @@ namespace UserService.DataModels
|
|||||||
|
|
||||||
public IEnumerable<UserMember> MemberOf { get; set; } = new List<UserMember>();
|
public IEnumerable<UserMember> MemberOf { get; set; } = new List<UserMember>();
|
||||||
|
|
||||||
public User Clone()
|
public User Clone() => (User)MemberwiseClone();
|
||||||
{
|
|
||||||
return new User
|
|
||||||
{
|
|
||||||
Children = Children,
|
|
||||||
CommonName = CommonName,
|
|
||||||
Description = Description,
|
|
||||||
EMail = EMail,
|
|
||||||
FirstName = FirstName,
|
|
||||||
Id = Id,
|
|
||||||
IsActive = IsActive,
|
|
||||||
LastName = LastName,
|
|
||||||
MemberOf = MemberOf,
|
|
||||||
Members = Members,
|
|
||||||
Parent = Parent,
|
|
||||||
ParentId = ParentId
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UserMember
|
public class UserMember
|
||||||
@ -64,10 +48,15 @@ namespace UserService.DataModels
|
|||||||
public abstract class Node
|
public abstract class Node
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
[Required] public string CommonName { get; set; } = "commonName";
|
[Required] public string CommonName { get; set; } = null!;
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
public ICollection<Node> Children { get; set; } = new List<Node>();
|
public ICollection<Node> Children { get; set; } = new List<Node>();
|
||||||
public Node? Parent { get; set; } //Parent
|
public Node? Parent { get; set; } //Parent
|
||||||
public int? ParentId { get; set; }
|
public int? ParentId { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"[{GetType().Name}] {Id:D5} {CommonName}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,13 +1,12 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace UserService.DataModels
|
namespace UserService.DatabaseLayer.DataModels
|
||||||
{
|
{
|
||||||
public class UserServiceDbContext : DbContext
|
public class UserServiceDbContext : DbContext
|
||||||
{
|
{
|
||||||
public DbSet<User> Users { get; set; } = null!;
|
public DbSet<User> Users { get; set; } = null!;
|
||||||
public DbSet<SecurityGroup> SecurityGroups { get; set; } = null!;
|
public DbSet<SecurityGroup> SecurityGroups { get; set; } = null!;
|
||||||
public DbSet<UserMember> UserMembers { get; set; } = null!;
|
public DbSet<UserMember> UserMembers { get; set; } = null!;
|
||||||
|
|
||||||
public DbSet<OrganizationUnit> OrganizationUnits { get; set; } = null!;
|
public DbSet<OrganizationUnit> OrganizationUnits { get; set; } = null!;
|
||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder options)
|
protected override void OnConfiguring(DbContextOptionsBuilder options)
|
@ -4,12 +4,12 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using UserService.DataModels;
|
using UserService.DatabaseLayer.DataModels;
|
||||||
|
|
||||||
namespace UserService.Migrations
|
namespace UserService.DatabaseLayer.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(UserServiceDbContext))]
|
[DbContext(typeof(UserServiceDbContext))]
|
||||||
[Migration("20200724180034_initial")]
|
[Migration("20200725195658_initial")]
|
||||||
partial class initial
|
partial class initial
|
||||||
{
|
{
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
@ -18,7 +18,7 @@ namespace UserService.Migrations
|
|||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "3.1.6");
|
.HasAnnotation("ProductVersion", "3.1.6");
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.Node", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.Node", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
@ -47,7 +47,7 @@ namespace UserService.Migrations
|
|||||||
b.HasDiscriminator<string>("Discriminator").HasValue("Node");
|
b.HasDiscriminator<string>("Discriminator").HasValue("Node");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.UserMember", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.UserMember", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("MemberId")
|
b.Property<int>("MemberId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
@ -64,14 +64,14 @@ namespace UserService.Migrations
|
|||||||
b.HasData(
|
b.HasData(
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
MemberId = -3,
|
MemberId = -8,
|
||||||
UserId = -4
|
UserId = -7
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.Member", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.Member", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DataModels.Node");
|
b.HasBaseType("UserService.DatabaseLayer.DataModels.Node");
|
||||||
|
|
||||||
b.Property<string>("EMail")
|
b.Property<string>("EMail")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
@ -79,9 +79,9 @@ namespace UserService.Migrations
|
|||||||
b.HasDiscriminator().HasValue("Member");
|
b.HasDiscriminator().HasValue("Member");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.OrganizationUnit", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.OrganizationUnit", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DataModels.Node");
|
b.HasBaseType("UserService.DatabaseLayer.DataModels.Node");
|
||||||
|
|
||||||
b.Property<int?>("ManagerId")
|
b.Property<int?>("ManagerId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
@ -100,27 +100,51 @@ namespace UserService.Migrations
|
|||||||
{
|
{
|
||||||
Id = -1,
|
Id = -1,
|
||||||
CommonName = "Groups"
|
CommonName = "Groups"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = -6,
|
||||||
|
CommonName = "Germany",
|
||||||
|
ParentId = -2
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = -5,
|
||||||
|
CommonName = "USA",
|
||||||
|
ParentId = -2
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = -4,
|
||||||
|
CommonName = "Arizona",
|
||||||
|
ParentId = -5
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = -3,
|
||||||
|
CommonName = "France",
|
||||||
|
ParentId = -2
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.SecurityGroup", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.SecurityGroup", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DataModels.Member");
|
b.HasBaseType("UserService.DatabaseLayer.DataModels.Member");
|
||||||
|
|
||||||
b.HasDiscriminator().HasValue("SecurityGroup");
|
b.HasDiscriminator().HasValue("SecurityGroup");
|
||||||
|
|
||||||
b.HasData(
|
b.HasData(
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = -3,
|
Id = -8,
|
||||||
CommonName = "Global Admin",
|
CommonName = "Global Admin",
|
||||||
ParentId = -1
|
ParentId = -1
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.User", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.User", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DataModels.Member");
|
b.HasBaseType("UserService.DatabaseLayer.DataModels.Member");
|
||||||
|
|
||||||
b.Property<string>("FirstName")
|
b.Property<string>("FirstName")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
@ -136,38 +160,38 @@ namespace UserService.Migrations
|
|||||||
b.HasData(
|
b.HasData(
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = -4,
|
Id = -7,
|
||||||
CommonName = "holger",
|
CommonName = "holger",
|
||||||
ParentId = -2,
|
ParentId = -6,
|
||||||
IsActive = true
|
IsActive = true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.Node", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.Node", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("UserService.DataModels.Node", "Parent")
|
b.HasOne("UserService.DatabaseLayer.DataModels.Node", "Parent")
|
||||||
.WithMany("Children")
|
.WithMany("Children")
|
||||||
.HasForeignKey("ParentId");
|
.HasForeignKey("ParentId");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.UserMember", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.UserMember", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("UserService.DataModels.Member", "Member")
|
b.HasOne("UserService.DatabaseLayer.DataModels.Member", "Member")
|
||||||
.WithMany("Members")
|
.WithMany("Members")
|
||||||
.HasForeignKey("MemberId")
|
.HasForeignKey("MemberId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b.HasOne("UserService.DataModels.User", "User")
|
b.HasOne("UserService.DatabaseLayer.DataModels.User", "User")
|
||||||
.WithMany("MemberOf")
|
.WithMany("MemberOf")
|
||||||
.HasForeignKey("UserId")
|
.HasForeignKey("UserId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.OrganizationUnit", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.OrganizationUnit", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("UserService.DataModels.Member", "Manager")
|
b.HasOne("UserService.DatabaseLayer.DataModels.Member", "Manager")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("ManagerId");
|
.HasForeignKey("ManagerId");
|
||||||
});
|
});
|
@ -1,6 +1,6 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
namespace UserService.Migrations
|
namespace UserService.DatabaseLayer.Migrations
|
||||||
{
|
{
|
||||||
public partial class initial : Migration
|
public partial class initial : Migration
|
||||||
{
|
{
|
||||||
@ -75,18 +75,38 @@ namespace UserService.Migrations
|
|||||||
|
|
||||||
migrationBuilder.InsertData(
|
migrationBuilder.InsertData(
|
||||||
table: "Node",
|
table: "Node",
|
||||||
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "EMail", "FirstName", "IsActive", "LastName" },
|
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "ManagerId" },
|
||||||
values: new object[] { -4, "holger", null, "User", -2, null, null, true, null });
|
values: new object[] { -6, "Germany", null, "OrganizationUnit", -2, null });
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "Node",
|
||||||
|
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "ManagerId" },
|
||||||
|
values: new object[] { -5, "USA", null, "OrganizationUnit", -2, null });
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "Node",
|
||||||
|
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "ManagerId" },
|
||||||
|
values: new object[] { -3, "France", null, "OrganizationUnit", -2, null });
|
||||||
|
|
||||||
migrationBuilder.InsertData(
|
migrationBuilder.InsertData(
|
||||||
table: "Node",
|
table: "Node",
|
||||||
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "EMail" },
|
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "EMail" },
|
||||||
values: new object[] { -3, "Global Admin", null, "SecurityGroup", -1, null });
|
values: new object[] { -8, "Global Admin", null, "SecurityGroup", -1, null });
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "Node",
|
||||||
|
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "EMail", "FirstName", "IsActive", "LastName" },
|
||||||
|
values: new object[] { -7, "holger", null, "User", -6, null, null, true, null });
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "Node",
|
||||||
|
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "ManagerId" },
|
||||||
|
values: new object[] { -4, "Arizona", null, "OrganizationUnit", -5, null });
|
||||||
|
|
||||||
migrationBuilder.InsertData(
|
migrationBuilder.InsertData(
|
||||||
table: "UserMembers",
|
table: "UserMembers",
|
||||||
columns: new[] { "MemberId", "UserId" },
|
columns: new[] { "MemberId", "UserId" },
|
||||||
values: new object[] { -3, -4 });
|
values: new object[] { -8, -7 });
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_Node_ParentId",
|
name: "IX_Node_ParentId",
|
@ -3,9 +3,9 @@ using System;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using UserService.DataModels;
|
using UserService.DatabaseLayer.DataModels;
|
||||||
|
|
||||||
namespace UserService.Migrations
|
namespace UserService.DatabaseLayer.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(UserServiceDbContext))]
|
[DbContext(typeof(UserServiceDbContext))]
|
||||||
partial class UserServiceDbContextModelSnapshot : ModelSnapshot
|
partial class UserServiceDbContextModelSnapshot : ModelSnapshot
|
||||||
@ -16,7 +16,7 @@ namespace UserService.Migrations
|
|||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "3.1.6");
|
.HasAnnotation("ProductVersion", "3.1.6");
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.Node", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.Node", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
@ -45,7 +45,7 @@ namespace UserService.Migrations
|
|||||||
b.HasDiscriminator<string>("Discriminator").HasValue("Node");
|
b.HasDiscriminator<string>("Discriminator").HasValue("Node");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.UserMember", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.UserMember", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("MemberId")
|
b.Property<int>("MemberId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
@ -62,14 +62,14 @@ namespace UserService.Migrations
|
|||||||
b.HasData(
|
b.HasData(
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
MemberId = -3,
|
MemberId = -8,
|
||||||
UserId = -4
|
UserId = -7
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.Member", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.Member", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DataModels.Node");
|
b.HasBaseType("UserService.DatabaseLayer.DataModels.Node");
|
||||||
|
|
||||||
b.Property<string>("EMail")
|
b.Property<string>("EMail")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
@ -77,9 +77,9 @@ namespace UserService.Migrations
|
|||||||
b.HasDiscriminator().HasValue("Member");
|
b.HasDiscriminator().HasValue("Member");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.OrganizationUnit", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.OrganizationUnit", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DataModels.Node");
|
b.HasBaseType("UserService.DatabaseLayer.DataModels.Node");
|
||||||
|
|
||||||
b.Property<int?>("ManagerId")
|
b.Property<int?>("ManagerId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
@ -98,27 +98,51 @@ namespace UserService.Migrations
|
|||||||
{
|
{
|
||||||
Id = -1,
|
Id = -1,
|
||||||
CommonName = "Groups"
|
CommonName = "Groups"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = -6,
|
||||||
|
CommonName = "Germany",
|
||||||
|
ParentId = -2
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = -5,
|
||||||
|
CommonName = "USA",
|
||||||
|
ParentId = -2
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = -4,
|
||||||
|
CommonName = "Arizona",
|
||||||
|
ParentId = -5
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = -3,
|
||||||
|
CommonName = "France",
|
||||||
|
ParentId = -2
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.SecurityGroup", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.SecurityGroup", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DataModels.Member");
|
b.HasBaseType("UserService.DatabaseLayer.DataModels.Member");
|
||||||
|
|
||||||
b.HasDiscriminator().HasValue("SecurityGroup");
|
b.HasDiscriminator().HasValue("SecurityGroup");
|
||||||
|
|
||||||
b.HasData(
|
b.HasData(
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = -3,
|
Id = -8,
|
||||||
CommonName = "Global Admin",
|
CommonName = "Global Admin",
|
||||||
ParentId = -1
|
ParentId = -1
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.User", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.User", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DataModels.Member");
|
b.HasBaseType("UserService.DatabaseLayer.DataModels.Member");
|
||||||
|
|
||||||
b.Property<string>("FirstName")
|
b.Property<string>("FirstName")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
@ -134,38 +158,38 @@ namespace UserService.Migrations
|
|||||||
b.HasData(
|
b.HasData(
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = -4,
|
Id = -7,
|
||||||
CommonName = "holger",
|
CommonName = "holger",
|
||||||
ParentId = -2,
|
ParentId = -6,
|
||||||
IsActive = true
|
IsActive = true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.Node", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.Node", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("UserService.DataModels.Node", "Parent")
|
b.HasOne("UserService.DatabaseLayer.DataModels.Node", "Parent")
|
||||||
.WithMany("Children")
|
.WithMany("Children")
|
||||||
.HasForeignKey("ParentId");
|
.HasForeignKey("ParentId");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.UserMember", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.UserMember", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("UserService.DataModels.Member", "Member")
|
b.HasOne("UserService.DatabaseLayer.DataModels.Member", "Member")
|
||||||
.WithMany("Members")
|
.WithMany("Members")
|
||||||
.HasForeignKey("MemberId")
|
.HasForeignKey("MemberId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b.HasOne("UserService.DataModels.User", "User")
|
b.HasOne("UserService.DatabaseLayer.DataModels.User", "User")
|
||||||
.WithMany("MemberOf")
|
.WithMany("MemberOf")
|
||||||
.HasForeignKey("UserId")
|
.HasForeignKey("UserId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DataModels.OrganizationUnit", b =>
|
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.OrganizationUnit", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("UserService.DataModels.Member", "Manager")
|
b.HasOne("UserService.DatabaseLayer.DataModels.Member", "Manager")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("ManagerId");
|
.HasForeignKey("ManagerId");
|
||||||
});
|
});
|
53
UserService.DatabaseLayer/Repository/BaseRepository.cs
Normal file
53
UserService.DatabaseLayer/Repository/BaseRepository.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using UserService.DatabaseLayer.DataModels;
|
||||||
|
|
||||||
|
namespace UserService.DatabaseLayer.Repository
|
||||||
|
{
|
||||||
|
public class BaseRepository<T> where T : class
|
||||||
|
{
|
||||||
|
private readonly Func<UserServiceDbContext, DbSet<T>> _context;
|
||||||
|
|
||||||
|
protected BaseRepository(Func<UserServiceDbContext, DbSet<T>> context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IReadOnlyList<T>> GetAllAsync(CancellationToken token = default)
|
||||||
|
{
|
||||||
|
await using var db = new UserServiceDbContext();
|
||||||
|
return await _context(db).ToListAsync(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<T?> GetAsync(Expression<Func<T, bool>> predicate, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
await using var db = new UserServiceDbContext();
|
||||||
|
return await _context(db).FirstOrDefaultAsync(predicate, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AddAsync(T entity, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
await using var db = new UserServiceDbContext();
|
||||||
|
await _context(db).AddAsync(@entity, token);
|
||||||
|
await db.SaveChangesAsync(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateAsync(T entity, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
await using var db = new UserServiceDbContext();
|
||||||
|
_context(db).Update(entity);
|
||||||
|
await db.SaveChangesAsync(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteAsync(T entity, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
await using var db = new UserServiceDbContext();
|
||||||
|
_context(db).Remove(entity);
|
||||||
|
await db.SaveChangesAsync(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,22 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq.Expressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using UserService.DataModels;
|
using UserService.DatabaseLayer.DataModels;
|
||||||
|
|
||||||
namespace UserService.Repository
|
namespace UserService.DatabaseLayer.Repository
|
||||||
{
|
{
|
||||||
public interface IRepository<T> where T : Node
|
public interface IRepository<T> where T : Node
|
||||||
{
|
{
|
||||||
Task<IReadOnlyList<T>> GetAllAsync(CancellationToken token = default);
|
Task<IReadOnlyList<T>> GetAllAsync(CancellationToken token = default);
|
||||||
Task<T?> GetAsync(Func<T, bool> predicate, CancellationToken token = default);
|
Task<T?> GetAsync(Expression<Func<T, bool>> predicate, CancellationToken token = default);
|
||||||
Task AddAsync(T entity, CancellationToken token = default);
|
Task AddAsync(T entity, CancellationToken token = default);
|
||||||
Task UpdateAsync(T entity, CancellationToken token = default);
|
Task UpdateAsync(T entity, CancellationToken token = default);
|
||||||
Task DeleteAsync(T entity, CancellationToken token = default);
|
Task DeleteAsync(T entity, CancellationToken token = default);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IOrganizationUnitRepository : IRepository<OrganizationUnit>
|
public interface IOrganizationUnitsRepository : IRepository<OrganizationUnit>
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -29,4 +30,9 @@ namespace UserService.Repository
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface INodesRepository : IRepository<Node>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
97
UserService.DatabaseLayer/Repository/Repository.cs
Normal file
97
UserService.DatabaseLayer/Repository/Repository.cs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UserService.DatabaseLayer.DataModels;
|
||||||
|
|
||||||
|
namespace UserService.DatabaseLayer.Repository
|
||||||
|
{
|
||||||
|
public class OrganizationUnitsRepository : BaseRepository<OrganizationUnit>, IOrganizationUnitsRepository
|
||||||
|
{
|
||||||
|
public OrganizationUnitsRepository() : base(x => x.OrganizationUnits)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SecurityGroupsRepository : BaseRepository<SecurityGroup>, ISecurityGroupsRepository
|
||||||
|
{
|
||||||
|
public SecurityGroupsRepository() : base(x=> x.SecurityGroups)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class UsersRepository : BaseRepository<User>, IUsersRepository
|
||||||
|
{
|
||||||
|
public UsersRepository() : base(x => x.Users)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NodesRepository : INodesRepository
|
||||||
|
{
|
||||||
|
private readonly IUsersRepository _users;
|
||||||
|
private readonly ISecurityGroupsRepository _securityGroups;
|
||||||
|
private readonly IOrganizationUnitsRepository _organizationUnits;
|
||||||
|
|
||||||
|
public NodesRepository(IUsersRepository users, ISecurityGroupsRepository securityGroups, IOrganizationUnitsRepository organizationUnits)
|
||||||
|
{
|
||||||
|
_users = users;
|
||||||
|
_securityGroups = securityGroups;
|
||||||
|
_organizationUnits = organizationUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async IAsyncEnumerable<Node> GetNodesAsync([EnumeratorCancellation] CancellationToken token = default)
|
||||||
|
{
|
||||||
|
await using var db = new UserServiceDbContext();
|
||||||
|
await foreach (var note in db.OrganizationUnits.AsAsyncEnumerable().WithCancellation(token))
|
||||||
|
{
|
||||||
|
yield return note;
|
||||||
|
}
|
||||||
|
await foreach (var node in db.SecurityGroups.AsAsyncEnumerable().WithCancellation(token))
|
||||||
|
{
|
||||||
|
yield return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
await foreach (var node in db.Users.AsAsyncEnumerable().WithCancellation(token))
|
||||||
|
{
|
||||||
|
yield return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IReadOnlyList<Node>> GetAllAsync(CancellationToken token = default)
|
||||||
|
{
|
||||||
|
|
||||||
|
var list = new List<Node>();
|
||||||
|
await foreach (var node in GetNodesAsync(token))
|
||||||
|
{
|
||||||
|
list.Add(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Node?> GetAsync(Expression<Func<Node, bool>> predicate, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task AddAsync(Node entity, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task UpdateAsync(Node entity, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeleteAsync(Node entity, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
UserService.DatabaseLayer/UserService.DatabaseLayer.csproj
Normal file
17
UserService.DatabaseLayer/UserService.DatabaseLayer.csproj
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
<LangVersion>8</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.6">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.6" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -1,8 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using UserService.DataModels;
|
using UserService.DatabaseLayer.DataModels;
|
||||||
|
|
||||||
namespace UserService.Test
|
namespace UserService.Test
|
||||||
{
|
{
|
||||||
@ -22,6 +26,8 @@ namespace UserService.Test
|
|||||||
var ous = await db.OrganizationUnits.ToListAsync();
|
var ous = await db.OrganizationUnits.ToListAsync();
|
||||||
var mo = await db.UserMembers.ToListAsync();
|
var mo = await db.UserMembers.ToListAsync();
|
||||||
|
|
||||||
|
var securityGroupsOfUser = user.GetSecurityGroups();
|
||||||
|
var usersOfSecurityGroup = secGroup.GetUsers();
|
||||||
//var testGroup = new SecurityGroup {CommonName = "Test", Parent = ous.Last()};
|
//var testGroup = new SecurityGroup {CommonName = "Test", Parent = ous.Last()};
|
||||||
//await db.SecurityGroups.AddAsync(testGroup);
|
//await db.SecurityGroups.AddAsync(testGroup);
|
||||||
//var testgroup = await db.SecurityGroups.FindAsync(1);
|
//var testgroup = await db.SecurityGroups.FindAsync(1);
|
||||||
@ -29,5 +35,26 @@ namespace UserService.Test
|
|||||||
//await db.SaveChangesAsync();
|
//await db.SaveChangesAsync();
|
||||||
Assert.Pass();
|
Assert.Pass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test2()
|
||||||
|
{
|
||||||
|
await using var db = new UserServiceDbContext();
|
||||||
|
var ous = await db.OrganizationUnits.ToListAsync();
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
NewMethod(ous, null, 0, ref sb);
|
||||||
|
var result = sb.ToString();
|
||||||
|
Assert.Pass();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void NewMethod(IEnumerable<OrganizationUnit> ous, Node parent, int level, ref StringBuilder sb)
|
||||||
|
{
|
||||||
|
foreach (var unit in ous.Where(x => x.Parent == parent))
|
||||||
|
{
|
||||||
|
sb.AppendLine(string.Concat(Enumerable.Repeat(' ', 4 * level)) + unit.CommonName);
|
||||||
|
NewMethod(unit.Children.OfType<OrganizationUnit>(), unit, level + 1, ref sb);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="nunit" Version="3.12.0" />
|
<PackageReference Include="nunit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
BIN
UserService.db
BIN
UserService.db
Binary file not shown.
@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UserService", "UserService\
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UserService.Test", "UserService.Test\UserService.Test.csproj", "{F4C0B161-F9DD-4335-A609-D7FC5EA0E14A}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UserService.Test", "UserService.Test\UserService.Test.csproj", "{F4C0B161-F9DD-4335-A609-D7FC5EA0E14A}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UserService.DatabaseLayer", "UserService.DatabaseLayer\UserService.DatabaseLayer.csproj", "{4505C991-7E39-416F-94E5-D906DD0D90F9}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -21,6 +23,10 @@ Global
|
|||||||
{F4C0B161-F9DD-4335-A609-D7FC5EA0E14A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{F4C0B161-F9DD-4335-A609-D7FC5EA0E14A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{F4C0B161-F9DD-4335-A609-D7FC5EA0E14A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{F4C0B161-F9DD-4335-A609-D7FC5EA0E14A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{F4C0B161-F9DD-4335-A609-D7FC5EA0E14A}.Release|Any CPU.Build.0 = Release|Any CPU
|
{F4C0B161-F9DD-4335-A609-D7FC5EA0E14A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4505C991-7E39-416F-94E5-D906DD0D90F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4505C991-7E39-416F-94E5-D906DD0D90F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4505C991-7E39-416F-94E5-D906DD0D90F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4505C991-7E39-416F-94E5-D906DD0D90F9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace UserService.Data
|
|
||||||
{
|
|
||||||
public class WeatherForecast
|
|
||||||
{
|
|
||||||
public DateTime Date { get; set; }
|
|
||||||
|
|
||||||
public int TemperatureC { get; set; }
|
|
||||||
|
|
||||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
|
||||||
|
|
||||||
public string Summary { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace UserService.Data
|
|
||||||
{
|
|
||||||
public class WeatherForecastService
|
|
||||||
{
|
|
||||||
private static readonly string[] Summaries = new[]
|
|
||||||
{
|
|
||||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
|
||||||
};
|
|
||||||
|
|
||||||
public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
|
|
||||||
{
|
|
||||||
var rng = new Random();
|
|
||||||
return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
|
||||||
{
|
|
||||||
Date = startDate.AddDays(index),
|
|
||||||
TemperatureC = rng.Next(-20, 55),
|
|
||||||
Summary = Summaries[rng.Next(Summaries.Length)]
|
|
||||||
}).ToArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace UserService.DataModels
|
|
||||||
{
|
|
||||||
public static class ModelBuilderExtensions
|
|
||||||
{
|
|
||||||
public static void Seed(this ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
var users = new OrganizationUnit {CommonName = "Users", Id = -2};
|
|
||||||
var groups = new OrganizationUnit {CommonName = "Groups", Id = -1};
|
|
||||||
modelBuilder.Entity<OrganizationUnit>().HasData(users, groups);
|
|
||||||
var user = new User {CommonName = "holger", IsActive = true, Id = -4, ParentId = users.Id};
|
|
||||||
modelBuilder.Entity<User>().HasData(user);
|
|
||||||
var secGroup = new SecurityGroup {CommonName = "Global Admin", Id = -3, ParentId = groups.Id};
|
|
||||||
modelBuilder.Entity<SecurityGroup>().HasData(secGroup);
|
|
||||||
|
|
||||||
modelBuilder.Entity<UserMember>()
|
|
||||||
.HasData(new UserMember {MemberId = secGroup.Id, UserId = user.Id});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void CreateRelations(this ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
modelBuilder.Entity<UserMember>()
|
|
||||||
.HasKey(bc => new {bc.MemberId, bc.UserId});
|
|
||||||
modelBuilder.Entity<UserMember>()
|
|
||||||
.HasOne(bc => bc.User)
|
|
||||||
.WithMany(b => b!.MemberOf)
|
|
||||||
.HasForeignKey(bc => bc.UserId);
|
|
||||||
modelBuilder.Entity<UserMember>()
|
|
||||||
.HasOne(bc => bc.Member)
|
|
||||||
.WithMany(c => c!.Members)
|
|
||||||
.HasForeignKey(bc => bc.MemberId);
|
|
||||||
|
|
||||||
modelBuilder.Entity<Node>()
|
|
||||||
.HasMany(c => c.Children)
|
|
||||||
.WithOne(e => e.Parent!)
|
|
||||||
.HasForeignKey(bc => bc.ParentId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +1,30 @@
|
|||||||
@page "/counter"
|
@page "/counter"
|
||||||
|
@using UserService.DatabaseLayer.DataModels
|
||||||
|
@using UserService.DatabaseLayer.Repository
|
||||||
|
@inject IOrganizationUnitsRepository OuRepository
|
||||||
|
|
||||||
<h1>Counter</h1>
|
<h1>Tree</h1>
|
||||||
|
|
||||||
<p>Current count: @currentCount</p>
|
@if (_organizationUnits == null)
|
||||||
|
{
|
||||||
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
|
<p>
|
||||||
|
<em>Loading...</em>
|
||||||
@code {
|
</p>
|
||||||
private int currentCount = 0;
|
|
||||||
|
|
||||||
private void IncrementCount()
|
|
||||||
{
|
|
||||||
currentCount++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MatNavMenu>
|
||||||
|
@foreach (var unit in _organizationUnits)
|
||||||
|
{
|
||||||
|
<OrgUnitItem OrganizationUnit="@unit"/>
|
||||||
|
}
|
||||||
|
</MatNavMenu>
|
||||||
|
}
|
||||||
|
@code {
|
||||||
|
private IReadOnlyList<OrganizationUnit> _organizationUnits;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
_organizationUnits = await OuRepository.GetAllAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
@ -1,46 +0,0 @@
|
|||||||
@page "/fetchdata"
|
|
||||||
|
|
||||||
@using UserService.Data
|
|
||||||
@inject WeatherForecastService ForecastService
|
|
||||||
|
|
||||||
<h1>Weather forecast</h1>
|
|
||||||
|
|
||||||
<p>This component demonstrates fetching data from a service.</p>
|
|
||||||
|
|
||||||
@if (forecasts == null)
|
|
||||||
{
|
|
||||||
<p><em>Loading...</em></p>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Date</th>
|
|
||||||
<th>Temp. (C)</th>
|
|
||||||
<th>Temp. (F)</th>
|
|
||||||
<th>Summary</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach (var forecast in forecasts)
|
|
||||||
{
|
|
||||||
<tr>
|
|
||||||
<td>@forecast.Date.ToShortDateString()</td>
|
|
||||||
<td>@forecast.TemperatureC</td>
|
|
||||||
<td>@forecast.TemperatureF</td>
|
|
||||||
<td>@forecast.Summary</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
}
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private WeatherForecast[] forecasts;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
@page "/"
|
@page "/"
|
||||||
@using UserService.Repository
|
@using UserService.DatabaseLayer.DataModels
|
||||||
@using UserService.DataModels
|
@using UserService.DatabaseLayer.Repository
|
||||||
@inject IUsersRepository UsersRepository
|
@inject IUsersRepository UsersRepository
|
||||||
|
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ else
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MatDialogTitle>No user selected</MatDialogTitle>
|
<MatDialogTitle>No securityGroup selected</MatDialogTitle>
|
||||||
}
|
}
|
||||||
<MatDialogActions>
|
<MatDialogActions>
|
||||||
<MatButton OnClick="@(e => { _dialogIsOpen = false; })">No Thanks</MatButton>
|
<MatButton OnClick="@(e => { _dialogIsOpen = false; })">No Thanks</MatButton>
|
||||||
@ -74,7 +74,7 @@ else
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
bool _dialogIsOpen;
|
bool _dialogIsOpen;
|
||||||
User _userToEdit;
|
User? _userToEdit;
|
||||||
|
|
||||||
private IReadOnlyList<User> _users;
|
private IReadOnlyList<User> _users;
|
||||||
|
|
||||||
|
@ -1,124 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using UserService.DataModels;
|
|
||||||
|
|
||||||
namespace UserService.Repository
|
|
||||||
{
|
|
||||||
public class OrganizationUnitRepository : IOrganizationUnitRepository
|
|
||||||
{
|
|
||||||
public async Task<IReadOnlyList<OrganizationUnit>> GetAllAsync(CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
return await db.OrganizationUnits.ToListAsync(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public async Task<OrganizationUnit?> GetAsync(Func<OrganizationUnit, bool> predicate,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
return db.OrganizationUnits.Where(predicate).FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task AddAsync(OrganizationUnit entity, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
await db.OrganizationUnits.AddAsync(@entity, token);
|
|
||||||
await db.SaveChangesAsync(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task UpdateAsync(OrganizationUnit entity, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
db.OrganizationUnits.Update(entity);
|
|
||||||
await db.SaveChangesAsync(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeleteAsync(OrganizationUnit entity, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
db.OrganizationUnits.Remove(entity);
|
|
||||||
await db.SaveChangesAsync(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class SecurityGroupsRepository : ISecurityGroupsRepository
|
|
||||||
{
|
|
||||||
public async Task<IReadOnlyList<SecurityGroup>> GetAllAsync(CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
return await db.SecurityGroups.ToListAsync(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public async Task<SecurityGroup?> GetAsync(Func<SecurityGroup, bool> predicate, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
return db.SecurityGroups.Where(predicate).FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task AddAsync(SecurityGroup entity, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
await db.SecurityGroups.AddAsync(@entity, token);
|
|
||||||
await db.SaveChangesAsync(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task UpdateAsync(SecurityGroup entity, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
db.SecurityGroups.Update(entity);
|
|
||||||
await db.SaveChangesAsync(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeleteAsync(SecurityGroup entity, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
db.SecurityGroups.Remove(entity);
|
|
||||||
await db.SaveChangesAsync(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class UsersRepository : IUsersRepository
|
|
||||||
{
|
|
||||||
public async Task<IReadOnlyList<User>> GetAllAsync(CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
return await db.Users.ToListAsync(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public async Task<User?> GetAsync(Func<User, bool> predicate, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
return db.Users.Where(predicate).FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task AddAsync(User entity, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
await db.Users.AddAsync(@entity, token);
|
|
||||||
await db.SaveChangesAsync(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task UpdateAsync(User entity, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
db.Users.Update(entity);
|
|
||||||
await db.SaveChangesAsync(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeleteAsync(User entity, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await using var db = new UserServiceDbContext();
|
|
||||||
db.Users.Remove(entity);
|
|
||||||
await db.SaveChangesAsync(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,11 +17,6 @@
|
|||||||
<span class="oi oi-plus" aria-hidden="true"></span> Counter
|
<span class="oi oi-plus" aria-hidden="true"></span> Counter
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item px-3">
|
|
||||||
<NavLink class="nav-link" href="fetchdata">
|
|
||||||
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
|
|
||||||
</NavLink>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
15
UserService/Shared/OrgUnitItem.razor
Normal file
15
UserService/Shared/OrgUnitItem.razor
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
@using UserService.DatabaseLayer.DataModels
|
||||||
|
<MatNavSubMenu>
|
||||||
|
<MatNavSubMenuHeader>
|
||||||
|
<MatNavItem AllowSelection="false"><MatIcon Icon="folder"></MatIcon> @OrganizationUnit.CommonName</MatNavItem>
|
||||||
|
</MatNavSubMenuHeader>
|
||||||
|
<MatNavSubMenuList>
|
||||||
|
<MatNavItem Disabled="true" Href="#">Item 6.A</MatNavItem>
|
||||||
|
<MatNavItem>Item 6.B</MatNavItem>
|
||||||
|
<MatNavItem>Item 6.C</MatNavItem>
|
||||||
|
</MatNavSubMenuList>
|
||||||
|
</MatNavSubMenu>
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public OrganizationUnit OrganizationUnit { get; set; }
|
||||||
|
}
|
@ -1,16 +1,9 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.HttpsPolicy;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using UserService.Data;
|
using UserService.DatabaseLayer.Repository;
|
||||||
using UserService.Repository;
|
|
||||||
|
|
||||||
namespace UserService
|
namespace UserService
|
||||||
{
|
{
|
||||||
@ -29,10 +22,10 @@ namespace UserService
|
|||||||
{
|
{
|
||||||
services.AddRazorPages();
|
services.AddRazorPages();
|
||||||
services.AddServerSideBlazor();
|
services.AddServerSideBlazor();
|
||||||
services.AddSingleton<WeatherForecastService>();
|
|
||||||
services.AddSingleton<IUsersRepository, UsersRepository>();
|
services.AddSingleton<IUsersRepository, UsersRepository>();
|
||||||
services.AddSingleton<ISecurityGroupsRepository, SecurityGroupsRepository>();
|
services.AddSingleton<ISecurityGroupsRepository, SecurityGroupsRepository>();
|
||||||
services.AddSingleton<IOrganizationUnitRepository, OrganizationUnitRepository>();
|
services.AddSingleton<IOrganizationUnitsRepository, OrganizationUnitsRepository>();
|
||||||
|
//services.AddSingleton<INodesRepository, NodesRepository>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
@ -7,11 +7,10 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MatBlazor" Version="2.6.2" />
|
<PackageReference Include="MatBlazor" Version="2.6.2" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.6">
|
</ItemGroup>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<ItemGroup>
|
||||||
</PackageReference>
|
<ProjectReference Include="..\UserService.DatabaseLayer\UserService.DatabaseLayer.csproj" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.6" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user