Implemented a basic permission system base
This commit is contained in:
13
Moonlight/Shared/Components/Alerts/NoPermissionAlert.razor
Normal file
13
Moonlight/Shared/Components/Alerts/NoPermissionAlert.razor
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="mx-auto">
|
||||
<div class="card">
|
||||
<div class="d-flex justify-content-center pt-5">
|
||||
<img height="300" width="300" src="/assets/media/svg/warning.svg" alt="Warning"/>
|
||||
</div>
|
||||
<span class="card-title text-center fs-3">
|
||||
<TL>You have no permission to access this resource</TL>
|
||||
</span>
|
||||
<p class="card-body text-center fs-4 text-gray-800">
|
||||
<TL>You have no permission to access this resource. This attempt has been logged ;)</TL>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -14,7 +14,7 @@
|
||||
<span class="bullet me-5"></span> <TL>The resource was deleted</TL>
|
||||
</li>
|
||||
<li class="d-flex align-items-center py-2">
|
||||
<span class="bullet me-5"></span> <TL>You have to permission to access this resource</TL>
|
||||
<span class="bullet me-5"></span> <TL>You have no permission to access this resource</TL>
|
||||
</li>
|
||||
<li class="d-flex align-items-center py-2">
|
||||
<span class="bullet me-5"></span> <TL>You may have entered invalid data</TL>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
@using Moonlight.App.Services
|
||||
|
||||
<div class="card card-flush w-lg-650px py-5">
|
||||
<div class="card-body py-15 py-lg-20">
|
||||
<h1 class="fw-bolder text-gray-900 mb-5"><TL>Setup complete</TL></h1>
|
||||
<div class="fw-semibold fs-6 text-gray-500 mb-8">
|
||||
<TL>It looks like this moonlight instance is ready to go</TL>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
86
Moonlight/Shared/Components/Partials/PermissionEditor.razor
Normal file
86
Moonlight/Shared/Components/Partials/PermissionEditor.razor
Normal file
@@ -0,0 +1,86 @@
|
||||
@using Moonlight.App.Services.Interop
|
||||
@using Moonlight.App.Services
|
||||
@using Moonlight.App.Perms
|
||||
|
||||
@inject ModalService ModalService
|
||||
@inject SmartTranslateService SmartTranslateService
|
||||
|
||||
<div id="permissionEditor" class="modal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">
|
||||
<TL>Edit permissions</TL>
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@if (Enabled)
|
||||
{
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle table-row-dashed fs-6 gy-5">
|
||||
<tbody class="text-gray-600 fw-semibold">
|
||||
@foreach (var permission in Permissions.GetAllPermissions())
|
||||
{
|
||||
<tr>
|
||||
<td class="text-gray-800">
|
||||
@(permission.Name)
|
||||
</td>
|
||||
<td>
|
||||
@(permission.Description)
|
||||
</td>
|
||||
<td>
|
||||
<div class="form-check form-switch form-check-custom form-check-solid">
|
||||
<input class="form-check-input" type="checkbox" @bind="Storage[permission]"/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<TL>Close</TL>
|
||||
</button>
|
||||
<WButton Text="@(SmartTranslateService.Translate("Save"))"
|
||||
WorkingText="@(SmartTranslateService.Translate("Saving"))"
|
||||
CssClasses="btn-primary"
|
||||
OnClick="Save">
|
||||
</WButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
[Parameter]
|
||||
public byte[] InitialData { get; set; } = Array.Empty<byte>();
|
||||
|
||||
[Parameter]
|
||||
public Func<byte[], Task>? OnSave { get; set; }
|
||||
|
||||
private bool Enabled = false;
|
||||
private PermissionStorage Storage;
|
||||
|
||||
public async Task Launch()
|
||||
{
|
||||
Enabled = true;
|
||||
Storage = new(InitialData);
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
await ModalService.Show("permissionEditor");
|
||||
}
|
||||
|
||||
private async Task Save()
|
||||
{
|
||||
OnSave?.Invoke(Storage.Data);
|
||||
|
||||
await ModalService.Hide("permissionEditor");
|
||||
Enabled = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
@using Moonlight.App.Services.Sessions
|
||||
@using Moonlight.App.Perms
|
||||
@using Moonlight.App.Helpers
|
||||
@using Moonlight.Shared.Components.Alerts
|
||||
|
||||
@inject IdentityService IdentityService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@if (Allowed)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
else
|
||||
{
|
||||
<NoPermissionAlert />
|
||||
}
|
||||
|
||||
@code
|
||||
{
|
||||
[CascadingParameter(Name = "TargetPageType")]
|
||||
public Type TargetPageType { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
private bool Allowed = false;
|
||||
|
||||
protected override Task OnParametersSetAsync()
|
||||
{
|
||||
var attributes = TargetPageType.GetCustomAttributes(true);
|
||||
var permAttrs = attributes
|
||||
.Where(x => x.GetType() == typeof(PermissionRequired))
|
||||
.Select(x => x as PermissionRequired)
|
||||
.ToArray();
|
||||
|
||||
Allowed = true;
|
||||
|
||||
foreach (var permissionRequired in permAttrs)
|
||||
{
|
||||
var permission = Permissions.FromString(permissionRequired!.Name);
|
||||
|
||||
if (permission == null)
|
||||
{
|
||||
Allowed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IdentityService.Permissions[permission])
|
||||
{
|
||||
Allowed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Allowed)
|
||||
{
|
||||
Logger.Warn($"{IdentityService.GetIp()} has tried to access {NavigationManager.Uri} without permission", "security");
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user