From 17f3274abc23add29d8b073a40949ee1fc8a77b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Mon, 3 Aug 2020 22:15:25 +0200 Subject: [PATCH 01/11] Added Blazorise gui framework --- .../Repository/BaseRepository.cs | 25 ++--- .../Repository/IRepository.cs | 5 +- .../Repository/Repository.cs | 2 +- UserService/Pages/Directory.razor | 40 +++++--- UserService/Pages/Directory.razor.cs | 45 +++++++++ UserService/Pages/OrganizationUnits.razor | 67 +++++++------ UserService/Pages/SecurityGroups.razor | 82 ++++++++-------- UserService/Pages/Users.razor | 98 +++++++++---------- UserService/Pages/_Host.cshtml | 54 +++++----- UserService/Shared/NavMenu.razor | 61 ++++-------- UserService/Shared/SurveyPrompt.razor | 16 --- UserService/Startup.cs | 17 +++- UserService/UserService.csproj | 11 ++- UserService/_Imports.razor | 5 +- 14 files changed, 290 insertions(+), 238 deletions(-) create mode 100644 UserService/Pages/Directory.razor.cs delete mode 100644 UserService/Shared/SurveyPrompt.razor diff --git a/UserService.DatabaseLayer/Repository/BaseRepository.cs b/UserService.DatabaseLayer/Repository/BaseRepository.cs index aeb0dd7..7df73ec 100644 --- a/UserService.DatabaseLayer/Repository/BaseRepository.cs +++ b/UserService.DatabaseLayer/Repository/BaseRepository.cs @@ -1,8 +1,8 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; -using System.Runtime.CompilerServices; -using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; @@ -12,43 +12,46 @@ namespace UserService.DatabaseLayer.Repository { public class BaseRepository where T : Node { - protected readonly Func> _context; + protected readonly Func> Context; protected BaseRepository(Func> context) { - _context = context; + Context = context; } - public virtual async Task> GetAllAsync(CancellationToken token = default) + public virtual async Task> GetAllAsync(Expression>? predicate = null, CancellationToken token = default) { await using var db = new UserServiceDbContext(); - return await _context(db).Include(x => x.Parent).ToListAsync(token); + + IQueryable queryable = Context(db).Include(x => x.Parent); + if(queryable != null) queryable = queryable.Where(predicate); + return await queryable.ToListAsync(token); } public async Task GetAsync(Expression> predicate, CancellationToken token = default) { await using var db = new UserServiceDbContext(); - return await _context(db).FirstOrDefaultAsync(predicate, token); + 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 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); + 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); + Context(db).Remove(entity); await db.SaveChangesAsync(token); } } diff --git a/UserService.DatabaseLayer/Repository/IRepository.cs b/UserService.DatabaseLayer/Repository/IRepository.cs index 19f8598..189c21a 100644 --- a/UserService.DatabaseLayer/Repository/IRepository.cs +++ b/UserService.DatabaseLayer/Repository/IRepository.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Threading; @@ -9,7 +10,7 @@ namespace UserService.DatabaseLayer.Repository { public interface IRepository where T : Node { - Task> GetAllAsync(CancellationToken token = default); + Task> GetAllAsync(Expression>? predicate = null, CancellationToken token = default); Task GetAsync(Expression> predicate, CancellationToken token = default); Task AddAsync(T entity, CancellationToken token = default); Task UpdateAsync(T entity, CancellationToken token = default); diff --git a/UserService.DatabaseLayer/Repository/Repository.cs b/UserService.DatabaseLayer/Repository/Repository.cs index 2be88fd..86afdd3 100644 --- a/UserService.DatabaseLayer/Repository/Repository.cs +++ b/UserService.DatabaseLayer/Repository/Repository.cs @@ -23,7 +23,7 @@ namespace UserService.DatabaseLayer.Repository await using var db = new UserServiceDbContext(); var result = new List(); - var rootOus = await _context(db) + var rootOus = await Context(db) .Include(x => x.Parent) .ToListAsync(token); diff --git a/UserService/Pages/Directory.razor b/UserService/Pages/Directory.razor index 4ba6e41..39bb61c 100644 --- a/UserService/Pages/Directory.razor +++ b/UserService/Pages/Directory.razor @@ -1,11 +1,20 @@ @page "/directory" -@using UserService.DatabaseLayer.DataModels @using UserService.DatabaseLayer.Repository @inject IOrganizationUnitsRepository OuRepository +@inherits DirectoryBase -

TODO

+@functions { -@if (_organizationUnits == null) + + +} + + + +

TODO

+
+
+@if (OrganizationUnits == null) {

Loading... @@ -13,17 +22,20 @@ } else { + + + + + + @context?.CommonName + + + - -} -@code { - private IReadOnlyList _organizationUnits; - private OrganizationUnit _selectedOu; - - protected override async Task OnInitializedAsync() - { - _organizationUnits = (await OuRepository.GetAllAsync().ConfigureAwait(false)).Where(x=> x.Parent is null).ToList(); - } - + + } \ No newline at end of file diff --git a/UserService/Pages/Directory.razor.cs b/UserService/Pages/Directory.razor.cs new file mode 100644 index 0000000..4a7ac5c --- /dev/null +++ b/UserService/Pages/Directory.razor.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using UserService.DatabaseLayer.DataModels; +using UserService.DatabaseLayer.Repository; + +namespace UserService.Pages +{ + public class DirectoryBase : ComponentBase + { + private Node? _selectedNode; + public IReadOnlyList? OrganizationUnits { get; set; } + + public Node? SelectedNode + { + get => _selectedNode; + set + { + if(Equals(_selectedNode, value)) return; + _selectedNode = value; + OnSelectedNodeChanged(value); + } + } + + private async void OnSelectedNodeChanged(Node? value) + { + Members = await UsersRepository.GetAllAsync(); + } + + [Inject] public IOrganizationUnitsRepository OuRepository { get; set; } + + [Inject] public IUsersRepository UsersRepository { get; set; } + + + protected override async Task OnInitializedAsync() + { + OrganizationUnits = (await OuRepository.GetAllAsync().ConfigureAwait(false)) + .Where(x => x.Parent is null) + .ToList(); + } + + } +} \ No newline at end of file diff --git a/UserService/Pages/OrganizationUnits.razor b/UserService/Pages/OrganizationUnits.razor index c17c79e..ff8896c 100644 --- a/UserService/Pages/OrganizationUnits.razor +++ b/UserService/Pages/OrganizationUnits.razor @@ -12,33 +12,36 @@ } else { - - - Common Name - Description - Parent - Manager - - - - - @context.CommonName - @context.Description - @context.Parent - @context.Manager - - edit - - - delete - - - + + + + @* + + Common Name + Description + Parent + Manager + + + + + @context.CommonName + @context.Description + @context.Parent + @context.Manager + + edit + + + delete + + + *@ Create organization unit } - +@* @if (OuToEdit != null) { @(OuToEdit.Id == 0 ? "New" : "Edit") @OuToEdit.CommonName (@OuToEdit.Id) @@ -47,16 +50,16 @@ else

@**@ -

- - - } - else - { - No securityGroup selected - } +@*

+ + + } + else + { + No securityGroup selected + } No Thanks OK - \ No newline at end of file + *@ \ No newline at end of file diff --git a/UserService/Pages/SecurityGroups.razor b/UserService/Pages/SecurityGroups.razor index fdbfba0..0904a02 100644 --- a/UserService/Pages/SecurityGroups.razor +++ b/UserService/Pages/SecurityGroups.razor @@ -13,47 +13,47 @@ } else { - - - Common Name - Description - E-Mail - Parent - - - - - @context.CommonName - @context.Description - @context.EMail - @context.Parent - edit - delete + @* + + Common Name + Description + E-Mail + Parent + + + + + @context.CommonName + @context.Description + @context.EMail + @context.Parent + edit + delete - - - Create new group + + + Create new group*@ } - - @if (SecurityGroupToEdit != null) - { - @(SecurityGroupToEdit.Id == 0 ? "New" : "Edit") @SecurityGroupToEdit.CommonName (@SecurityGroupToEdit.Id) - - -

- - -

- - - } - else - { - No securityGroup selected - } - - No Thanks - OK - - \ No newline at end of file +@* + @if (SecurityGroupToEdit != null) + { + @(SecurityGroupToEdit.Id == 0 ? "New" : "Edit") @SecurityGroupToEdit.CommonName (@SecurityGroupToEdit.Id) + + +

+ + +

+ + + } + else + { + No securityGroup selected + } + + No Thanks + OK + + *@ \ No newline at end of file diff --git a/UserService/Pages/Users.razor b/UserService/Pages/Users.razor index 6bc2fd3..77ac95a 100644 --- a/UserService/Pages/Users.razor +++ b/UserService/Pages/Users.razor @@ -12,55 +12,55 @@ } else { - - - Common Name - Full name - Description - E-Mail - Parent - Is active - - - - - @context.CommonName - @context.FullName - @context.Description - @context.EMail - @context.Parent - @context.IsActive - edit - delete - - + @* + + Common Name + Full name + Description + E-Mail + Parent + Is active + + + + + @context.CommonName + @context.FullName + @context.Description + @context.EMail + @context.Parent + @context.IsActive + edit + delete + + - Create user + Create user*@ } - - @if (UserToEdit != null) - { - @(UserToEdit.Id == 0 ? "New" : "Edit") @UserToEdit.CommonName (@UserToEdit.Id) - - - -

- - -

- - -

- - - } - else - { - No securityGroup selected - } - - No Thanks - OK - - \ No newline at end of file +@* + @if (UserToEdit != null) + { + @(UserToEdit.Id == 0 ? "New" : "Edit") @UserToEdit.CommonName (@UserToEdit.Id) + + + +

+ + +

+ + +

+ + + } + else + { + No securityGroup selected + } + + No Thanks + OK + + *@ \ No newline at end of file diff --git a/UserService/Pages/_Host.cshtml b/UserService/Pages/_Host.cshtml index 8b3f80a..b5f61a9 100644 --- a/UserService/Pages/_Host.cshtml +++ b/UserService/Pages/_Host.cshtml @@ -8,33 +8,41 @@ - - + + UserService - + + - - - + + + + + + + - - - + + + -

