list of authorities, changing authority auth data
This commit is contained in:
		| @@ -49,6 +49,20 @@ | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void Logout() | ||||
|     { | ||||
|         Client.AuthToken = null; | ||||
|         AuthData = null; | ||||
|         try | ||||
|         { | ||||
|             UserDataProvider.UpdateCurrentRole(); | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             ErrorHandler.Handle(e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ///Re-auth if token expired or something | ||||
|     public async Task ReAuthenticate() | ||||
|     { | ||||
|   | ||||
| @@ -20,21 +20,27 @@ namespace BlazorWebAssemblyVisaApiClient.Infrastructure.Services.UserDataProvide | ||||
|  | ||||
|         public void UpdateCurrentRole() | ||||
|         { | ||||
|             var role = CurrentRole; | ||||
|  | ||||
|             if (client.AuthToken is null) | ||||
|             { | ||||
|                 CurrentRole = null; | ||||
|                 return; | ||||
|                 if (CurrentRole is not null) | ||||
|                 { | ||||
|                     role = null; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             var token = tokenHandler.ReadJwtToken(client.AuthToken.Token); | ||||
|             var role = token.Claims.FirstOrDefault(claim => claim.Type == ClaimTypes.Role)?.Value; | ||||
|  | ||||
|             switch (role) | ||||
|             else | ||||
|             { | ||||
|                 case Constants.ApplicantRole: break; | ||||
|                 case Constants.ApprovingAuthorityRole: break; | ||||
|                 case Constants.AdminRole: break; | ||||
|                 default: throw new UnknownRoleException(); | ||||
|                 var token = tokenHandler.ReadJwtToken(client.AuthToken.Token); | ||||
|                 role = token.Claims.FirstOrDefault(claim => claim.Type == ClaimTypes.Role)?.Value; | ||||
|  | ||||
|                 switch (role) | ||||
|                 { | ||||
|                     case Constants.ApplicantRole: break; | ||||
|                     case Constants.ApprovingAuthorityRole: break; | ||||
|                     case Constants.AdminRole: break; | ||||
|                     default: throw new UnknownRoleException(); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (CurrentRole != role) | ||||
|   | ||||
| @@ -1,12 +1,41 @@ | ||||
| @inherits LayoutComponentBase | ||||
| @using BlazorWebAssemblyVisaApiClient.Components.Auth | ||||
| @using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.UserDataProvider | ||||
| @inherits LayoutComponentBase | ||||
| <div class="page"> | ||||
|     <div class="sidebar"> | ||||
|         <NavMenu/> | ||||
|     </div> | ||||
|  | ||||
|     <main> | ||||
|         <article class="content px-4 fullscreen"> | ||||
|     <main class="fullscreen"> | ||||
|         <div class="top-row px-4"> | ||||
|             <AuthComponent @ref="authComponent"/> | ||||
|             @if (UserDataProvider.CurrentRole is not null) | ||||
|             { | ||||
|                 <p> | ||||
|                     Logged as @UserDataProvider.CurrentRole (@AuthComponent.AuthData?.Email) | ||||
|                     <button class="btn-secondary" @onclick="authComponent.Logout">Log out</button> | ||||
|                 </p> | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 <NavLink href="/">Log in</NavLink> | ||||
|             } | ||||
|         </div> | ||||
|  | ||||
|         <article class="content px-4"> | ||||
|             @Body | ||||
|         </article> | ||||
|     </main> | ||||
| </div> | ||||
|  | ||||
| @code | ||||
| { | ||||
|     private AuthComponent authComponent = null!; | ||||
|  | ||||
|     [Inject] private IUserDataProvider UserDataProvider { get; set; } = null!; | ||||
|  | ||||
|     protected override void OnInitialized() | ||||
|     { | ||||
|         UserDataProvider.OnRoleChanged += StateHasChanged; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -26,7 +26,7 @@ | ||||
|             </div> | ||||
|         </nav> | ||||
|     } | ||||
|     @if(UserDataProvider.CurrentRole is Constants.ApplicantRole) | ||||
|     @if (UserDataProvider.CurrentRole is Constants.ApplicantRole) | ||||
|     { | ||||
|     <nav class="flex-column"> | ||||
|         <div class="nav-item px-3"> | ||||
| @@ -36,6 +36,16 @@ | ||||
|         </div> | ||||
|     </nav> | ||||
|     } | ||||
|     @if (UserDataProvider.CurrentRole is Constants.AdminRole) | ||||
|     { | ||||
|         <nav class="flex-column"> | ||||
|             <div class="nav-item px-3"> | ||||
|                 <NavLink class="nav-link" href="authorities" Match="NavLinkMatch.All"> | ||||
|                     <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Authorities | ||||
|                 </NavLink> | ||||
|             </div> | ||||
|         </nav> | ||||
|     } | ||||
| </div> | ||||
|  | ||||
| @code { | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| @page "/applications/{ApplicationId}" | ||||
| @using System.Net | ||||
| @using BlazorWebAssemblyVisaApiClient.Common.Exceptions | ||||
| @using BlazorWebAssemblyVisaApiClient.Components | ||||
| @using BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers | ||||
| @@ -210,6 +211,11 @@ | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|  | ||||
|             if (e is ApiException<ProblemDetails> { Result.Status: (int)HttpStatusCode.Conflict }) | ||||
|             { | ||||
|                 Nav.NavigateTo("/applications"); | ||||
|             } | ||||
|             ErrorHandler.Handle(e); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -0,0 +1,42 @@ | ||||
| @page "/authorities" | ||||
| @using VisaApiClient | ||||
| @inherits BlazorWebAssemblyVisaApiClient.Components.Base.VisaClientComponentBase | ||||
|  | ||||
| <table class="table table-bordered table-hover"> | ||||
|     <thead> | ||||
|     <tr> | ||||
|         <th>Email</th><th></th> | ||||
|     </tr> | ||||
|     </thead> | ||||
|     <tbody> | ||||
|     @foreach (var authority in authorities) | ||||
|     { | ||||
|         var path = $"authorities/{authority.Id}/{authority.Email}"; | ||||
|         <tr> | ||||
|             <td>@authority.Email</td> | ||||
|             <td> | ||||
|                 <NavLink href="@path"> | ||||
|                     <button class="btn-outline-primary">Change</button> | ||||
|                 </NavLink> | ||||
|             </td> | ||||
|         </tr> | ||||
|     } | ||||
|     </tbody> | ||||
| </table> | ||||
|  | ||||
| @code { | ||||
|     private IEnumerable<UserModel> authorities = []; | ||||
|  | ||||
|     protected override async Task OnInitializedAsync() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             authorities = await Client.GetAuthorityAccountsAsync(); | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             ErrorHandler.Handle(e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,83 @@ | ||||
| @page "/authorities/{authorityId}/{oldEmail}" | ||||
| @inherits BlazorWebAssemblyVisaApiClient.Components.Base.VisaClientComponentBase | ||||
| @using BlazorWebAssemblyVisaApiClient.Common.Exceptions | ||||
| @using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.UserDataProvider | ||||
| @using VisaApiClient | ||||
| @using BlazorWebAssemblyVisaApiClient.Components | ||||
| @using BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers | ||||
| @using FluentValidation | ||||
|  | ||||
| <EditForm Model="model" class="with-centered-content"> | ||||
|     <div > | ||||
|         <label> | ||||
|             New email:<br/> | ||||
|             <InputText class="rounded" @bind-Value="model.Email"/> | ||||
|         </label><br/><p/> | ||||
|  | ||||
|         <label> | ||||
|             New password (leave blank if shouldn't be changed):<br/> | ||||
|             <InputText class="rounded" @bind-Value="model.Password"/> | ||||
|         </label><br/><p/> | ||||
|  | ||||
|         <button class="btn-primary rounded" @onclick="Save">Save</button><br/> | ||||
|         <Status @ref="status"/> | ||||
|     </div> | ||||
| </EditForm> | ||||
|  | ||||
| @code | ||||
| { | ||||
|     private Status status = null!; | ||||
|     private ChangeAuthData model = new(); | ||||
|  | ||||
|     [Parameter] public string AuthorityId { get; set; } = null!; | ||||
|  | ||||
|     [Parameter] public string OldEmail { get; set; } = null!; | ||||
|  | ||||
|     [Inject] private IUserDataProvider UserDataProvider { get; set; } = null!; | ||||
|  | ||||
|     [Inject] private IValidator<ChangeUserAuthDataRequest> ChangeUserAuthDataRequestValidator { get; set; } = null!; | ||||
|  | ||||
|     protected override void OnInitialized() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             if (UserDataProvider.CurrentRole is not Constants.AdminRole) | ||||
|             { | ||||
|                 throw new NotLoggedInException(); | ||||
|             } | ||||
|  | ||||
|             model.Email = OldEmail; | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             ErrorHandler.Handle(e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private async Task Save() | ||||
|     { | ||||
|         var request = new ChangeUserAuthDataRequest | ||||
|         { | ||||
|             UserId = Guid.Parse(AuthorityId), | ||||
|             NewAuthData = model | ||||
|         }; | ||||
|  | ||||
|         var validationResult = await ChangeUserAuthDataRequestValidator.ValidateAsync(request); | ||||
|         if (!validationResult.IsValid) | ||||
|         { | ||||
|             status.SetError(validationResult.ToErrorsString()); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             status.SetMessage("Wait..."); | ||||
|             await Client.ChangeAuthorityAuthDataAsync(request); | ||||
|             status.SetSuccess("Success"); | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             ErrorHandler.Handle(e); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -102,7 +102,7 @@ | ||||
|             </label><br/> | ||||
|             <ValidationMessage For="() => editableVisa.ExpirationDate"></ValidationMessage><br/> | ||||
|  | ||||
|             <input type="button" class="btn-outline-primary" | ||||
|             <input type="button" class="btn-outline-primary rounded" | ||||
|                    disabled="@(requestModel.PastVisas.Count == ConfigurationConstraints.MaxPastVisas)" | ||||
|                    @onclick="AddPastVisa" value="Add"/> | ||||
|             <Status @ref="pastVisaStatus"/> | ||||
| @@ -157,7 +157,7 @@ | ||||
|             </label><br/> | ||||
|             <ValidationMessage For="() => editableVisit.EndDate"></ValidationMessage><br/> | ||||
|  | ||||
|             <input type="button" class="btn-outline-primary" | ||||
|             <input type="button" class="btn-outline-primary rounded" | ||||
|                    disabled="@(requestModel.PastVisits.Count == ConfigurationConstraints.MaxPastVisits)" | ||||
|                    @onclick="AddPastVisit" value="Add"/> | ||||
|             <Status @ref="pastVisitStatus"/> | ||||
| @@ -185,7 +185,7 @@ | ||||
|             </div> | ||||
|         } | ||||
|  | ||||
|         <br/><input type="submit" class="btn-outline-primary" value="Register"/> | ||||
|         <br/><input type="submit" class="btn-outline-primary rounded" value="Register"/> | ||||
|         <ValidationSummary/> | ||||
|         <Status @ref="status"/> | ||||
|     </EditForm> | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
| 
 | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Common; | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Auth; | ||||
| 
 | ||||
| public class AuthDataValidator : AbstractValidator<AuthData> | ||||
| { | ||||
| @@ -0,0 +1,21 @@ | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Auth | ||||
| { | ||||
|     public class ChangeUserAuthDataRequestValidator : AbstractValidator<ChangeUserAuthDataRequest> | ||||
|     { | ||||
|         public ChangeUserAuthDataRequestValidator() | ||||
|         { | ||||
|             RuleFor(r => r.NewAuthData) | ||||
|                 .NotEmpty(); | ||||
|  | ||||
|             RuleFor(r => r.NewAuthData.Email) | ||||
|                 .NotEmpty() | ||||
|                 .EmailAddress() | ||||
|                 .WithMessage("Email should be valid") | ||||
|                 .MaximumLength(ConfigurationConstraints.EmailLength) | ||||
|                 .WithMessage($"Email address length must be less than {ConfigurationConstraints.EmailLength}"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -2,7 +2,7 @@ | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
| 
 | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Common; | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Auth; | ||||
| 
 | ||||
| public class RegisterRequestValidator : AbstractValidator<RegisterRequestModel> | ||||
| { | ||||
		Reference in New Issue
	
	Block a user