-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add UI for adding a user * Start the test hosts immediately from constructor
- Loading branch information
Showing
30 changed files
with
856 additions
and
19 deletions.
There are no files selected for viewing
1 change: 0 additions & 1 deletion
1
TeachingRecordSystem/src/TeachingRecordSystem.Cli/Commands.CreateAdmin.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 0 additions & 7 deletions
7
TeachingRecordSystem/src/TeachingRecordSystem.Core/DataStore/Postgres/Models/UserType.cs
This file was deleted.
Oops, something went wrong.
1 change: 1 addition & 0 deletions
1
TeachingRecordSystem/src/TeachingRecordSystem.Core/DataStore/Postgres/TrsDbContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
TeachingRecordSystem/src/TeachingRecordSystem.Core/Events/User.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace TeachingRecordSystem.Core.Events; | ||
|
||
public record User | ||
{ | ||
public required Guid UserId { get; init; } | ||
public required UserType UserType { get; init; } | ||
public required string Name { get; init; } | ||
public string? Email { get; init; } | ||
public string? AzureAdUserId { get; init; } | ||
public required string[] Roles { get; init; } | ||
|
||
public static User FromModel(DataStore.Postgres.Models.User user) => new() | ||
{ | ||
UserId = user.UserId, | ||
UserType = user.UserType, | ||
Name = user.Name, | ||
Email = user.Email, | ||
AzureAdUserId = user.AzureAdUserId, | ||
Roles = user.Roles, | ||
}; | ||
} |
7 changes: 7 additions & 0 deletions
7
TeachingRecordSystem/src/TeachingRecordSystem.Core/Events/UserAddedEvent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace TeachingRecordSystem.Core.Events; | ||
|
||
public record UserAddedEvent : EventBase | ||
{ | ||
public required User User { get; init; } | ||
public required Guid AddedByUserId { get; init; } | ||
} |
17 changes: 16 additions & 1 deletion
17
TeachingRecordSystem/src/TeachingRecordSystem.Core/UserRoles.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,21 @@ | ||
namespace TeachingRecordSystem.Core; | ||
using System.ComponentModel.DataAnnotations; | ||
using System.Reflection; | ||
|
||
namespace TeachingRecordSystem.Core; | ||
|
||
public static class UserRoles | ||
{ | ||
[Display(Name = "Administrator")] | ||
public const string Administrator = "Administrator"; | ||
|
||
public static IReadOnlyCollection<string> All { get; } = new[] | ||
{ | ||
Administrator | ||
}; | ||
|
||
public static string GetDisplayNameForRole(string role) | ||
{ | ||
var member = typeof(UserRoles).GetField(role) ?? throw new ArgumentException("Invalid role.", nameof(role)); | ||
return member.GetCustomAttribute<DisplayAttribute>()?.Name ?? member.Name; | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
TeachingRecordSystem/src/TeachingRecordSystem.Core/UserType.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace TeachingRecordSystem.Core; | ||
|
||
public enum UserType | ||
{ | ||
Person = 1, | ||
Application = 2 | ||
} |
10 changes: 10 additions & 0 deletions
10
TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/ClaimsPrincipalExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System.Security.Claims; | ||
using TeachingRecordSystem.SupportUi.Infrastructure.Security; | ||
|
||
namespace TeachingRecordSystem.SupportUi; | ||
|
||
public static class ClaimsPrincipalExtensions | ||
{ | ||
public static Guid GetUserId(this ClaimsPrincipal principal) => | ||
Guid.Parse(principal.FindFirstValue(CustomClaims.UserId) ?? throw new InvalidOperationException("UserId claim was not found.")); | ||
} |
29 changes: 29 additions & 0 deletions
29
TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Users/AddUser/Confirm.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
@page "/users/add/confirm" | ||
@using TeachingRecordSystem.Core; | ||
@model TeachingRecordSystem.SupportUi.Pages.Users.AddUser.ConfirmModel | ||
@{ | ||
ViewBag.Title = "Add user"; | ||
} | ||
|
||
<div class="govuk-grid-row"> | ||
<div class="govuk-grid-column-two-thirds"> | ||
<form trs-action="l => l.AddUser(Model.UserId!)"> | ||
<h1 class="govuk-heading-l">@ViewBag.Title</h1> | ||
|
||
<govuk-input asp-for="Email" type="email" disabled /> | ||
|
||
<govuk-input asp-for="Name" /> | ||
|
||
<govuk-checkboxes asp-for="Roles"> | ||
<govuk-checkboxes-fieldset> | ||
@foreach (var role in UserRoles.All) | ||
{ | ||
<govuk-checkboxes-item value="@role">@UserRoles.GetDisplayNameForRole(role)</govuk-checkboxes-item> | ||
} | ||
</govuk-checkboxes-fieldset> | ||
</govuk-checkboxes> | ||
|
||
<govuk-button type="submit">Add user</govuk-button> | ||
</form> | ||
</div> | ||
</div> |
114 changes: 114 additions & 0 deletions
114
...hingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Users/AddUser/Confirm.cshtml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Filters; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
using TeachingRecordSystem.Core; | ||
using TeachingRecordSystem.Core.DataStore.Postgres; | ||
using TeachingRecordSystem.Core.Events; | ||
using TeachingRecordSystem.SupportUi.Services.AzureActiveDirectory; | ||
|
||
namespace TeachingRecordSystem.SupportUi.Pages.Users.AddUser; | ||
|
||
public class ConfirmModel : PageModel | ||
{ | ||
private readonly TrsDbContext _dbContext; | ||
private readonly IUserService _userService; | ||
private readonly IClock _clock; | ||
private readonly TrsLinkGenerator _linkGenerator; | ||
private Services.AzureActiveDirectory.User? _user; | ||
|
||
public ConfirmModel( | ||
TrsDbContext dbContext, | ||
IUserService userService, | ||
IClock clock, | ||
TrsLinkGenerator linkGenerator) | ||
{ | ||
_dbContext = dbContext; | ||
_userService = userService; | ||
_clock = clock; | ||
_linkGenerator = linkGenerator; | ||
} | ||
|
||
[BindProperty(SupportsGet = true)] | ||
public string? UserId { get; set; } | ||
|
||
public string? Email { get; set; } | ||
|
||
[BindProperty] | ||
[Display(Name = "Name")] | ||
[Required(ErrorMessage = "Enter a name")] | ||
[MaxLength(Core.DataStore.Postgres.Models.User.NameMaxLength, ErrorMessage = "Name must be 200 characters or less")] | ||
public string? Name { get; set; } | ||
|
||
[BindProperty] | ||
[Display(Name = "Roles")] | ||
public string[]? Roles { get; set; } | ||
|
||
public IActionResult OnGet() | ||
{ | ||
Name = _user!.Name; | ||
|
||
return Page(); | ||
} | ||
|
||
public async Task<IActionResult> OnPost() | ||
{ | ||
var roles = Roles ?? Array.Empty<string>(); | ||
|
||
// Ensure submitted roles are valid | ||
if (roles.Any(r => !UserRoles.All.Contains(r))) | ||
{ | ||
return BadRequest(); | ||
} | ||
|
||
if (roles.Length == 0) | ||
{ | ||
ModelState.AddModelError(nameof(Roles), "Select at least one role"); | ||
} | ||
|
||
if (!ModelState.IsValid) | ||
{ | ||
return this.PageWithErrors(); | ||
} | ||
|
||
var newUser = new Core.DataStore.Postgres.Models.User() | ||
{ | ||
Active = true, | ||
AzureAdUserId = _user!.UserId, | ||
Email = _user.Email, | ||
Name = Name!, | ||
Roles = roles, | ||
UserId = Guid.NewGuid(), | ||
UserType = UserType.Person | ||
}; | ||
|
||
_dbContext.Users.Add(newUser); | ||
|
||
_dbContext.AddEvent(new UserAddedEvent() | ||
{ | ||
User = Core.Events.User.FromModel(newUser), | ||
AddedByUserId = User.GetUserId(), | ||
CreatedUtc = _clock.UtcNow | ||
}); | ||
|
||
await _dbContext.SaveChangesAsync(); | ||
|
||
TempData.SetFlashSuccess("User added"); | ||
return Redirect(_linkGenerator.Users()); | ||
} | ||
|
||
public override async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) | ||
{ | ||
_user = await _userService.GetUserById(UserId!); | ||
|
||
if (_user is null) | ||
{ | ||
context.Result = NotFound(); | ||
return; | ||
} | ||
|
||
Email = _user.Email; | ||
|
||
await next(); | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Users/AddUser/Index.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
@page "/users/add" | ||
@model TeachingRecordSystem.SupportUi.Pages.Users.AddUser.IndexModel | ||
@{ | ||
ViewBag.Title = "Add user"; | ||
} | ||
|
||
<div class="govuk-grid-row"> | ||
<div class="govuk-grid-column-two-thirds"> | ||
<form trs-action="l => l.AddUser()"> | ||
<h1 class="govuk-heading-l">@ViewBag.Title</h1> | ||
|
||
<govuk-input asp-for="Email" type="email" autocomplete="off" /> | ||
|
||
<govuk-button type="submit">Find user</govuk-button> | ||
</form> | ||
</div> | ||
</div> |
54 changes: 54 additions & 0 deletions
54
TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Users/AddUser/Index.cshtml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
using TeachingRecordSystem.Core; | ||
using TeachingRecordSystem.SupportUi.Services.AzureActiveDirectory; | ||
|
||
namespace TeachingRecordSystem.SupportUi.Pages.Users.AddUser; | ||
|
||
[Authorize(Roles = UserRoles.Administrator)] | ||
public class IndexModel : PageModel | ||
{ | ||
private readonly IUserService _userService; | ||
private readonly TrsLinkGenerator _trsLinkGenerator; | ||
|
||
public IndexModel(IUserService userService, TrsLinkGenerator trsLinkGenerator) | ||
{ | ||
_userService = userService; | ||
_trsLinkGenerator = trsLinkGenerator; | ||
} | ||
|
||
[Display(Name = "Email address")] | ||
[Required(ErrorMessage = "Enter an email address")] | ||
[BindProperty] | ||
public string? Email { get; set; } | ||
|
||
public void OnGet() | ||
{ | ||
} | ||
|
||
public async Task<IActionResult> OnPost() | ||
{ | ||
if (!ModelState.IsValid) | ||
{ | ||
return this.PageWithErrors(); | ||
} | ||
|
||
var email = Email!; | ||
if (!email.Contains('@')) | ||
{ | ||
email += "@education.gov.uk"; | ||
} | ||
|
||
var user = await _userService.GetUserByEmail(email); | ||
|
||
if (user is null) | ||
{ | ||
ModelState.AddModelError(nameof(Email), "User does not exist"); | ||
return this.PageWithErrors(); | ||
} | ||
|
||
return Redirect(_trsLinkGenerator.AddUser(user.UserId)); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Users/Index.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
@page "/users" | ||
@model TeachingRecordSystem.SupportUi.Pages.Users.IndexModel | ||
@{ | ||
ViewBag.Title = "Users"; | ||
} | ||
|
||
<a href="@LinkGenerator.AddUser()" class="govuk-link">Add user</a> |
10 changes: 10 additions & 0 deletions
10
TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Users/Index.cshtml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
|
||
namespace TeachingRecordSystem.SupportUi.Pages.Users; | ||
|
||
public class IndexModel : PageModel | ||
{ | ||
public void OnGet() | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
...rdSystem/src/TeachingRecordSystem.SupportUi/Services/AzureActiveDirectory/IUserService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace TeachingRecordSystem.SupportUi.Services.AzureActiveDirectory; | ||
|
||
public interface IUserService | ||
{ | ||
Task<User?> GetUserByEmail(string email); | ||
Task<User?> GetUserById(string userId); | ||
} |
18 changes: 18 additions & 0 deletions
18
...achingRecordSystem.SupportUi/Services/AzureActiveDirectory/ServiceCollectionExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using TeachingRecordSystem.Core; | ||
|
||
namespace TeachingRecordSystem.SupportUi.Services.AzureActiveDirectory; | ||
|
||
public static class ServiceCollectionExtensions | ||
{ | ||
public static IServiceCollection AddAzureActiveDirectory( | ||
this IServiceCollection services, | ||
IHostEnvironment environment) | ||
{ | ||
if (!environment.IsUnitTests()) | ||
{ | ||
services.AddTransient<IUserService, UserService>(); | ||
} | ||
|
||
return services; | ||
} | ||
} |
Oops, something went wrong.