- - An error has occurred. This application may no longer respond until reloaded. - - - An unhandled exception has occurred. See browser dev tools for details. - - Reload - 🗙 -
- - - - +
+ + An error has occurred. This application may no longer respond until reloaded. + + + An unhandled exception has occurred. See browser dev tools for details. + + Reload + 🗙 +
+ + + + + + + \ No newline at end of file diff --git a/UserService/Shared/NavMenu.razor b/UserService/Shared/NavMenu.razor index d1a68c0..5e569fa 100644 --- a/UserService/Shared/NavMenu.razor +++ b/UserService/Shared/NavMenu.razor @@ -1,49 +1,26 @@ - - - -
- -
+ @code { - private bool _collapseNavMenu = true; + private SidebarInfo _sidebarInfo; - private string NavMenuCssClass => _collapseNavMenu ? "collapse" : null; - - private void ToggleNavMenu() + protected override void OnInitialized() { - _collapseNavMenu = !_collapseNavMenu; + _sidebarInfo = new SidebarInfo + { + Brand = new SidebarBrandInfo + { + Text = "SidebarBrand", + To = "/" + }, Items = new List + { + new SidebarItemInfo + { + Text = "Directory", + Icon = IconName.Folder, + To = "/directory" + } + } + }; } } \ No newline at end of file diff --git a/UserService/Shared/SurveyPrompt.razor b/UserService/Shared/SurveyPrompt.razor deleted file mode 100644 index e9706c8..0000000 --- a/UserService/Shared/SurveyPrompt.razor +++ /dev/null @@ -1,16 +0,0 @@ - - -@code { - // Demonstrates how a parent component can supply parameters - [Parameter] - public string Title { get; set; } -} diff --git a/UserService/Startup.cs b/UserService/Startup.cs index e43811c..b3c667e 100644 --- a/UserService/Startup.cs +++ b/UserService/Startup.cs @@ -1,4 +1,7 @@ using System.Net.Http; +using Blazorise; +using Blazorise.Bootstrap; +using Blazorise.Icons.FontAwesome; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; @@ -26,7 +29,13 @@ namespace UserService services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddScoped(); + services + .AddBlazorise(options => + { + options.ChangeTextOnKeyPress = true; // optional + }) + .AddBootstrapProviders() + .AddFontAwesomeIcons(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -48,6 +57,10 @@ namespace UserService app.UseRouting(); + app.ApplicationServices + .UseBootstrapProviders() + .UseFontAwesomeIcons(); + app.UseEndpoints(endpoints => { endpoints.MapBlazorHub(); @@ -55,4 +68,4 @@ namespace UserService }); } } -} +} \ No newline at end of file diff --git a/UserService/UserService.csproj b/UserService/UserService.csproj index 1217d5d..990bac0 100644 --- a/UserService/UserService.csproj +++ b/UserService/UserService.csproj @@ -5,12 +5,15 @@ enable - - - - + + + + + + + diff --git a/UserService/_Imports.razor b/UserService/_Imports.razor index 2e8ba2a..ea8639c 100644 --- a/UserService/_Imports.razor +++ b/UserService/_Imports.razor @@ -7,4 +7,7 @@ @using Microsoft.JSInterop @using UserService @using UserService.Shared -@using MatBlazor \ No newline at end of file +@using Blazorise +@using Blazorise.Sidebar +@using Blazorise.TreeView + -- 2.49.0 From 8eace42aaa53eab7376c2d239ddc3414296fd928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Mon, 3 Aug 2020 22:41:50 +0200 Subject: [PATCH 02/11] little work --- UserService.DatabaseLayer/Repository/BaseRepository.cs | 2 +- UserService/Pages/Directory.razor.cs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/UserService.DatabaseLayer/Repository/BaseRepository.cs b/UserService.DatabaseLayer/Repository/BaseRepository.cs index 7df73ec..c9e58b0 100644 --- a/UserService.DatabaseLayer/Repository/BaseRepository.cs +++ b/UserService.DatabaseLayer/Repository/BaseRepository.cs @@ -24,7 +24,7 @@ namespace UserService.DatabaseLayer.Repository await using var db = new UserServiceDbContext(); IQueryable queryable = Context(db).Include(x => x.Parent); - if(queryable != null) queryable = queryable.Where(predicate); + if(predicate != null) queryable = queryable.Where(predicate); return await queryable.ToListAsync(token); } diff --git a/UserService/Pages/Directory.razor.cs b/UserService/Pages/Directory.razor.cs index 4a7ac5c..31b6510 100644 --- a/UserService/Pages/Directory.razor.cs +++ b/UserService/Pages/Directory.razor.cs @@ -26,9 +26,12 @@ namespace UserService.Pages private async void OnSelectedNodeChanged(Node? value) { - Members = await UsersRepository.GetAllAsync(); + if (value == null) return; + Members = await UsersRepository.GetAllAsync(x => x.ParentId == value.Id); } + public IReadOnlyList Members { get; set; } + [Inject] public IOrganizationUnitsRepository OuRepository { get; set; } [Inject] public IUsersRepository UsersRepository { get; set; } -- 2.49.0 From 5d3c64d193454f1b7cf580c53f4bc1dde78efbad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Tue, 4 Aug 2020 22:47:35 +0200 Subject: [PATCH 03/11] Added very nice DataGrid control --- UserService.DatabaseLayer/DataModels/Node.cs | 17 --- UserService.DatabaseLayer/Queryable.cs | 17 +++ .../Repository/BaseRepository.cs | 5 +- .../Repository/OrganizationUnitsRepository.cs | 50 ++++++++ .../Repository/Repository.cs | 121 ------------------ .../Repository/SecurityGroupsRepository.cs | 11 ++ .../Repository/UsersRepository.cs | 11 ++ UserService.Test/UnitTest1.cs | 11 +- UserService.db | Bin 40960 -> 40960 bytes UserService/App.razor | 5 +- UserService/Pages/Directory.razor | 14 +- UserService/Pages/OrganizationUnits.razor | 65 ---------- UserService/Pages/OrganizationUnits.razor.cs | 41 ------ UserService/Pages/SecurityGroups.razor | 58 ++------- UserService/Pages/Users.razor | 73 +++-------- UserService/Pages/Users.razor.cs | 12 +- UserService/Shared/NavMenu.razor | 18 ++- UserService/Startup.cs | 1 - UserService/UserService.csproj | 1 + UserService/_Imports.razor | 2 +- 20 files changed, 157 insertions(+), 376 deletions(-) create mode 100644 UserService.DatabaseLayer/Queryable.cs create mode 100644 UserService.DatabaseLayer/Repository/OrganizationUnitsRepository.cs delete mode 100644 UserService.DatabaseLayer/Repository/Repository.cs create mode 100644 UserService.DatabaseLayer/Repository/SecurityGroupsRepository.cs create mode 100644 UserService.DatabaseLayer/Repository/UsersRepository.cs delete mode 100644 UserService/Pages/OrganizationUnits.razor delete mode 100644 UserService/Pages/OrganizationUnits.razor.cs diff --git a/UserService.DatabaseLayer/DataModels/Node.cs b/UserService.DatabaseLayer/DataModels/Node.cs index 5484f05..881ad38 100644 --- a/UserService.DatabaseLayer/DataModels/Node.cs +++ b/UserService.DatabaseLayer/DataModels/Node.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.Linq; using System.Text; namespace UserService.DatabaseLayer.DataModels @@ -9,22 +8,6 @@ namespace UserService.DatabaseLayer.DataModels public class OrganizationUnit : Node { public Member? Manager { get; set; } - - /// - public override string ToString() - { - var sb = new StringBuilder(); - if (Level != 0) - { - sb.Append("|"); - } - - sb.Append('-', Level * 4); - - return sb + CommonName; - } - - } public class SecurityGroup : Member diff --git a/UserService.DatabaseLayer/Queryable.cs b/UserService.DatabaseLayer/Queryable.cs new file mode 100644 index 0000000..bc15ede --- /dev/null +++ b/UserService.DatabaseLayer/Queryable.cs @@ -0,0 +1,17 @@ +using System.Linq.Expressions; + +// ReSharper disable once CheckNamespace +namespace System.Linq +{ + public static class Queryable + { + /// + /// Makes a where filtering, if it is not null. + /// + public static IQueryable WhereOrDefault(this IQueryable source, Expression>? predicate) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + return predicate is null ? source : source.Where(predicate); + } + } +} diff --git a/UserService.DatabaseLayer/Repository/BaseRepository.cs b/UserService.DatabaseLayer/Repository/BaseRepository.cs index c9e58b0..32065b7 100644 --- a/UserService.DatabaseLayer/Repository/BaseRepository.cs +++ b/UserService.DatabaseLayer/Repository/BaseRepository.cs @@ -22,10 +22,7 @@ namespace UserService.DatabaseLayer.Repository public virtual async Task> GetAllAsync(Expression>? predicate = null, CancellationToken token = default) { await using var db = new UserServiceDbContext(); - - IQueryable queryable = Context(db).Include(x => x.Parent); - if(predicate != null) queryable = queryable.Where(predicate); - return await queryable.ToListAsync(token); + return await Context(db).Include(x => x.Parent).WhereOrDefault(predicate).ToListAsync(token); } public async Task GetAsync(Expression> predicate, CancellationToken token = default) diff --git a/UserService.DatabaseLayer/Repository/OrganizationUnitsRepository.cs b/UserService.DatabaseLayer/Repository/OrganizationUnitsRepository.cs new file mode 100644 index 0000000..08e5222 --- /dev/null +++ b/UserService.DatabaseLayer/Repository/OrganizationUnitsRepository.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using UserService.DatabaseLayer.DataModels; + +namespace UserService.DatabaseLayer.Repository +{ + public class OrganizationUnitsRepository : BaseRepository, IOrganizationUnitsRepository + { + public OrganizationUnitsRepository() : base(x => x.OrganizationUnits) + { + } + + /// + public override async Task> GetAllAsync( + Expression>? predicate = null, CancellationToken token = default) + { + await using var db = new UserServiceDbContext(); + var result = new List(); + var rootOus = await Context(db) + .Include(x => x.Parent) + .WhereOrDefault(predicate) + .ToListAsync(cancellationToken: token); + + IEnumerable Rec(Node node) + { + if (!(node is OrganizationUnit organizationUnit)) yield break; + yield return organizationUnit; + foreach (var ouChild in rootOus.Where(x => x.ParentId != null && x.ParentId == organizationUnit.Id)) + { + foreach (var unit in Rec(ouChild)) + { + yield return unit; + } + } + } + + foreach (var ou in rootOus.Where(x => x.ParentId is null)) + { + result.AddRange(Rec(ou)); + } + + return result; + } + } +} \ No newline at end of file diff --git a/UserService.DatabaseLayer/Repository/Repository.cs b/UserService.DatabaseLayer/Repository/Repository.cs deleted file mode 100644 index 86afdd3..0000000 --- a/UserService.DatabaseLayer/Repository/Repository.cs +++ /dev/null @@ -1,121 +0,0 @@ -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 Microsoft.EntityFrameworkCore; -using UserService.DatabaseLayer.DataModels; - -namespace UserService.DatabaseLayer.Repository -{ - public class OrganizationUnitsRepository : BaseRepository, IOrganizationUnitsRepository - { - public OrganizationUnitsRepository() : base(x => x.OrganizationUnits) - { - } - - /// - public override async Task> GetAllAsync(CancellationToken token = default) - { - - - await using var db = new UserServiceDbContext(); - var result = new List(); - var rootOus = await Context(db) - .Include(x => x.Parent) - .ToListAsync(token); - - IEnumerable Rec(Node node) - { - if (!(node is OrganizationUnit organizationUnit)) yield break; - yield return organizationUnit; - foreach (var ouChild in rootOus.Where(x=>x.ParentId != null && x.ParentId == organizationUnit.Id)) - { - foreach (var unit in Rec(ouChild)) - { - yield return unit; - } - } - } - foreach (var ou in rootOus.Where(x=> x.ParentId is null)) - { - result.AddRange(Rec(ou)); - } - return result; - } - } - - public class SecurityGroupsRepository : BaseRepository, ISecurityGroupsRepository - { - public SecurityGroupsRepository() : base(x=> x.SecurityGroups) - { - } - } - - - public class UsersRepository : BaseRepository, IUsersRepository - { - public UsersRepository() : base(x => x.Users) - { - } - } - - public class NodesRepository : INodesRepository - { - public NodesRepository() - { - } - - public static async IAsyncEnumerable 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> GetAllAsync(CancellationToken token = default) - { - - var list = new List(); - await foreach (var node in GetNodesAsync(token)) - { - list.Add(node); - } - - return list; - } - - public Task GetAsync(Expression> 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(); - } - } -} \ No newline at end of file diff --git a/UserService.DatabaseLayer/Repository/SecurityGroupsRepository.cs b/UserService.DatabaseLayer/Repository/SecurityGroupsRepository.cs new file mode 100644 index 0000000..0f4ce54 --- /dev/null +++ b/UserService.DatabaseLayer/Repository/SecurityGroupsRepository.cs @@ -0,0 +1,11 @@ +using UserService.DatabaseLayer.DataModels; + +namespace UserService.DatabaseLayer.Repository +{ + public class SecurityGroupsRepository : BaseRepository, ISecurityGroupsRepository + { + public SecurityGroupsRepository() : base(x => x.SecurityGroups) + { + } + } +} \ No newline at end of file diff --git a/UserService.DatabaseLayer/Repository/UsersRepository.cs b/UserService.DatabaseLayer/Repository/UsersRepository.cs new file mode 100644 index 0000000..95421ca --- /dev/null +++ b/UserService.DatabaseLayer/Repository/UsersRepository.cs @@ -0,0 +1,11 @@ +using UserService.DatabaseLayer.DataModels; + +namespace UserService.DatabaseLayer.Repository +{ + public class UsersRepository : BaseRepository, IUsersRepository + { + public UsersRepository() : base(x => x.Users) + { + } + } +} \ No newline at end of file diff --git a/UserService.Test/UnitTest1.cs b/UserService.Test/UnitTest1.cs index 10d9223..4fd7428 100644 --- a/UserService.Test/UnitTest1.cs +++ b/UserService.Test/UnitTest1.cs @@ -1,11 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using NUnit.Framework; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; using UserService.DatabaseLayer.DataModels; namespace UserService.Test @@ -45,7 +43,6 @@ namespace UserService.Test NewMethod(ous, null, 0, ref sb); var result = sb.ToString(); Assert.Pass(); - } private static void NewMethod(IEnumerable ous, Node parent, int level, ref StringBuilder sb) diff --git a/UserService.db b/UserService.db index a58f715c4fe64657c72fe9d82a82469b3d78bf70..0dafeee3a7baea65d68fcf3ce55865aec5426161 100644 GIT binary patch delta 154 zcmZoTz|?SnX#7c=tTh5aQ!s$;f|`{~P~${wMq& m_+Rng+bmJg%|9`KWAe)SXl6eCU6a`xK-#A9Z{F4KCIA2(xElfh diff --git a/UserService/App.razor b/UserService/App.razor index ece7489..9c5b0e0 100644 --- a/UserService/App.razor +++ b/UserService/App.razor @@ -1,5 +1,4 @@ - - + @@ -10,4 +9,4 @@ - + \ No newline at end of file diff --git a/UserService/Pages/Directory.razor b/UserService/Pages/Directory.razor index 39bb61c..a7eed1e 100644 --- a/UserService/Pages/Directory.razor +++ b/UserService/Pages/Directory.razor @@ -1,14 +1,6 @@ @page "/directory" -@using UserService.DatabaseLayer.Repository -@inject IOrganizationUnitsRepository OuRepository @inherits DirectoryBase -@functions { - - - -} -

TODO

@@ -29,12 +21,12 @@ else HasChildNodes="@(item => item?.Children?.Any() == true)" @bind-SelectedNode="@SelectedNode"> - + @context?.CommonName - + +
-
diff --git a/UserService/Pages/OrganizationUnits.razor b/UserService/Pages/OrganizationUnits.razor deleted file mode 100644 index ff8896c..0000000 --- a/UserService/Pages/OrganizationUnits.razor +++ /dev/null @@ -1,65 +0,0 @@ -@page "/organizationUnits" -@using UserService.DatabaseLayer.DataModels -@inherits OrganizationUnitsBase - -

List of all organization units

- -@if (OrganizationUnits is null) -{ -

- Loading... -

-} -else -{ - - - - @* - - Common Name - Description - Parent - Manager - - - - - @context.CommonName - @context.Description - @context.Parent - @context.Manager - - edit - - - delete - - - *@ - - Create organization unit -} - -@* - @if (OuToEdit != null) - { - @(OuToEdit.Id == 0 ? "New" : "Edit") @OuToEdit.CommonName (@OuToEdit.Id) - - -

- - @**@ -@*

- - - } - else - { - No securityGroup selected - } - - No Thanks - OK - - *@ \ No newline at end of file diff --git a/UserService/Pages/OrganizationUnits.razor.cs b/UserService/Pages/OrganizationUnits.razor.cs deleted file mode 100644 index 637a122..0000000 --- a/UserService/Pages/OrganizationUnits.razor.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Components; -using UserService.DatabaseLayer.DataModels; -using UserService.DatabaseLayer.Repository; - -namespace UserService.Pages -{ - public class OrganizationUnitsBase : ComponentBase - { - [Inject] private IOrganizationUnitsRepository OrganizationUnitsRepository { get; set; } = null!; - - protected bool DialogIsOpen { get; set; } - protected OrganizationUnit? OuToEdit { get; private set; } - - protected IReadOnlyList? OrganizationUnits { get; private set; } - - protected override async Task OnInitializedAsync() - { - OrganizationUnits = await OrganizationUnitsRepository.GetAllAsync().ConfigureAwait(false); - } - - protected void Edit(OrganizationUnit organizationUnit) - { - DialogIsOpen = true; - OuToEdit = organizationUnit; - } - - protected async Task OkClick() - { - if (OuToEdit is null) return; - await OrganizationUnitsRepository.UpdateAsync(OuToEdit).ConfigureAwait(false); - DialogIsOpen = false; - } - - protected async Task Delete(OrganizationUnit organizationUnit) - { - await OrganizationUnitsRepository.DeleteAsync(organizationUnit).ConfigureAwait(false); - } - } -} \ No newline at end of file diff --git a/UserService/Pages/SecurityGroups.razor b/UserService/Pages/SecurityGroups.razor index 0904a02..e21b1e7 100644 --- a/UserService/Pages/SecurityGroups.razor +++ b/UserService/Pages/SecurityGroups.razor @@ -1,59 +1,21 @@ @page "/securitygroups" @using UserService.DatabaseLayer.DataModels -@using UserService.DatabaseLayer.Repository @inherits SecurityGroupsBase

Table of all security groups

@if (SecurityGroups is null) { -

- Loading... -

+

+ Loading... +

} else { - @* - - Common Name - Description - E-Mail - Parent - - - - - @context.CommonName - @context.Description - @context.EMail - @context.Parent - edit - delete - - - - Create new group*@ -} - -@* - @if (SecurityGroupToEdit != null) - { - @(SecurityGroupToEdit.Id == 0 ? "New" : "Edit") @SecurityGroupToEdit.CommonName (@SecurityGroupToEdit.Id) - - -

- - -

- - - } - else - { - No securityGroup selected - } - - No Thanks - OK - - *@ \ No newline at end of file + + + + + + +} \ No newline at end of file diff --git a/UserService/Pages/Users.razor b/UserService/Pages/Users.razor index 77ac95a..ed95eb6 100644 --- a/UserService/Pages/Users.razor +++ b/UserService/Pages/Users.razor @@ -12,55 +12,24 @@ } else { - @* - - Common Name - Full name - Description - E-Mail - Parent - Is active - - - - - @context.CommonName - @context.FullName - @context.Description - @context.EMail - @context.Parent - @context.IsActive - edit - delete - - - - Create user*@ -} - -@* - @if (UserToEdit != null) - { - @(UserToEdit.Id == 0 ? "New" : "Edit") @UserToEdit.CommonName (@UserToEdit.Id) - - - -

- - -

- - -

- - - } - else - { - No securityGroup selected - } - - No Thanks - OK - - *@ \ No newline at end of file + + + + + + + + + + + + + + + + + + + + +} \ No newline at end of file diff --git a/UserService/Pages/Users.razor.cs b/UserService/Pages/Users.razor.cs index 8aac50e..0c712a9 100644 --- a/UserService/Pages/Users.razor.cs +++ b/UserService/Pages/Users.razor.cs @@ -1,6 +1,7 @@ -using System.Collections.Generic; +using Microsoft.AspNetCore.Components; +using System.Collections.Generic; using System.Threading.Tasks; -using Microsoft.AspNetCore.Components; +using Blazorise.DataGrid; using UserService.DatabaseLayer.DataModels; using UserService.DatabaseLayer.Repository; @@ -40,5 +41,12 @@ namespace UserService.Pages { await UsersRepository.DeleteAsync(user).ConfigureAwait(false); } + + protected async Task RowInsertedCallback(SavedRowItem> obj) + { + var user = obj.Item; + user.ParentId = -2; + await UsersRepository.AddAsync(user); + } } } \ No newline at end of file diff --git a/UserService/Shared/NavMenu.razor b/UserService/Shared/NavMenu.razor index 5e569fa..3fb8567 100644 --- a/UserService/Shared/NavMenu.razor +++ b/UserService/Shared/NavMenu.razor @@ -9,18 +9,30 @@ { Brand = new SidebarBrandInfo { - Text = "SidebarBrand", + Text = "User service", To = "/" - }, Items = new List + }, + Items = new List { new SidebarItemInfo { Text = "Directory", Icon = IconName.Folder, To = "/directory" + }, + new SidebarItemInfo + { + Text = "Users", + Icon = IconName.Users, + To = "/users" + }, + new SidebarItemInfo + { + Text = "Security groups", + Icon = IconName.Book, + To = "/securitygroups" } } }; } - } \ No newline at end of file diff --git a/UserService/Startup.cs b/UserService/Startup.cs index b3c667e..dfd5430 100644 --- a/UserService/Startup.cs +++ b/UserService/Startup.cs @@ -1,4 +1,3 @@ -using System.Net.Http; using Blazorise; using Blazorise.Bootstrap; using Blazorise.Icons.FontAwesome; diff --git a/UserService/UserService.csproj b/UserService/UserService.csproj index 990bac0..ebd1211 100644 --- a/UserService/UserService.csproj +++ b/UserService/UserService.csproj @@ -11,6 +11,7 @@ + diff --git a/UserService/_Imports.razor b/UserService/_Imports.razor index ea8639c..8a87504 100644 --- a/UserService/_Imports.razor +++ b/UserService/_Imports.razor @@ -10,4 +10,4 @@ @using Blazorise @using Blazorise.Sidebar @using Blazorise.TreeView - +@using Blazorise.DataGrid -- 2.49.0 From 07f466d74b909152bf9fdcd386382351a33567a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Thu, 6 Aug 2020 20:31:48 +0200 Subject: [PATCH 04/11] modified user view --- UserService.db | Bin 40960 -> 40960 bytes UserService/Pages/Users.razor | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/UserService.db b/UserService.db index 0dafeee3a7baea65d68fcf3ce55865aec5426161..52aa9e57426b1a08190f8baa5a0289305d763cd3 100644 GIT binary patch delta 159 zcmZoTz|?SnX#Q4ka0pUcR9lm8q4dj2Q; zANXJK-{W7*KXEbGKhDXE>l2v;_%}>uZ;)r=-vG3_gP)a!nSqgW^VWWE F0RWHSF|Yst delta 88 zcmZoTz|?SnX#>9R6#TU!~l-Ti|Z4a`T4g_W^Vv#?B}1np`T^*&VF|R0PJxd4*&oF diff --git a/UserService/Pages/Users.razor b/UserService/Pages/Users.razor index ed95eb6..a0cfbc3 100644 --- a/UserService/Pages/Users.razor +++ b/UserService/Pages/Users.razor @@ -15,13 +15,13 @@ else - + - + - + -- 2.49.0 From d58a8702b33cb3f456ae7dc4dee5fad136999934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Thu, 6 Aug 2020 22:57:25 +0200 Subject: [PATCH 05/11] little modifications to users --- .idea/.idea.UserService/.idea/indexLayout.xml | 8 +++ .idea/.idea.UserService/.idea/modules.xml | 8 +++ .../.idea/projectSettingsUpdater.xml | 6 +++ .idea/.idea.UserService/.idea/vcs.xml | 6 +++ .idea/.idea.UserService/riderModule.iml | 15 ++++++ UserService.DatabaseLayer/DataModels/Node.cs | 2 +- .../Repository/BaseRepository.cs | 5 +- .../Repository/IRepository.cs | 2 +- UserService.db | Bin 40960 -> 40960 bytes UserService/Pages/Users.razor | 4 +- UserService/Pages/Users.razor.cs | 46 +++++++++--------- 11 files changed, 74 insertions(+), 28 deletions(-) create mode 100644 .idea/.idea.UserService/.idea/indexLayout.xml create mode 100644 .idea/.idea.UserService/.idea/modules.xml create mode 100644 .idea/.idea.UserService/.idea/projectSettingsUpdater.xml create mode 100644 .idea/.idea.UserService/.idea/vcs.xml create mode 100644 .idea/.idea.UserService/riderModule.iml diff --git a/.idea/.idea.UserService/.idea/indexLayout.xml b/.idea/.idea.UserService/.idea/indexLayout.xml new file mode 100644 index 0000000..27ba142 --- /dev/null +++ b/.idea/.idea.UserService/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.UserService/.idea/modules.xml b/.idea/.idea.UserService/.idea/modules.xml new file mode 100644 index 0000000..9ed9bc0 --- /dev/null +++ b/.idea/.idea.UserService/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.UserService/.idea/projectSettingsUpdater.xml b/.idea/.idea.UserService/.idea/projectSettingsUpdater.xml new file mode 100644 index 0000000..4bb9f4d --- /dev/null +++ b/.idea/.idea.UserService/.idea/projectSettingsUpdater.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/.idea.UserService/.idea/vcs.xml b/.idea/.idea.UserService/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/.idea.UserService/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/.idea.UserService/riderModule.iml b/.idea/.idea.UserService/riderModule.iml new file mode 100644 index 0000000..19473e1 --- /dev/null +++ b/.idea/.idea.UserService/riderModule.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UserService.DatabaseLayer/DataModels/Node.cs b/UserService.DatabaseLayer/DataModels/Node.cs index 881ad38..c5b63f1 100644 --- a/UserService.DatabaseLayer/DataModels/Node.cs +++ b/UserService.DatabaseLayer/DataModels/Node.cs @@ -52,7 +52,7 @@ namespace UserService.DatabaseLayer.DataModels public Node? Parent { get; set; } //Parent public int? ParentId { get; set; } - public override string ToString() => $"[{GetType().Name}] {Id:D5} {CommonName}"; + public override string ToString() => CommonName; public int Level => Parent?.Level + 1 ?? 0; diff --git a/UserService.DatabaseLayer/Repository/BaseRepository.cs b/UserService.DatabaseLayer/Repository/BaseRepository.cs index 32065b7..2df2c97 100644 --- a/UserService.DatabaseLayer/Repository/BaseRepository.cs +++ b/UserService.DatabaseLayer/Repository/BaseRepository.cs @@ -38,11 +38,12 @@ namespace UserService.DatabaseLayer.Repository await db.SaveChangesAsync(token); } - public async Task UpdateAsync(T entity, CancellationToken token = default) + public async Task UpdateAsync(T entity, CancellationToken token = default) { await using var db = new UserServiceDbContext(); Context(db).Update(entity); - await db.SaveChangesAsync(token); + var items= await db.SaveChangesAsync(token); + return items > 0; } public async Task DeleteAsync(T entity, CancellationToken token = default) diff --git a/UserService.DatabaseLayer/Repository/IRepository.cs b/UserService.DatabaseLayer/Repository/IRepository.cs index 189c21a..5a95ac4 100644 --- a/UserService.DatabaseLayer/Repository/IRepository.cs +++ b/UserService.DatabaseLayer/Repository/IRepository.cs @@ -13,7 +13,7 @@ namespace UserService.DatabaseLayer.Repository Task> GetAllAsync(Expression>? predicate = null, CancellationToken token = default); Task GetAsync(Expression> predicate, 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); } diff --git a/UserService.db b/UserService.db index 52aa9e57426b1a08190f8baa5a0289305d763cd3..dd1435b74729284c613821714f65c7bf236939c2 100644 GIT binary patch delta 98 zcmV-o0G57H0854#Vw52+8$562J3vk?$=4+IbU00xtxe`5m=54E!gfT<4z00005v$T&) E5H@-sM*si- delta 98 zcmV-o0G51kLv55W(+548`e56ut9vk?$=4+I4R0RfYte`5m>53sWbfT<4z1Oos8v$T&) E5KIgowg3PC diff --git a/UserService/Pages/Users.razor b/UserService/Pages/Users.razor index a0cfbc3..d420664 100644 --- a/UserService/Pages/Users.razor +++ b/UserService/Pages/Users.razor @@ -12,7 +12,7 @@ } else { - + @@ -29,7 +29,7 @@ else - + } \ No newline at end of file diff --git a/UserService/Pages/Users.razor.cs b/UserService/Pages/Users.razor.cs index 0c712a9..cc16240 100644 --- a/UserService/Pages/Users.razor.cs +++ b/UserService/Pages/Users.razor.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Blazorise.DataGrid; +using Microsoft.JSInterop; using UserService.DatabaseLayer.DataModels; using UserService.DatabaseLayer.Repository; @@ -12,8 +13,7 @@ namespace UserService.Pages [Inject] private IUsersRepository UsersRepository { get; set; } = null!; [Inject] private IOrganizationUnitsRepository OrganizationUnitsRepository { get; set; } = null!; - protected bool DialogIsOpen { get; set; } - protected User? UserToEdit { get; private set; } + [Inject] private IJSRuntime JsRuntime { get; set; } = null!; protected IReadOnlyList? Users { get; private set; } protected IReadOnlyList? OrganizationUnits { get; private set; } @@ -24,29 +24,31 @@ namespace UserService.Pages OrganizationUnits = await OrganizationUnitsRepository.GetAllAsync().ConfigureAwait(false); } - protected void EditUser(User user) + protected async Task RowInsertedCallback(SavedRowItem> arg) { - DialogIsOpen = true; - UserToEdit = user; - } - - protected async Task OkClick() - { - if (UserToEdit is null) return; - await UsersRepository.UpdateAsync(UserToEdit).ConfigureAwait(false); - DialogIsOpen = false; - } - - protected async Task DeleteUser(User user) - { - await UsersRepository.DeleteAsync(user).ConfigureAwait(false); - } - - protected async Task RowInsertedCallback(SavedRowItem> obj) - { - var user = obj.Item; + var user = arg.Item; user.ParentId = -2; await UsersRepository.AddAsync(user); } + + protected async Task RowDeletingCallback(CancellableRowChange arg) + { + var confirmed = await JsRuntime.InvokeAsync("confirm", + $"You are about to delete the user {arg.Item.FullName}. Are you sure?").ConfigureAwait(false); + if (confirmed) + { + await UsersRepository.DeleteAsync(arg.Item).ConfigureAwait(false); + return; + } + + arg.Cancel = true; + } + + protected async Task RowUpdatingCallback(CancellableRowChange> arg) + { + var result = await UsersRepository.UpdateAsync(arg.Item); + arg.Cancel = !result; + } + } } \ No newline at end of file -- 2.49.0 From fc5c6d0ce779f31e0f3dbf062f6271377e63b3b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Sat, 8 Aug 2020 20:03:57 +0200 Subject: [PATCH 06/11] Try to make parent editable --- UserService/Pages/Users.razor | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/UserService/Pages/Users.razor b/UserService/Pages/Users.razor index d420664..344483d 100644 --- a/UserService/Pages/Users.razor +++ b/UserService/Pages/Users.razor @@ -29,7 +29,27 @@ else - + + + @{ + var name = ((User) context).Parent?.CommonName ?? "-"; + @name + } + + + + @{ + + @foreach (var item in OrganizationUnits) + { + + @item.CommonName + } + + } + + + } \ No newline at end of file -- 2.49.0 From 23da5583fd0b065ea8f222c61f0e878c6f574820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Thu, 13 Aug 2020 22:53:44 +0200 Subject: [PATCH 07/11] Added FxCop and get Organization Unit selection running --- .editorconfig | 4 ++++ .../DataModels/ModelBuilderExtensions.cs | 7 ++++++- UserService.DatabaseLayer/DataModels/Node.cs | 4 ++-- .../Repository/BaseRepository.cs | 14 +++++++------- .../Repository/OrganizationUnitsRepository.cs | 2 +- .../UserService.DatabaseLayer.csproj | 8 ++++++-- UserService.Test/UnitTest1.cs | 10 +++++----- UserService.Test/UserService.Test.csproj | 8 ++++++-- UserService.db | Bin 40960 -> 40960 bytes UserService.sln | 5 +++++ UserService/Pages/Directory.razor.cs | 11 +++++------ UserService/Pages/SecurityGroups.razor | 4 ++-- UserService/Pages/SecurityGroups.razor.cs | 14 +++++++------- UserService/Pages/Users.razor | 15 +++++++-------- UserService/Pages/Users.razor.cs | 15 +++++++++++---- UserService/Startup.cs | 2 ++ UserService/UserService.csproj | 8 ++++++++ 17 files changed, 84 insertions(+), 47 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3d25c9a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# CA1822: Member als statisch markieren +dotnet_diagnostic.CA1822.severity = suggestion diff --git a/UserService.DatabaseLayer/DataModels/ModelBuilderExtensions.cs b/UserService.DatabaseLayer/DataModels/ModelBuilderExtensions.cs index d06cd66..68710ae 100644 --- a/UserService.DatabaseLayer/DataModels/ModelBuilderExtensions.cs +++ b/UserService.DatabaseLayer/DataModels/ModelBuilderExtensions.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore; +using System; +using Microsoft.EntityFrameworkCore; using System.Collections.Generic; namespace UserService.DatabaseLayer.DataModels @@ -7,6 +8,7 @@ namespace UserService.DatabaseLayer.DataModels { public static void Seed(this ModelBuilder modelBuilder) { + if (modelBuilder == null) throw new ArgumentNullException(nameof(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}; @@ -25,6 +27,7 @@ namespace UserService.DatabaseLayer.DataModels public static void CreateRelations(this ModelBuilder modelBuilder) { + if (modelBuilder == null) throw new ArgumentNullException(nameof(modelBuilder)); modelBuilder.Entity() .HasKey(bc => new { bc.MemberId, bc.UserId }); modelBuilder.Entity() @@ -47,6 +50,7 @@ namespace UserService.DatabaseLayer.DataModels { public static IEnumerable GetSecurityGroups(this User user) { + if (user == null) throw new ArgumentNullException(nameof(user)); foreach (var userMember in user.MemberOf) { if (userMember.Member is SecurityGroup securityGroup) @@ -62,6 +66,7 @@ namespace UserService.DatabaseLayer.DataModels { public static IEnumerable GetUsers(this SecurityGroup securityGroup) { + if (securityGroup == null) throw new ArgumentNullException(nameof(securityGroup)); foreach (var userMember in securityGroup.Members) { if (userMember.User is null) continue; diff --git a/UserService.DatabaseLayer/DataModels/Node.cs b/UserService.DatabaseLayer/DataModels/Node.cs index c5b63f1..ed5c873 100644 --- a/UserService.DatabaseLayer/DataModels/Node.cs +++ b/UserService.DatabaseLayer/DataModels/Node.cs @@ -1,7 +1,7 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.Text; namespace UserService.DatabaseLayer.DataModels { diff --git a/UserService.DatabaseLayer/Repository/BaseRepository.cs b/UserService.DatabaseLayer/Repository/BaseRepository.cs index 2df2c97..b50f2ee 100644 --- a/UserService.DatabaseLayer/Repository/BaseRepository.cs +++ b/UserService.DatabaseLayer/Repository/BaseRepository.cs @@ -12,7 +12,7 @@ namespace UserService.DatabaseLayer.Repository { public class BaseRepository where T : Node { - protected readonly Func> Context; + protected Func> Context { get; } protected BaseRepository(Func> context) { @@ -22,27 +22,27 @@ namespace UserService.DatabaseLayer.Repository public virtual async Task> GetAllAsync(Expression>? predicate = null, CancellationToken token = default) { await using var db = new UserServiceDbContext(); - return await Context(db).Include(x => x.Parent).WhereOrDefault(predicate).ToListAsync(token); + return await Context(db).Include(x => x.Parent).WhereOrDefault(predicate).ToListAsync(token).ConfigureAwait(false); } public async Task GetAsync(Expression> predicate, CancellationToken token = default) { await using var db = new UserServiceDbContext(); - return await Context(db).FirstOrDefaultAsync(predicate, token); + return await Context(db).FirstOrDefaultAsync(predicate, token).ConfigureAwait(false); } 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); + await Context(db).AddAsync(@entity, token).ConfigureAwait(false); + await db.SaveChangesAsync(token).ConfigureAwait(false); } public async Task UpdateAsync(T entity, CancellationToken token = default) { await using var db = new UserServiceDbContext(); Context(db).Update(entity); - var items= await db.SaveChangesAsync(token); + var items= await db.SaveChangesAsync(token).ConfigureAwait(false); return items > 0; } @@ -50,7 +50,7 @@ namespace UserService.DatabaseLayer.Repository { await using var db = new UserServiceDbContext(); Context(db).Remove(entity); - await db.SaveChangesAsync(token); + await db.SaveChangesAsync(token).ConfigureAwait(false); } } } \ No newline at end of file diff --git a/UserService.DatabaseLayer/Repository/OrganizationUnitsRepository.cs b/UserService.DatabaseLayer/Repository/OrganizationUnitsRepository.cs index 08e5222..7a1fa41 100644 --- a/UserService.DatabaseLayer/Repository/OrganizationUnitsRepository.cs +++ b/UserService.DatabaseLayer/Repository/OrganizationUnitsRepository.cs @@ -24,7 +24,7 @@ namespace UserService.DatabaseLayer.Repository var rootOus = await Context(db) .Include(x => x.Parent) .WhereOrDefault(predicate) - .ToListAsync(cancellationToken: token); + .ToListAsync(cancellationToken: token).ConfigureAwait(false); IEnumerable Rec(Node node) { diff --git a/UserService.DatabaseLayer/UserService.DatabaseLayer.csproj b/UserService.DatabaseLayer/UserService.DatabaseLayer.csproj index c6062ce..fc60665 100644 --- a/UserService.DatabaseLayer/UserService.DatabaseLayer.csproj +++ b/UserService.DatabaseLayer/UserService.DatabaseLayer.csproj @@ -7,11 +7,15 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/UserService.Test/UnitTest1.cs b/UserService.Test/UnitTest1.cs index 4fd7428..0b70fc3 100644 --- a/UserService.Test/UnitTest1.cs +++ b/UserService.Test/UnitTest1.cs @@ -19,10 +19,10 @@ namespace UserService.Test public async Task Test1() { await using var db = new UserServiceDbContext(); - var user = await db.Users.FirstOrDefaultAsync(); - var secGroup = await db.SecurityGroups.FirstOrDefaultAsync(); - var ous = await db.OrganizationUnits.ToListAsync(); - var mo = await db.UserMembers.ToListAsync(); + var user = await db.Users.FirstOrDefaultAsync().ConfigureAwait(false); + var secGroup = await db.SecurityGroups.FirstOrDefaultAsync().ConfigureAwait(false); + var ous = await db.OrganizationUnits.ToListAsync().ConfigureAwait(false); + var mo = await db.UserMembers.ToListAsync().ConfigureAwait(false); var securityGroupsOfUser = user.GetSecurityGroups(); var usersOfSecurityGroup = secGroup.GetUsers(); @@ -38,7 +38,7 @@ namespace UserService.Test public async Task Test2() { await using var db = new UserServiceDbContext(); - var ous = await db.OrganizationUnits.ToListAsync(); + var ous = await db.OrganizationUnits.ToListAsync().ConfigureAwait(false); var sb = new StringBuilder(); NewMethod(ous, null, 0, ref sb); var result = sb.ToString(); diff --git a/UserService.Test/UserService.Test.csproj b/UserService.Test/UserService.Test.csproj index 022e46a..48b2f52 100644 --- a/UserService.Test/UserService.Test.csproj +++ b/UserService.Test/UserService.Test.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 @@ -7,9 +7,13 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - + diff --git a/UserService.db b/UserService.db index dd1435b74729284c613821714f65c7bf236939c2..e800ecad9718b37fe45c3e03a9a4f4b284dd32ec 100644 GIT binary patch delta 40 vcmZoTz|?SnX~P9uMz+ltZ3B$h&+@P2KhA%Av!FmJ|Kz##CP48^^?C{bNLde9 delta 40 vcmZoTz|?SnX~P9uM)u7YZ3B$hSMs0bKhA%Av!FmJ|Kz##CP48^^?C{bNHq^y diff --git a/UserService.sln b/UserService.sln index f9488a0..3136372 100644 --- a/UserService.sln +++ b/UserService.sln @@ -9,6 +9,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UserService.Test", "UserSer EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UserService.DatabaseLayer", "UserService.DatabaseLayer\UserService.DatabaseLayer.csproj", "{4505C991-7E39-416F-94E5-D906DD0D90F9}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A8D411B0-CD71-4448-9D4F-12898D0CCDD6}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/UserService/Pages/Directory.razor.cs b/UserService/Pages/Directory.razor.cs index 31b6510..2e238b7 100644 --- a/UserService/Pages/Directory.razor.cs +++ b/UserService/Pages/Directory.razor.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; @@ -27,14 +26,14 @@ namespace UserService.Pages private async void OnSelectedNodeChanged(Node? value) { if (value == null) return; - Members = await UsersRepository.GetAllAsync(x => x.ParentId == value.Id); + Members = await UsersRepository.GetAllAsync(x => x.ParentId == value.Id).ConfigureAwait(false); } - public IReadOnlyList Members { get; set; } + public IReadOnlyList? Members { get; set; } - [Inject] public IOrganizationUnitsRepository OuRepository { get; set; } + [Inject] public IOrganizationUnitsRepository OuRepository { get; set; } = null!; - [Inject] public IUsersRepository UsersRepository { get; set; } + [Inject] public IUsersRepository UsersRepository { get; set; } = null!; protected override async Task OnInitializedAsync() diff --git a/UserService/Pages/SecurityGroups.razor b/UserService/Pages/SecurityGroups.razor index e21b1e7..21b50da 100644 --- a/UserService/Pages/SecurityGroups.razor +++ b/UserService/Pages/SecurityGroups.razor @@ -4,7 +4,7 @@

Table of all security groups

-@if (SecurityGroups is null) +@if (Groups is null) {

Loading... @@ -12,7 +12,7 @@ } else { - + diff --git a/UserService/Pages/SecurityGroups.razor.cs b/UserService/Pages/SecurityGroups.razor.cs index b1269ba..1c65bfd 100644 --- a/UserService/Pages/SecurityGroups.razor.cs +++ b/UserService/Pages/SecurityGroups.razor.cs @@ -8,18 +8,18 @@ namespace UserService.Pages { public class SecurityGroupsBase : ComponentBase { - [Inject] private ISecurityGroupsRepository? SecurityGroupsRepository { get; set; } - [Inject] private IOrganizationUnitsRepository? OrganizationUnitsRepository { get; set; } + [Inject] private ISecurityGroupsRepository SecurityGroupsRepository { get; set; } = null!; + [Inject] private IOrganizationUnitsRepository OrganizationUnitsRepository { get; set; } = null!; - protected bool DialogIsOpen; - protected SecurityGroup? SecurityGroupToEdit; + protected bool DialogIsOpen { get; set; } + protected SecurityGroup? SecurityGroupToEdit { get; set; } - protected IReadOnlyList? SecurityGroups; - protected IReadOnlyList? OrganizationUnits; + protected IReadOnlyList? Groups { get; set; } + protected IReadOnlyList? OrganizationUnits { get; set; } protected override async Task OnInitializedAsync() { - SecurityGroups = await SecurityGroupsRepository.GetAllAsync().ConfigureAwait(false); + Groups = await SecurityGroupsRepository.GetAllAsync().ConfigureAwait(false); OrganizationUnits = await OrganizationUnitsRepository.GetAllAsync().ConfigureAwait(false); } diff --git a/UserService/Pages/Users.razor b/UserService/Pages/Users.razor index 344483d..16e99a6 100644 --- a/UserService/Pages/Users.razor +++ b/UserService/Pages/Users.razor @@ -29,24 +29,23 @@ else - + @{ - var name = ((User) context).Parent?.CommonName ?? "-"; + var name = ((User) context ).Parent?.CommonName ?? "-"; @name } - @{ - + + + diff --git a/UserService/Pages/Users.razor.cs b/UserService/Pages/Users.razor.cs index cc16240..a134c6f 100644 --- a/UserService/Pages/Users.razor.cs +++ b/UserService/Pages/Users.razor.cs @@ -1,5 +1,7 @@ -using Microsoft.AspNetCore.Components; +using System; +using Microsoft.AspNetCore.Components; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Blazorise.DataGrid; using Microsoft.JSInterop; @@ -20,19 +22,21 @@ namespace UserService.Pages protected override async Task OnInitializedAsync() { - Users = await UsersRepository.GetAllAsync(); + Users = await UsersRepository.GetAllAsync().ConfigureAwait(false); OrganizationUnits = await OrganizationUnitsRepository.GetAllAsync().ConfigureAwait(false); } protected async Task RowInsertedCallback(SavedRowItem> arg) { + if (arg == null) throw new ArgumentNullException(nameof(arg)); var user = arg.Item; user.ParentId = -2; - await UsersRepository.AddAsync(user); + await UsersRepository.AddAsync(user).ConfigureAwait(false); } protected async Task RowDeletingCallback(CancellableRowChange arg) { + if (arg == null) throw new ArgumentNullException(nameof(arg)); var confirmed = await JsRuntime.InvokeAsync("confirm", $"You are about to delete the user {arg.Item.FullName}. Are you sure?").ConfigureAwait(false); if (confirmed) @@ -46,7 +50,10 @@ namespace UserService.Pages protected async Task RowUpdatingCallback(CancellableRowChange> arg) { - var result = await UsersRepository.UpdateAsync(arg.Item); + if (arg == null) throw new ArgumentNullException(nameof(arg)); + var user = arg.Item; + user.Parent = OrganizationUnits.FirstOrDefault(x => x.Id == (int?)arg.Values[nameof(Node.ParentId)]); + var result = await UsersRepository.UpdateAsync(user).ConfigureAwait(false); arg.Cancel = !result; } diff --git a/UserService/Startup.cs b/UserService/Startup.cs index dfd5430..8827107 100644 --- a/UserService/Startup.cs +++ b/UserService/Startup.cs @@ -1,3 +1,4 @@ +using System; using Blazorise; using Blazorise.Bootstrap; using Blazorise.Icons.FontAwesome; @@ -40,6 +41,7 @@ namespace UserService // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { + if (app == null) throw new ArgumentNullException(nameof(app)); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); diff --git a/UserService/UserService.csproj b/UserService/UserService.csproj index ebd1211..1bffdf8 100644 --- a/UserService/UserService.csproj +++ b/UserService/UserService.csproj @@ -5,6 +5,10 @@ enable + + + + @@ -15,6 +19,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + -- 2.49.0 From ccb5b6a15442c62aa8f091a8fbba17234a1723ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Thu, 13 Aug 2020 23:18:11 +0200 Subject: [PATCH 08/11] minor fixes --- .idea/.idea.UserService/riderModule.iml | 6 +++--- UserService.db | Bin 40960 -> 40960 bytes UserService/Pages/Users.razor | 24 ++++++++++++++++++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/.idea/.idea.UserService/riderModule.iml b/.idea/.idea.UserService/riderModule.iml index 19473e1..882628e 100644 --- a/.idea/.idea.UserService/riderModule.iml +++ b/.idea/.idea.UserService/riderModule.iml @@ -1,9 +1,9 @@ - - - + + + diff --git a/UserService.db b/UserService.db index e800ecad9718b37fe45c3e03a9a4f4b284dd32ec..cef1d65e32c2db506dde6510f5271a1def64ea62 100644 GIT binary patch delta 68 zcmZoTz|?SnX@j;cBl~0>+a-*DHea-LFcLq@|AGG%|2_Uo{0I4W^Ka!}$$y-GG5_(+ Yf&!)dljqiR0adT4*95A*RIjH10G(bM-T(jq delta 68 zcmZoTz|?SnX@j;c + - + - + - + + + + + + + -- 2.49.0 From 697886730ebaa5a3b9778dfc53b6fcb8114f532b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Sun, 16 Aug 2020 22:10:23 +0200 Subject: [PATCH 09/11] added validator --- UserService.db | Bin 40960 -> 40960 bytes UserService/Pages/Users.razor | 34 ++++++++++++++++++++---- UserService/Pages/Users.razor.cs | 44 ++++++++++++++++++++++++------- 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/UserService.db b/UserService.db index cef1d65e32c2db506dde6510f5271a1def64ea62..11403be6291cbe783e4caabbba18c425a201ee63 100644 GIT binary patch delta 145 zcmZoTz|?SnX#6O#lD@ delta 146 zcmZoTz|?SnX# + - - + + + + + + + + + Please enter a valid common name! + + + + + - + + + + + + Please enter the email. + Email is ok. + Enter valid email! + + + + + @{ @@ -55,7 +79,7 @@ else - @foreach (var item in OrganizationUnits) { @item.CommonName diff --git a/UserService/Pages/Users.razor.cs b/UserService/Pages/Users.razor.cs index a134c6f..ff80935 100644 --- a/UserService/Pages/Users.razor.cs +++ b/UserService/Pages/Users.razor.cs @@ -1,8 +1,10 @@ using System; using Microsoft.AspNetCore.Components; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; +using Blazorise; using Blazorise.DataGrid; using Microsoft.JSInterop; using UserService.DatabaseLayer.DataModels; @@ -47,15 +49,39 @@ namespace UserService.Pages arg.Cancel = true; } - - protected async Task RowUpdatingCallback(CancellableRowChange> arg) - { - if (arg == null) throw new ArgumentNullException(nameof(arg)); - var user = arg.Item; - user.Parent = OrganizationUnits.FirstOrDefault(x => x.Id == (int?)arg.Values[nameof(Node.ParentId)]); - var result = await UsersRepository.UpdateAsync(user).ConfigureAwait(false); - arg.Cancel = !result; - } + protected static void ValidateCommonName(ValidatorEventArgs e) + { + if (e == null) throw new ArgumentNullException(nameof(e)); + var commonName = e.Value?.ToString(); + + if (string.IsNullOrEmpty(commonName)) + e.Status = ValidationStatus.Error; + else + e.Status = ValidationStatus.Success; + } + + protected static void ValidateEmail(ValidatorEventArgs e) + { + if (e == null) throw new ArgumentNullException(nameof(e)); + var email = e.Value?.ToString(); + + if (string.IsNullOrEmpty(email)) + e.Status = ValidationStatus.None; + else if (!new EmailAddressAttribute().IsValid(email)) + { + e.Status = ValidationStatus.Error; + } + else + e.Status = ValidationStatus.Success; + } + protected async Task RowUpdatingCallback(CancellableRowChange> arg) + { + if (arg == null) throw new ArgumentNullException(nameof(arg)); + var user = arg.Item; + user.Parent = OrganizationUnits.FirstOrDefault(x => x.Id == (int?) arg.Values[nameof(Node.ParentId)]); + var result = await UsersRepository.UpdateAsync(user).ConfigureAwait(false); + arg.Cancel = !result; + } } } \ No newline at end of file -- 2.49.0 From 8fcd1c4c44ed0be5b5ace5f2dbdbf1dc894854e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Tue, 18 Aug 2020 21:59:10 +0200 Subject: [PATCH 10/11] Working on users view, added infrastructure lib --- .../DataModels/ModelBuilderExtensions.cs | 1 + UserService.DatabaseLayer/DataModels/Node.cs | 62 ------------------ .../DataModels/UserServiceDbContext.cs | 1 + .../UserServiceDbContextModelSnapshot.cs | 3 +- .../Repository/BaseRepository.cs | 1 + .../Repository/IRepository.cs | 2 +- .../Repository/OrganizationUnitsRepository.cs | 1 + .../Repository/SecurityGroupsRepository.cs | 2 +- .../Repository/UsersRepository.cs | 2 +- .../UserService.DatabaseLayer.csproj | 6 +- .../DataModels/Member.cs | 13 ++++ UserService.Infrastructure/DataModels/Node.cs | 24 +++++++ .../DataModels/OrganizationUnit.cs | 7 ++ .../DataModels/SecurityGroup.cs | 6 ++ UserService.Infrastructure/DataModels/User.cs | 15 +++++ .../DataModels/UserMember.cs | 12 ++++ .../UserService.Infrastructure.csproj | 12 ++++ UserService.Infrastructure/Validators.cs | 22 +++++++ UserService.Test/UnitTest1.cs | 1 + UserService.Test/UserService.Test.csproj | 2 + UserService.db | Bin 40960 -> 40960 bytes UserService.sln | 6 ++ UserService/Pages/Directory.razor.cs | 2 +- UserService/Pages/SecurityGroups.razor | 2 +- UserService/Pages/SecurityGroups.razor.cs | 2 +- UserService/Pages/Users.razor | 13 ++-- UserService/Pages/Users.razor.cs | 61 +++++++++++------ UserService/UserService.csproj | 2 + 28 files changed, 184 insertions(+), 99 deletions(-) delete mode 100644 UserService.DatabaseLayer/DataModels/Node.cs create mode 100644 UserService.Infrastructure/DataModels/Member.cs create mode 100644 UserService.Infrastructure/DataModels/Node.cs create mode 100644 UserService.Infrastructure/DataModels/OrganizationUnit.cs create mode 100644 UserService.Infrastructure/DataModels/SecurityGroup.cs create mode 100644 UserService.Infrastructure/DataModels/User.cs create mode 100644 UserService.Infrastructure/DataModels/UserMember.cs create mode 100644 UserService.Infrastructure/UserService.Infrastructure.csproj create mode 100644 UserService.Infrastructure/Validators.cs diff --git a/UserService.DatabaseLayer/DataModels/ModelBuilderExtensions.cs b/UserService.DatabaseLayer/DataModels/ModelBuilderExtensions.cs index 68710ae..e2be228 100644 --- a/UserService.DatabaseLayer/DataModels/ModelBuilderExtensions.cs +++ b/UserService.DatabaseLayer/DataModels/ModelBuilderExtensions.cs @@ -1,6 +1,7 @@ using System; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; +using UserService.Infrastructure.DataModels; namespace UserService.DatabaseLayer.DataModels { diff --git a/UserService.DatabaseLayer/DataModels/Node.cs b/UserService.DatabaseLayer/DataModels/Node.cs deleted file mode 100644 index ed5c873..0000000 --- a/UserService.DatabaseLayer/DataModels/Node.cs +++ /dev/null @@ -1,62 +0,0 @@ -#nullable enable -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; - -namespace UserService.DatabaseLayer.DataModels -{ - public class OrganizationUnit : Node - { - public Member? Manager { get; set; } - } - - public class SecurityGroup : Member - { - } - - public class User : Member - { - public string? FirstName { get; set; } - public string? LastName { get; set; } - public bool IsActive { get; set; } - - public string FullName => $"{FirstName} {LastName}"; - - public IEnumerable MemberOf { get; set; } = new List(); - } - - public class UserMember - { - public int MemberId { get; set; } - public Member? Member { get; set; } - - public int UserId { get; set; } - - public User? User { get; set; } - } - - public abstract class Member : Node - { - [EmailAddress] - public string? EMail { get; set; } - - public ICollection Members { get; set; } = new List(); - } - - public abstract class Node : ICloneable - { - public int Id { get; set; } - [Required] public string CommonName { get; set; } = null!; - public string? Description { get; set; } - public ICollection Children { get; set; } = new List(); - public Node? Parent { get; set; } //Parent - public int? ParentId { get; set; } - - public override string ToString() => CommonName; - - public int Level => Parent?.Level + 1 ?? 0; - - /// - public virtual object Clone() => MemberwiseClone(); - } -} \ No newline at end of file diff --git a/UserService.DatabaseLayer/DataModels/UserServiceDbContext.cs b/UserService.DatabaseLayer/DataModels/UserServiceDbContext.cs index 68c5567..cd9e5d8 100644 --- a/UserService.DatabaseLayer/DataModels/UserServiceDbContext.cs +++ b/UserService.DatabaseLayer/DataModels/UserServiceDbContext.cs @@ -1,4 +1,5 @@ using Microsoft.EntityFrameworkCore; +using UserService.Infrastructure.DataModels; namespace UserService.DatabaseLayer.DataModels { diff --git a/UserService.DatabaseLayer/Migrations/UserServiceDbContextModelSnapshot.cs b/UserService.DatabaseLayer/Migrations/UserServiceDbContextModelSnapshot.cs index 4d03a6e..c9aa074 100644 --- a/UserService.DatabaseLayer/Migrations/UserServiceDbContextModelSnapshot.cs +++ b/UserService.DatabaseLayer/Migrations/UserServiceDbContextModelSnapshot.cs @@ -1,8 +1,7 @@ // -using System; + using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using UserService.DatabaseLayer.DataModels; namespace UserService.DatabaseLayer.Migrations diff --git a/UserService.DatabaseLayer/Repository/BaseRepository.cs b/UserService.DatabaseLayer/Repository/BaseRepository.cs index b50f2ee..61db729 100644 --- a/UserService.DatabaseLayer/Repository/BaseRepository.cs +++ b/UserService.DatabaseLayer/Repository/BaseRepository.cs @@ -7,6 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using UserService.DatabaseLayer.DataModels; +using UserService.Infrastructure.DataModels; namespace UserService.DatabaseLayer.Repository { diff --git a/UserService.DatabaseLayer/Repository/IRepository.cs b/UserService.DatabaseLayer/Repository/IRepository.cs index 5a95ac4..74058e5 100644 --- a/UserService.DatabaseLayer/Repository/IRepository.cs +++ b/UserService.DatabaseLayer/Repository/IRepository.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; -using UserService.DatabaseLayer.DataModels; +using UserService.Infrastructure.DataModels; namespace UserService.DatabaseLayer.Repository { diff --git a/UserService.DatabaseLayer/Repository/OrganizationUnitsRepository.cs b/UserService.DatabaseLayer/Repository/OrganizationUnitsRepository.cs index 7a1fa41..fa44e7c 100644 --- a/UserService.DatabaseLayer/Repository/OrganizationUnitsRepository.cs +++ b/UserService.DatabaseLayer/Repository/OrganizationUnitsRepository.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using UserService.DatabaseLayer.DataModels; +using UserService.Infrastructure.DataModels; namespace UserService.DatabaseLayer.Repository { diff --git a/UserService.DatabaseLayer/Repository/SecurityGroupsRepository.cs b/UserService.DatabaseLayer/Repository/SecurityGroupsRepository.cs index 0f4ce54..6948ce7 100644 --- a/UserService.DatabaseLayer/Repository/SecurityGroupsRepository.cs +++ b/UserService.DatabaseLayer/Repository/SecurityGroupsRepository.cs @@ -1,4 +1,4 @@ -using UserService.DatabaseLayer.DataModels; +using UserService.Infrastructure.DataModels; namespace UserService.DatabaseLayer.Repository { diff --git a/UserService.DatabaseLayer/Repository/UsersRepository.cs b/UserService.DatabaseLayer/Repository/UsersRepository.cs index 95421ca..cb60251 100644 --- a/UserService.DatabaseLayer/Repository/UsersRepository.cs +++ b/UserService.DatabaseLayer/Repository/UsersRepository.cs @@ -1,4 +1,4 @@ -using UserService.DatabaseLayer.DataModels; +using UserService.Infrastructure.DataModels; namespace UserService.DatabaseLayer.Repository { diff --git a/UserService.DatabaseLayer/UserService.DatabaseLayer.csproj b/UserService.DatabaseLayer/UserService.DatabaseLayer.csproj index fc60665..6bd1a27 100644 --- a/UserService.DatabaseLayer/UserService.DatabaseLayer.csproj +++ b/UserService.DatabaseLayer/UserService.DatabaseLayer.csproj @@ -2,7 +2,7 @@ netcoreapp3.1 - 8 + latest enable @@ -18,4 +18,8 @@ + + + + diff --git a/UserService.Infrastructure/DataModels/Member.cs b/UserService.Infrastructure/DataModels/Member.cs new file mode 100644 index 0000000..ee4a4cc --- /dev/null +++ b/UserService.Infrastructure/DataModels/Member.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace UserService.Infrastructure.DataModels +{ + public abstract class Member : Node + { + [EmailAddress] + public string? EMail { get; set; } + + public ICollection Members { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/UserService.Infrastructure/DataModels/Node.cs b/UserService.Infrastructure/DataModels/Node.cs new file mode 100644 index 0000000..6bbb3c0 --- /dev/null +++ b/UserService.Infrastructure/DataModels/Node.cs @@ -0,0 +1,24 @@ +#nullable enable +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace UserService.Infrastructure.DataModels +{ + public abstract class Node : ICloneable + { + public int Id { get; set; } + [Required] public string CommonName { get; set; } = null!; + public string? Description { get; set; } + public ICollection Children { get; set; } = new List(); + public Node? Parent { get; set; } //Parent + public int? ParentId { get; set; } + + public override string ToString() => CommonName; + + public int Level => Parent?.Level + 1 ?? 0; + + /// + public virtual object Clone() => MemberwiseClone(); + } +} \ No newline at end of file diff --git a/UserService.Infrastructure/DataModels/OrganizationUnit.cs b/UserService.Infrastructure/DataModels/OrganizationUnit.cs new file mode 100644 index 0000000..405278a --- /dev/null +++ b/UserService.Infrastructure/DataModels/OrganizationUnit.cs @@ -0,0 +1,7 @@ +namespace UserService.Infrastructure.DataModels +{ + public class OrganizationUnit : Node + { + public Member? Manager { get; set; } + } +} \ No newline at end of file diff --git a/UserService.Infrastructure/DataModels/SecurityGroup.cs b/UserService.Infrastructure/DataModels/SecurityGroup.cs new file mode 100644 index 0000000..78d3a91 --- /dev/null +++ b/UserService.Infrastructure/DataModels/SecurityGroup.cs @@ -0,0 +1,6 @@ +namespace UserService.Infrastructure.DataModels +{ + public class SecurityGroup : Member + { + } +} \ No newline at end of file diff --git a/UserService.Infrastructure/DataModels/User.cs b/UserService.Infrastructure/DataModels/User.cs new file mode 100644 index 0000000..a7f458e --- /dev/null +++ b/UserService.Infrastructure/DataModels/User.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace UserService.Infrastructure.DataModels +{ + public class User : Member + { + public string? FirstName { get; set; } + public string? LastName { get; set; } + public bool IsActive { get; set; } + + public string FullName => $"{FirstName} {LastName}"; + + public IEnumerable MemberOf { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/UserService.Infrastructure/DataModels/UserMember.cs b/UserService.Infrastructure/DataModels/UserMember.cs new file mode 100644 index 0000000..91d4f69 --- /dev/null +++ b/UserService.Infrastructure/DataModels/UserMember.cs @@ -0,0 +1,12 @@ +namespace UserService.Infrastructure.DataModels +{ + public class UserMember + { + public int MemberId { get; set; } + public Member? Member { get; set; } + + public int UserId { get; set; } + + public User? User { get; set; } + } +} \ No newline at end of file diff --git a/UserService.Infrastructure/UserService.Infrastructure.csproj b/UserService.Infrastructure/UserService.Infrastructure.csproj new file mode 100644 index 0000000..551862b --- /dev/null +++ b/UserService.Infrastructure/UserService.Infrastructure.csproj @@ -0,0 +1,12 @@ + + + + netstandard2.0 + latest + + + + + + + diff --git a/UserService.Infrastructure/Validators.cs b/UserService.Infrastructure/Validators.cs new file mode 100644 index 0000000..5eabcf6 --- /dev/null +++ b/UserService.Infrastructure/Validators.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using UserService.Infrastructure.DataModels; + +namespace UserService.Infrastructure +{ + public static class Validators + { + public static bool? ValidateEmail(string mailAddress) + { + if (string.IsNullOrEmpty(mailAddress)) return null; + return new EmailAddressAttribute().IsValid(mailAddress); + } + + public static bool? ValidateCommonName(string commonName, IReadOnlyList users) + { + if (string.IsNullOrEmpty(commonName)) return false; + return users.All(x => x.CommonName != commonName); + } + } +} diff --git a/UserService.Test/UnitTest1.cs b/UserService.Test/UnitTest1.cs index 0b70fc3..8fc8774 100644 --- a/UserService.Test/UnitTest1.cs +++ b/UserService.Test/UnitTest1.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using UserService.DatabaseLayer.DataModels; +using UserService.Infrastructure.DataModels; namespace UserService.Test { diff --git a/UserService.Test/UserService.Test.csproj b/UserService.Test/UserService.Test.csproj index 48b2f52..c20cbd9 100644 --- a/UserService.Test/UserService.Test.csproj +++ b/UserService.Test/UserService.Test.csproj @@ -4,6 +4,8 @@ netcoreapp3.1 false + + latest diff --git a/UserService.db b/UserService.db index 11403be6291cbe783e4caabbba18c425a201ee63..adc6bf48576a35c914c5bf477dd3fb9dc74b6429 100644 GIT binary patch delta 273 zcmZoTz|?SnX#=AH8_!Dy0iM;9*$os}SMz-4nY>w0Af2ZkC@LYzz$nVVz`((fm6(^A zm-sKVIJL-zo0~xzC~ht-&&iOLpOKiCm&gv1fU+Hu@>7eFGg6C+_413-y&wvl4sU~q z@u@Qyr~-9MN~-We%#oDj=VZvp&q+@$G6Gv*=wPImlFIG@7INAwY5Powk#|!7lLF6N z1_A!*jQltGzwxi1EKnf9#y=edf$mM^7vi7G!1j-am6?%|otytRkj*=JaeW*c{|2BY lpywKZp5x!ZzYM6jik}}S%F4sS%)rPE^d2kk=B@qS0s#82OUnQN delta 159 zcmZoTz|?SnX#=AH8=pFZ0ME;?*qFE*PKNBn zw6xSzx6GW9)S_RZ#i>Px4n}$@soqG!nTable of all security groups diff --git a/UserService/Pages/SecurityGroups.razor.cs b/UserService/Pages/SecurityGroups.razor.cs index 1c65bfd..c1fcb06 100644 --- a/UserService/Pages/SecurityGroups.razor.cs +++ b/UserService/Pages/SecurityGroups.razor.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; -using UserService.DatabaseLayer.DataModels; using UserService.DatabaseLayer.Repository; +using UserService.Infrastructure.DataModels; namespace UserService.Pages { diff --git a/UserService/Pages/Users.razor b/UserService/Pages/Users.razor index 82bbe63..33c4612 100644 --- a/UserService/Pages/Users.razor +++ b/UserService/Pages/Users.razor @@ -1,5 +1,5 @@ @page "/users" -@using UserService.DatabaseLayer.DataModels +@using UserService.Infrastructure.DataModels @inherits UsersBase

List of all users

@@ -12,7 +12,9 @@ } else { - + + + + + + + + + + + + + + + + + + + + + + + + + + Please enter a valid common name! + + + + + + + + @{ + var name = ((SecurityGroup) context ).Parent?.CommonName ?? "-"; + @name + } + + + + + + } \ No newline at end of file diff --git a/UserService/Pages/SecurityGroups.razor.cs b/UserService/Pages/SecurityGroups.razor.cs index c1fcb06..4145a00 100644 --- a/UserService/Pages/SecurityGroups.razor.cs +++ b/UserService/Pages/SecurityGroups.razor.cs @@ -1,47 +1,49 @@ using System.Collections.Generic; using System.Threading.Tasks; +using Blazorise.DataGrid; using Microsoft.AspNetCore.Components; using UserService.DatabaseLayer.Repository; using UserService.Infrastructure.DataModels; namespace UserService.Pages { - public class SecurityGroupsBase : ComponentBase + public class SecurityGroupsBase : MembersBase { [Inject] private ISecurityGroupsRepository SecurityGroupsRepository { get; set; } = null!; [Inject] private IOrganizationUnitsRepository OrganizationUnitsRepository { get; set; } = null!; - protected bool DialogIsOpen { get; set; } - protected SecurityGroup? SecurityGroupToEdit { get; set; } - - protected IReadOnlyList? Groups { get; set; } - protected IReadOnlyList? OrganizationUnits { get; set; } - protected override async Task OnInitializedAsync() { - Groups = await SecurityGroupsRepository.GetAllAsync().ConfigureAwait(false); + Members = await SecurityGroupsRepository.GetAllAsync().ConfigureAwait(false); OrganizationUnits = await OrganizationUnitsRepository.GetAllAsync().ConfigureAwait(false); } - protected void EditSecurityGroup(SecurityGroup securityGroup) + /// + protected override async Task RowInsertingCallback(CancellableRowChange> arg) { - SecurityGroupToEdit = securityGroup; - DialogIsOpen = true; } - protected async Task OkClick() + /// + protected override async Task RowInsertedCallback(SavedRowItem> arg) { - if (!(SecurityGroupToEdit is null)) - { - await SecurityGroupsRepository.UpdateAsync(SecurityGroupToEdit).ConfigureAwait(false); - } - - DialogIsOpen = false; } - protected async Task DeleteSecurityGroup(SecurityGroup securityGroup) + /// + protected override async Task RowDeletingCallback(CancellableRowChange arg) { - await SecurityGroupsRepository.DeleteAsync(securityGroup).ConfigureAwait(false); + + + } + + /// + protected override async Task RowUpdatingCallback(CancellableRowChange> arg) + { + } + + /// + protected override bool OnCustomFilter(SecurityGroup model) + { + return true; } } } \ No newline at end of file diff --git a/UserService/Pages/Users.razor b/UserService/Pages/Users.razor index 33c4612..625b638 100644 --- a/UserService/Pages/Users.razor +++ b/UserService/Pages/Users.razor @@ -4,7 +4,7 @@

List of all users

-@if (Users == null) +@if (Members == null) {

Loading... @@ -14,7 +14,18 @@ else { - +