Adding permissions. I hate my life ;)

This commit is contained in:
Marcel Baumgartner 2023-07-16 22:44:36 +02:00
parent 178ff36e86
commit 74d4ee729d
18 changed files with 698 additions and 706 deletions

View file

@ -8,6 +8,104 @@ public static class Permissions
Name = "Admin dashboard", Name = "Admin dashboard",
Description = "See basic information about growth and status of the moonlight instance" Description = "See basic information about growth and status of the moonlight instance"
}; };
public static Permission SystemDashboard = new()
{
Index = 1,
Name = "System information",
Description = "See information about the moonlight instance like the uptime and memory usage"
};
public static Permission SystemSentry = new()
{
Index = 2,
Name = "Settings for Sentry",
Description = "See information about the sentry status"
};
public static Permission SystemMalware = new()
{
Index = 3,
Name = "Server malware scanner",
Description = "Scan running servers for malware"
};
public static Permission SystemSecurity = new()
{
Index = 4,
Name = "System security settings",
Description = "Ban ip addresses and view the security logs"
};
public static Permission SystemResources = new()
{
Index = 5,
Name = "Resources",
Description = "Read and write moonlight resources like configuration files"
};
public static Permission DiscordBot = new()
{
Index = 6,
Name = "Discord bot actions",
Description = "Setup and remote control the discord bot if enabled"
};
public static Permission NewsMessages = new()
{
Index = 7,
Name = "News messages",
Description = "Edit, view and delete messages for the user dashboard"
};
public static Permission SystemConfiguration = new()
{
Index = 8,
Name = "System configuration",
Description = "Modify the moonlight configuration though the visual editor"
};
public static Permission SystemMail = new()
{
Index = 9,
Name = "System mail settings",
Description = "Modify the mail templates and send test mails"
};
public static Permission ServersOverview = new()
{
Index = 10,
Name = "Servers overview",
Description = "View all servers and their owners"
};
public static Permission ServerAdminEdit = new()
{
Index = 11,
Name = "Edit servers",
Description = "View all servers and their owners"
};
public static Permission ServerManager = new()
{
Index = 12,
Name = "Server manager",
Description = "View all servers are currently running and stop/kill all running servers"
};
public static Permission ServerCleanup = new()
{
Index = 13,
Name = "Server cleanup",
Description = "View the stats about the cleanup system"
};
public static Permission Nodes = new()
{
Index = 14,
Name = "Nodes",
Description = "View stats about the nodes"
};
public static Permission? FromString(string name) public static Permission? FromString(string name)
{ {

View file

@ -77,6 +77,7 @@
<_ContentIncludedByDefault Remove="Shared\Views\Admin\Servers\Cleanup\Exceptions\Edit.razor" /> <_ContentIncludedByDefault Remove="Shared\Views\Admin\Servers\Cleanup\Exceptions\Edit.razor" />
<_ContentIncludedByDefault Remove="Shared\Components\News\NewsEditor.razor" /> <_ContentIncludedByDefault Remove="Shared\Components\News\NewsEditor.razor" />
<_ContentIncludedByDefault Remove="Shared\News\Edit.razor" /> <_ContentIncludedByDefault Remove="Shared\News\Edit.razor" />
<_ContentIncludedByDefault Remove="Shared\Views\Admin\AaPanels\Index.razor" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -1,2 +0,0 @@
@page "/admin/aapanels"

View file

@ -17,118 +17,116 @@
@attribute [PermissionRequired(nameof(Permissions.AdminDashboard))] @attribute [PermissionRequired(nameof(Permissions.AdminDashboard))]
<OnlyAdmin> <LazyLoader Load="Load">
<LazyLoader Load="Load"> <div class="row mb-5">
<div class="row mb-5"> <div class="col-12 col-lg-6 col-xl">
<div class="col-12 col-lg-6 col-xl"> <a class="mt-4 card" href="/admin/servers">
<a class="mt-4 card" href="/admin/servers"> <div class="card-body">
<div class="card-body"> <div class="row align-items-center gx-0">
<div class="row align-items-center gx-0"> <div class="col">
<div class="col"> <h6 class="text-uppercase text-muted mb-2">
<h6 class="text-uppercase text-muted mb-2"> <TL>Servers</TL>
<TL>Servers</TL> </h6>
</h6> <span class="h2 mb-0">
<span class="h2 mb-0"> @(ServerCount)
@(ServerCount) </span>
</span>
</div>
<div class="col-auto">
<span class="h2 text-muted mb-0">
<i class="text-primary bx bx-server bx-lg"></i>
</span>
</div>
</div> </div>
</div> <div class="col-auto">
</a> <span class="h2 text-muted mb-0">
</div> <i class="text-primary bx bx-server bx-lg"></i>
<div class="col-12 col-lg-6 col-xl"> </span>
<a class="mt-4 card" href="/admin/webspaces">
<div class="card-body">
<div class="row align-items-center gx-0">
<div class="col">
<h6 class="text-uppercase text-muted mb-2">
<TL>Webspaces</TL>
</h6>
<span class="h2 mb-0">
@(WebSpaceCount)
</span>
</div>
<div class="col-auto">
<span class="h2 text-muted mb-0">
<i class="text-primary bx bx-globe bx-lg"></i>
</span>
</div>
</div>
</div>
</a>
</div>
<div class="col-12 col-lg-6 col-xl">
<a class="mt-4 card" href="/admin/domains">
<div class="card-body">
<div class="row align-items-center gx-0">
<div class="col">
<h6 class="text-uppercase text-muted mb-2">
<TL>Domains</TL>
</h6>
<span class="h2 mb-0">
@(DomainCount)
</span>
</div>
<div class="col-auto">
<span class="h2 text-muted mb-">
<i class="text-primary bx bx-purchase-tag bx-lg"></i>
</span>
</div>
</div>
</div>
</a>
</div>
<div class="col-12 col-lg-6 col-xl">
<a class="mt-4 card" href="/admin/users">
<div class="card-body">
<div class="row align-items-center gx-0">
<div class="col">
<h6 class="text-uppercase text-muted mb-2">
<TL>Users</TL>
</h6>
<span class="h2 mb-0">
@(UserCount)
</span>
</div>
<div class="col-auto">
<span class="h2 text-muted mb-">
<i class="text-primary bx bx-user bx-lg"></i>
</span>
</div>
</div>
</div>
</a>
</div>
</div>
<LazyLoader Load="LoadHealthCheckData">
@if (HealthCheckData == null)
{
<div class="card">
<div class="card-header">
<div class="card-title">
<TL>Moonlight health</TL>
</div>
</div>
<div class="card-body">
<div class="alert alert-warning">
<TL>Unable to fetch health check data</TL>
</div> </div>
</div> </div>
</div> </div>
} </a>
else </div>
{ <div class="col-12 col-lg-6 col-xl">
<HealthCheckView HealthCheck="@HealthCheckData"/> <a class="mt-4 card" href="/admin/webspaces">
} <div class="card-body">
</LazyLoader> <div class="row align-items-center gx-0">
<div class="col">
<h6 class="text-uppercase text-muted mb-2">
<TL>Webspaces</TL>
</h6>
<span class="h2 mb-0">
@(WebSpaceCount)
</span>
</div>
<div class="col-auto">
<span class="h2 text-muted mb-0">
<i class="text-primary bx bx-globe bx-lg"></i>
</span>
</div>
</div>
</div>
</a>
</div>
<div class="col-12 col-lg-6 col-xl">
<a class="mt-4 card" href="/admin/domains">
<div class="card-body">
<div class="row align-items-center gx-0">
<div class="col">
<h6 class="text-uppercase text-muted mb-2">
<TL>Domains</TL>
</h6>
<span class="h2 mb-0">
@(DomainCount)
</span>
</div>
<div class="col-auto">
<span class="h2 text-muted mb-">
<i class="text-primary bx bx-purchase-tag bx-lg"></i>
</span>
</div>
</div>
</div>
</a>
</div>
<div class="col-12 col-lg-6 col-xl">
<a class="mt-4 card" href="/admin/users">
<div class="card-body">
<div class="row align-items-center gx-0">
<div class="col">
<h6 class="text-uppercase text-muted mb-2">
<TL>Users</TL>
</h6>
<span class="h2 mb-0">
@(UserCount)
</span>
</div>
<div class="col-auto">
<span class="h2 text-muted mb-">
<i class="text-primary bx bx-user bx-lg"></i>
</span>
</div>
</div>
</div>
</a>
</div>
</div>
<LazyLoader Load="LoadHealthCheckData">
@if (HealthCheckData == null)
{
<div class="card">
<div class="card-header">
<div class="card-title">
<TL>Moonlight health</TL>
</div>
</div>
<div class="card-body">
<div class="alert alert-warning">
<TL>Unable to fetch health check data</TL>
</div>
</div>
</div>
}
else
{
<HealthCheckView HealthCheck="@HealthCheckData"/>
}
</LazyLoader> </LazyLoader>
</OnlyAdmin> </LazyLoader>
@code @code
{ {

View file

@ -8,62 +8,64 @@
@inject ServerRepository ServerRepository @inject ServerRepository ServerRepository
@inject SmartTranslateService SmartTranslateService @inject SmartTranslateService SmartTranslateService
<OnlyAdmin> @attribute [PermissionRequired(nameof(Permissions.ServersOverview))]
<div class="row">
<LazyLoader Load="Load"> <div class="row">
<div class="card"> <LazyLoader Load="Load">
<div class="card-header border-0 pt-5"> <div class="card">
<h3 class="card-title align-items-start flex-column"> <div class="card-header border-0 pt-5">
<span class="card-label fw-bold fs-3 mb-1"><TL>Servers</TL></span> <h3 class="card-title align-items-start flex-column">
</h3> <span class="card-label fw-bold fs-3 mb-1">
<div class="card-toolbar"> <TL>Servers</TL>
<a href="/admin/servers/new" class="btn btn-sm btn-light-success"> </span>
<i class="bx bx-layer-plus"></i> </h3>
<TL>New server</TL> <div class="card-toolbar">
</a> <a href="/admin/servers/new" class="btn btn-sm btn-light-success">
</div> <i class="bx bx-layer-plus"></i>
</div> <TL>New server</TL>
<div class="card-body pt-0"> </a>
@if (Servers.Any())
{
<div class="table-responsive">
<Table TableItem="Server" Items="Servers" PageSize="25" TableClass="table table-row-bordered table-row-gray-100 align-middle gs-0 gy-3" TableHeadClass="fw-bold text-muted">
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Id"))" Field="@(x => x.Id)" Sortable="true" Filterable="true"/>
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Name"))" Field="@(x => x.Name)" Sortable="true" Filterable="true">
<Template>
<a href="/server/@(context.Uuid)">@(context.Name)</a>
</Template>
</Column>
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Cores"))" Field="@(x => x.Cpu)" Sortable="true" Filterable="true"/>
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Memory"))" Field="@(x => x.Memory)" Sortable="true" Filterable="true"/>
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Disk"))" Field="@(x => x.Disk)" Sortable="true" Filterable="true"/>
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Owner"))" Field="@(x => x.Owner)" Sortable="true" Filterable="true">
<Template>
<a href="/admin/users/view/@(context.Owner.Id)/">@context.Owner.Email</a>
</Template>
</Column>
<Column TableItem="Server" Title="" Field="@(x => x.Id)" Sortable="false" Filterable="false">
<Template>
<a href="/admin/servers/view/@(context.Id)">
@(SmartTranslateService.Translate("Manage"))
</a>
</Template>
</Column>
<Pager ShowPageNumber="true" ShowTotalCount="true"/>
</Table>
</div>
}
else
{
<div class="alert alert-info">
<TL>No servers found</TL>
</div>
}
</div> </div>
</div> </div>
</LazyLoader> <div class="card-body pt-0">
</div> @if (Servers.Any())
</OnlyAdmin> {
<div class="table-responsive">
<Table TableItem="Server" Items="Servers" PageSize="25" TableClass="table table-row-bordered table-row-gray-100 align-middle gs-0 gy-3" TableHeadClass="fw-bold text-muted">
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Id"))" Field="@(x => x.Id)" Sortable="true" Filterable="true"/>
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Name"))" Field="@(x => x.Name)" Sortable="true" Filterable="true">
<Template>
<a href="/server/@(context.Uuid)">@(context.Name)</a>
</Template>
</Column>
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Cores"))" Field="@(x => x.Cpu)" Sortable="true" Filterable="true"/>
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Memory"))" Field="@(x => x.Memory)" Sortable="true" Filterable="true"/>
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Disk"))" Field="@(x => x.Disk)" Sortable="true" Filterable="true"/>
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Owner"))" Field="@(x => x.Owner)" Sortable="true" Filterable="true">
<Template>
<a href="/admin/users/view/@(context.Owner.Id)/">@context.Owner.Email</a>
</Template>
</Column>
<Column TableItem="Server" Title="" Field="@(x => x.Id)" Sortable="false" Filterable="false">
<Template>
<a href="/admin/servers/view/@(context.Id)">
@(SmartTranslateService.Translate("Manage"))
</a>
</Template>
</Column>
<Pager ShowPageNumber="true" ShowTotalCount="true"/>
</Table>
</div>
}
else
{
<div class="alert alert-info">
<TL>No servers found</TL>
</div>
}
</div>
</div>
</LazyLoader>
</div>
@code @code
{ {

View file

@ -1,106 +0,0 @@
@page "/admin/system/auditlog"
@using Moonlight.Shared.Components.Navigations
@using Moonlight.App.Repositories.LogEntries
@using Moonlight.App.Services
@using Moonlight.App.Database.Entities.LogsEntries
@using BlazorTable
@using Moonlight.App.Helpers
@using Moonlight.App.Models.Misc
@using Moonlight.Shared.Components.AuditLogEntrys
@inject AuditLogEntryRepository AuditLogEntryRepository
<OnlyAdmin>
<AdminSystemNavigation Index="2"/>
<div class="card">
<div class="card-header card-header-stretch">
<div class="card-title d-flex align-items-center">
<span class="me-3 lh-0">
<i class="bx bx-md bx-calendar"></i>
</span>
<h3 class="fw-bold m-0 text-gray-800">@(Formatter.FormatDateOnly(DateTime))</h3>
</div>
<div class="card-toolbar m-0">
<ul class="nav nav-tabs nav-line-tabs nav-stretch fs-6 border-0 fw-bold">
<li class="nav-item">
<button @onclick="Left" class="nav-link justify-content-center text-active-gray-800">
<i class="bx bx-md bx-left-arrow"></i>
</button>
</li>
<li class="nav-item">
<button @onclick="Right" class="nav-link justify-content-center text-active-gray-800">
<i class="bx bx-md bx-right-arrow"></i>
</button>
</li>
</ul>
</div>
</div>
<div class="card-body">
<LazyLoader @ref="LazyLoader" Load="Load">
@if (AuditLogEntries.Any())
{
<div class="timeline">
@foreach (var entry in AuditLogEntries)
{
switch (entry.Type)
{
case AuditLogType.Login:
<AuditLogEntryLogin Entry="entry"/>
break;
case AuditLogType.Register:
<AuditLogEntryRegister Entry="entry"/>
break;
case AuditLogType.ChangePassword:
<AuditLogEntryChangePassword Entry="entry"/>
break;
case AuditLogType.ChangePowerState:
<AuditLogEntryChangePowerState Entry="entry"/>
break;
}
}
</div>
}
else
{
<div class="alert alert-primary">
<TL>No records found for this day</TL>
</div>
}
</LazyLoader>
</div>
</div>
</OnlyAdmin>
@code
{
private AuditLogEntry[] AuditLogEntries;
private LazyLoader LazyLoader;
private DateTime DateTime = DateTime.Today;
private Task Load(LazyLoader arg)
{
AuditLogEntries = AuditLogEntryRepository
.Get()
.Where(x => x.CreatedAt.Date == DateTime.Date)
.OrderByDescending(x => x.Id)
.ToArray();
return Task.CompletedTask;
}
private async Task Left()
{
DateTime = DateTime.AddDays(1);
await LazyLoader.Reload();
}
private async Task Right()
{
DateTime = DateTime.AddDays(-1);
await LazyLoader.Reload();
}
}

View file

@ -9,26 +9,26 @@
@inject ToastService ToastService @inject ToastService ToastService
@inject SmartTranslateService SmartTranslateService @inject SmartTranslateService SmartTranslateService
<OnlyAdmin> @attribute [PermissionRequired(nameof(Permissions.SystemConfiguration))]
<AdminSystemNavigation Index="8"/>
<LazyLoader Load="Load"> <AdminSystemNavigation Index="8"/>
<div class="card">
<SmartForm Model="Config" OnValidSubmit="OnSubmit"> <LazyLoader Load="Load">
<div class="card-body"> <div class="card">
<SmartFormClass Model="Config"/> <SmartForm Model="Config" OnValidSubmit="OnSubmit">
<div class="card-body">
<SmartFormClass Model="Config"/>
</div>
<div class="card-footer">
<div class="text-end">
<button type="submit" class="btn btn-success">
<TL>Save</TL>
</button>
</div> </div>
<div class="card-footer"> </div>
<div class="text-end"> </SmartForm>
<button type="submit" class="btn btn-success"> </div>
<TL>Save</TL> </LazyLoader>
</button>
</div>
</div>
</SmartForm>
</div>
</LazyLoader>
</OnlyAdmin>
@code @code
{ {

View file

@ -4,34 +4,34 @@
@inject DiscordBotService DiscordBotService @inject DiscordBotService DiscordBotService
<OnlyAdmin> @attribute [PermissionRequired(nameof(Permissions.DiscordBot))]
<AdminSystemNavigation Index="6"/>
<div class="mt-3 card card-body"> <AdminSystemNavigation Index="6"/>
<WButton Text="Register commands"
WorkingText="Working"
CssClasses="btn-primary"
OnClick="RegisterCommands">
</WButton>
<WButton Text="Void commands" <div class="mt-3 card card-body">
WorkingText="Working" <WButton Text="Register commands"
CssClasses="mt-3 btn-danger" WorkingText="Working"
OnClick="VoidCommands"> CssClasses="btn-primary"
</WButton> OnClick="RegisterCommands">
</div> </WButton>
</OnlyAdmin>
<WButton Text="Void commands"
WorkingText="Working"
CssClasses="mt-3 btn-danger"
OnClick="VoidCommands">
</WButton>
</div>
@code @code
{ {
//ToDo: Ole muss ins Bett gehen //ToDo: Ole muss ins Bett gehen
//ToDo: Bot Info Card with Name, Bot Avatar, (RichPresence) Game Status, Activity Status //ToDo: Bot Info Card with Name, Bot Avatar, (RichPresence) Game Status, Activity Status
private async Task RegisterCommands() private async Task RegisterCommands()
{ {
await DiscordBotService.CreateCommands(); await DiscordBotService.CreateCommands();
} }
private Task VoidCommands() private Task VoidCommands()
{ {
DiscordBotService.RemoveCommandsModule.VoidCommands(); DiscordBotService.RemoveCommandsModule.VoidCommands();

View file

@ -7,92 +7,92 @@
@inject HostSystemHelper HostSystemHelper @inject HostSystemHelper HostSystemHelper
@inject MoonlightService MoonlightService @inject MoonlightService MoonlightService
<OnlyAdmin> @attribute [PermissionRequired(nameof(Permissions.SystemDashboard))]
<AdminSystemNavigation Index="0"/>
<LazyLoader Load="Load"> <AdminSystemNavigation Index="0"/>
<div class="row">
<div class="col-xxl-6 my-3"> <LazyLoader Load="Load">
<div class="card"> <div class="row">
<div class="card-header"> <div class="col-xxl-6 my-3">
<span class="card-title"> <div class="card">
<TL>Version</TL> <div class="card-header">
</span> <span class="card-title">
</div> <TL>Version</TL>
<div class="card-body"> </span>
<span class="fs-5">
<TL>You are running moonlight version</TL>
<span class="text-primary">@(MoonlightService.AppVersion)</span>
</span>
</div>
</div>
</div> </div>
<div class="col-xxl-6 my-3"> <div class="card-body">
<div class="card"> <span class="fs-5">
<div class="card-header"> <TL>You are running moonlight version</TL>
<span class="card-title"> <span class="text-primary">@(MoonlightService.AppVersion)</span>
<TL>Operating system</TL> </span>
</span>
</div>
<div class="card-body">
<span class="fs-5">
<TL>Moonlight is running on</TL>
<span class="text-primary">@(HostSystemHelper.GetOsName())</span>
</span>
</div>
</div>
</div>
<div class="col-xxl-6 my-3">
<div class="card">
<div class="card-header">
<span class="card-title">
<TL>Memory usage</TL>
</span>
</div>
<div class="card-body">
<span class="fs-5">
<TL>Moonlight is using</TL>
<span class="text-primary">@(HostSystemHelper.GetMemoryUsage()) MB</span>
<TL>of memory</TL>
</span>
</div>
</div>
</div>
<div class="col-xxl-6 my-3">
<div class="card">
<div class="card-header">
<span class="card-title">
<TL>Cpu usage</TL>
</span>
</div>
<div class="card-body">
<span class="fs-5">
<TL>Moonlight is using</TL>
<span class="text-primary">@(HostSystemHelper.GetCpuUsage()) %</span>
</span>
</div>
</div>
</div>
<div class="col-xxl-6 my-3">
<div class="card">
<div class="card-header">
<span class="card-title">
<TL>Uptime</TL>
</span>
</div>
<div class="card-body">
<span class="fs-5">
<TL>Moonlight is since</TL>
<span class="text-primary">
@(Formatter.FormatUptime(DateTime.UtcNow - MoonlightService.StartTimestamp))
</span>
</span>
</div>
</div>
</div> </div>
</div> </div>
</LazyLoader> </div>
</OnlyAdmin> <div class="col-xxl-6 my-3">
<div class="card">
<div class="card-header">
<span class="card-title">
<TL>Operating system</TL>
</span>
</div>
<div class="card-body">
<span class="fs-5">
<TL>Moonlight is running on</TL>
<span class="text-primary">@(HostSystemHelper.GetOsName())</span>
</span>
</div>
</div>
</div>
<div class="col-xxl-6 my-3">
<div class="card">
<div class="card-header">
<span class="card-title">
<TL>Memory usage</TL>
</span>
</div>
<div class="card-body">
<span class="fs-5">
<TL>Moonlight is using</TL>
<span class="text-primary">@(HostSystemHelper.GetMemoryUsage()) MB</span>
<TL>of memory</TL>
</span>
</div>
</div>
</div>
<div class="col-xxl-6 my-3">
<div class="card">
<div class="card-header">
<span class="card-title">
<TL>Cpu usage</TL>
</span>
</div>
<div class="card-body">
<span class="fs-5">
<TL>Moonlight is using</TL>
<span class="text-primary">@(HostSystemHelper.GetCpuUsage()) %</span>
</span>
</div>
</div>
</div>
<div class="col-xxl-6 my-3">
<div class="card">
<div class="card-header">
<span class="card-title">
<TL>Uptime</TL>
</span>
</div>
<div class="card-body">
<span class="fs-5">
<TL>Moonlight is since</TL>
<span class="text-primary">
@(Formatter.FormatUptime(DateTime.UtcNow - MoonlightService.StartTimestamp))
</span>
</span>
</div>
</div>
</div>
</div>
</LazyLoader>
@code @code
{ {
@ -100,4 +100,4 @@
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
} }

View file

@ -16,79 +16,79 @@
@inject AlertService AlertService @inject AlertService AlertService
@inject MailService MailService @inject MailService MailService
<OnlyAdmin> @attribute [PermissionRequired(nameof(Permissions.SystemMail))]
<AdminSystemNavigation Index="9"/>
<div class="card mb-3"> <AdminSystemNavigation Index="9"/>
<div class="card-header">
<span class="card-title"> <div class="card mb-3">
<TL>Actions</TL> <div class="card-header">
</span> <span class="card-title">
</div> <TL>Actions</TL>
<div class="card-body"> </span>
<WButton Text="@(SmartTranslateService.Translate("Test mail configuration"))"
WorkingText="@(SmartTranslateService.Translate("Sending test mail"))"
CssClasses="btn-primary"
OnClick="SendTestMail">
</WButton>
</div>
</div> </div>
<div class="card-body">
<WButton Text="@(SmartTranslateService.Translate("Test mail configuration"))"
WorkingText="@(SmartTranslateService.Translate("Sending test mail"))"
CssClasses="btn-primary"
OnClick="SendTestMail">
</WButton>
</div>
</div>
<LazyLoader @ref="LazyLoader" Load="Load"> <LazyLoader @ref="LazyLoader" Load="Load">
@if (CurrentMailTemplate == null) @if (CurrentMailTemplate == null)
{ {
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<span class="card-title"> <span class="card-title">
<TL>Mail templates</TL> <TL>Mail templates</TL>
</span> </span>
<div class="card-toolbar"> <div class="card-toolbar">
<WButton Text="@(SmartTranslateService.Translate("New mail template"))" <WButton Text="@(SmartTranslateService.Translate("New mail template"))"
CssClasses="btn-sm btn-success" CssClasses="btn-sm btn-success"
OnClick="CreateNewMailTemplate"> OnClick="CreateNewMailTemplate">
</WButton> </WButton>
</div>
</div>
<div class="card-body">
<div class="table-responsive">
<Table TableItem="MailTemplate" Items="MailTemplateFiles" PageSize="25" TableClass="table table-row-bordered table-row-gray-100 align-middle gs-0 gy-3" TableHeadClass="fw-bold text-muted">
<Column TableItem="MailTemplate" Title="@(SmartTranslateService.Translate("Name"))" Field="@(x => x.Name)" Sortable="true" Filterable="true">
<Template>
@{
var name = context.Name.Replace(Path.GetExtension(context.Name), "");
}
<span>@(name)</span>
</Template>
</Column>
<Column TableItem="MailTemplate" Title="" Field="@(x => x.Name)" Filterable="false" Sortable="false">
<Template>
<div class="text-end">
<WButton Text="@(SmartTranslateService.Translate("Edit"))"
OnClick="() => EditTemplate(context)">
</WButton>
<DeleteButton OnClick="() => DeleteTemplate(context)"
Confirm="true">
</DeleteButton>
</div>
</Template>
</Column>
<Pager ShowPageNumber="true" ShowTotalCount="true"/>
</Table>
</div>
</div> </div>
</div> </div>
} <div class="card-body">
else <div class="table-responsive">
{ <Table TableItem="MailTemplate" Items="MailTemplateFiles" PageSize="25" TableClass="table table-row-bordered table-row-gray-100 align-middle gs-0 gy-3" TableHeadClass="fw-bold text-muted">
<FileEditor Language="html" <Column TableItem="MailTemplate" Title="@(SmartTranslateService.Translate("Name"))" Field="@(x => x.Name)" Sortable="true" Filterable="true">
HideControls="false" <Template>
InitialData="@(CurrentMailTemplateContent)" @{
OnCancel="OnCancelTemplateEdit" var name = context.Name.Replace(Path.GetExtension(context.Name), "");
OnSubmit="OnSubmitTemplateEdit"/> }
}
</LazyLoader> <span>@(name)</span>
</OnlyAdmin> </Template>
</Column>
<Column TableItem="MailTemplate" Title="" Field="@(x => x.Name)" Filterable="false" Sortable="false">
<Template>
<div class="text-end">
<WButton Text="@(SmartTranslateService.Translate("Edit"))"
OnClick="() => EditTemplate(context)">
</WButton>
<DeleteButton OnClick="() => DeleteTemplate(context)"
Confirm="true">
</DeleteButton>
</div>
</Template>
</Column>
<Pager ShowPageNumber="true" ShowTotalCount="true"/>
</Table>
</div>
</div>
</div>
}
else
{
<FileEditor Language="html"
HideControls="false"
InitialData="@(CurrentMailTemplateContent)"
OnCancel="OnCancelTemplateEdit"
OnSubmit="OnSubmitTemplateEdit"/>
}
</LazyLoader>
@code @code
{ {

View file

@ -14,89 +14,89 @@
@implements IDisposable @implements IDisposable
<OnlyAdmin> @attribute [PermissionRequired(nameof(Permissions.SystemMalware))]
<AdminSystemNavigation Index="2"/>
<div class="row"> <AdminSystemNavigation Index="2"/>
<div class="col-12 col-lg-6">
<div class="card">
<div class="card-body">
@if (MalwareScanService.IsRunning)
{
<span class="fs-3 spinner-border align-middle me-3"></span>
}
<span class="fs-3">@(MalwareScanService.Status)</span> <div class="row">
</div> <div class="col-12 col-lg-6">
<div class="card-footer"> <div class="card">
@if (MalwareScanService.IsRunning) <div class="card-body">
{ @if (MalwareScanService.IsRunning)
<button class="btn btn-success disabled"> {
<TL>Scan in progress</TL> <span class="fs-3 spinner-border align-middle me-3"></span>
</button> }
}
else <span class="fs-3">@(MalwareScanService.Status)</span>
{ </div>
<WButton Text="@(SmartTranslateService.Translate("Start scan"))" <div class="card-footer">
CssClasses="btn-success" @if (MalwareScanService.IsRunning)
OnClick="MalwareScanService.Start"> {
</WButton> <button class="btn btn-success disabled">
} <TL>Scan in progress</TL>
</div> </button>
}
else
{
<WButton Text="@(SmartTranslateService.Translate("Start scan"))"
CssClasses="btn-success"
OnClick="MalwareScanService.Start">
</WButton>
}
</div> </div>
</div> </div>
<div class="col-12 col-lg-6"> </div>
<div class="card"> <div class="col-12 col-lg-6">
<div class="card-header"> <div class="card">
<span class="card-title"> <div class="card-header">
<TL>Results</TL> <span class="card-title">
</span> <TL>Results</TL>
</div> </span>
<div class="card-body"> </div>
<LazyLoader @ref="LazyLoaderResults" Load="LoadResults"> <div class="card-body">
<div class="table-responsive"> <LazyLoader @ref="LazyLoaderResults" Load="LoadResults">
<Table TableItem="Server" Items="ScanResults.Keys" PageSize="25" TableClass="table table-row-bordered table-row-gray-100 align-middle gs-0 gy-3" TableHeadClass="fw-bold text-muted"> <div class="table-responsive">
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Server"))" Field="@(x => x.Id)" Sortable="false" Filterable="false"> <Table TableItem="Server" Items="ScanResults.Keys" PageSize="25" TableClass="table table-row-bordered table-row-gray-100 align-middle gs-0 gy-3" TableHeadClass="fw-bold text-muted">
<Template> <Column TableItem="Server" Title="@(SmartTranslateService.Translate("Server"))" Field="@(x => x.Id)" Sortable="false" Filterable="false">
<a href="/server/@(context.Uuid)">@(context.Name)</a> <Template>
</Template> <a href="/server/@(context.Uuid)">@(context.Name)</a>
</Column> </Template>
<Column TableItem="Server" Title="@(SmartTranslateService.Translate("Results"))" Field="@(x => x.Id)" Sortable="false" Filterable="false"> </Column>
<Template> <Column TableItem="Server" Title="@(SmartTranslateService.Translate("Results"))" Field="@(x => x.Id)" Sortable="false" Filterable="false">
<div class="row"> <Template>
@foreach (var result in ScanResults[context]) <div class="row">
{ @foreach (var result in ScanResults[context])
<div class="col-12 col-md-6 p-3"> {
<div class="accordion" id="scanResult@(result.GetHashCode())"> <div class="col-12 col-md-6 p-3">
<div class="accordion-item"> <div class="accordion" id="scanResult@(result.GetHashCode())">
<h2 class="accordion-header" id="scanResult-header@(result.GetHashCode())"> <div class="accordion-item">
<button class="accordion-button fs-4 fw-semibold collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#scanResult-body@(result.GetHashCode())" aria-expanded="false" aria-controls="scanResult-body@(result.GetHashCode())"> <h2 class="accordion-header" id="scanResult-header@(result.GetHashCode())">
<span>@(result.Title)</span> <button class="accordion-button fs-4 fw-semibold collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#scanResult-body@(result.GetHashCode())" aria-expanded="false" aria-controls="scanResult-body@(result.GetHashCode())">
</button> <span>@(result.Title)</span>
</h2> </button>
<div id="scanResult-body@(result.GetHashCode())" class="accordion-collapse collapse" aria-labelledby="scanResult-header@(result.GetHashCode())" data-bs-parent="#scanResult"> </h2>
<div class="accordion-body"> <div id="scanResult-body@(result.GetHashCode())" class="accordion-collapse collapse" aria-labelledby="scanResult-header@(result.GetHashCode())" data-bs-parent="#scanResult">
<p> <div class="accordion-body">
@(result.Description) <p>
</p> @(result.Description)
</div> </p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
} </div>
</div> }
</Template> </div>
</Column> </Template>
<Pager ShowPageNumber="true" ShowTotalCount="true"/> </Column>
</Table> <Pager ShowPageNumber="true" ShowTotalCount="true"/>
</div> </Table>
</LazyLoader> </div>
</div> </LazyLoader>
</div> </div>
</div> </div>
</div> </div>
</OnlyAdmin> </div>
@code @code
{ {

View file

@ -10,52 +10,52 @@
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject NewsEntryRepository NewsEntryRepository @inject NewsEntryRepository NewsEntryRepository
<OnlyAdmin> @attribute [PermissionRequired(nameof(Permissions.NewsMessages))]
<LazyLoader Load="Load">
@if (Entry == null) <LazyLoader Load="Load">
{ @if (Entry == null)
<div class="alert bg-info d-flex flex-column flex-sm-row w-100 p-5"> {
<div class="d-flex flex-column pe-0 pe-sm-10"> <div class="alert bg-info d-flex flex-column flex-sm-row w-100 p-5">
<h4 class="fw-semibold"> <div class="d-flex flex-column pe-0 pe-sm-10">
<TL>No entry found</TL> <h4 class="fw-semibold">
</h4> <TL>No entry found</TL>
<span> </h4>
<TL>We were not able to find the news entry with this id</TL> <span>
</span> <TL>We were not able to find the news entry with this id</TL>
</span>
</div>
</div>
}
else
{
<div class="card mb-6">
<div class="card-header">
<h3 class="card-title w-75">
<input type="text" @bind="Entry.Title" placeholder="@SmartTranslateService.Translate("Title...")" class="form-control form-control-flush"/>
</h3>
<div class="card-toolbar">
<span class="text-gray-600 fw-semibold">@(Formatter.FormatDateOnly(Entry.Date))</span>
</div> </div>
</div> </div>
} <div class="card-body">
else <FileEditor @ref="FileEditor" Language="markdown" HideControls="true" InitialData="@(Entry.Markdown)"/>
{
<div class="card mb-6">
<div class="card-header">
<h3 class="card-title w-75">
<input type="text" @bind="Entry.Title" placeholder="@SmartTranslateService.Translate("Title...")" class="form-control form-control-flush"/>
</h3>
<div class="card-toolbar">
<span class="text-gray-600 fw-semibold">@(Formatter.FormatDateOnly(Entry.Date))</span>
</div>
</div>
<div class="card-body">
<FileEditor @ref="FileEditor" Language="markdown" HideControls="true" InitialData="@(Entry.Markdown)"/>
</div>
<div class="card-footer">
<WButton CssClasses="btn btn-primary text-end"
OnClick="Save"
Text="@SmartTranslateService.Translate("Save")"
WorkingText="@SmartTranslateService.Translate("Saving...")">
</WButton>
</div>
</div> </div>
} <div class="card-footer">
</LazyLoader> <WButton CssClasses="btn btn-primary text-end"
</OnlyAdmin> OnClick="Save"
Text="@SmartTranslateService.Translate("Save")"
WorkingText="@SmartTranslateService.Translate("Saving...")">
</WButton>
</div>
</div>
}
</LazyLoader>
@code @code
{ {
[Parameter] [Parameter]
public int Id { get; set; } public int Id { get; set; }
private NewsEntry? Entry; private NewsEntry? Entry;
private FileEditor FileEditor; private FileEditor FileEditor;
@ -63,16 +63,16 @@
private async Task Save() private async Task Save()
{ {
Entry!.Markdown = await FileEditor.GetData(); Entry!.Markdown = await FileEditor.GetData();
NewsEntryRepository.Update(Entry); NewsEntryRepository.Update(Entry);
NavigationManager.NavigateTo("/admin/system/news"); NavigationManager.NavigateTo("/admin/system/news");
} }
private Task Load(LazyLoader arg) private Task Load(LazyLoader arg)
{ {
Entry = NewsEntryRepository.Get().FirstOrDefault(x => x.Id == Id); Entry = NewsEntryRepository.Get().FirstOrDefault(x => x.Id == Id);
return Task.CompletedTask; return Task.CompletedTask;
} }
} }

View file

@ -12,50 +12,50 @@
@inject SmartTranslateService SmartTranslateService @inject SmartTranslateService SmartTranslateService
@inject AlertService AlertService @inject AlertService AlertService
<OnlyAdmin> @attribute [PermissionRequired(nameof(Permissions.NewsMessages))]
<AdminSystemNavigation Index="7" />
<AdminSystemNavigation Index="7"/>
<div class="card card-body mb-6">
<div class="text-end"> <div class="card card-body mb-6">
<a href="/admin/system/news/new" class="btn btn-success"> <div class="text-end">
<TL>New entry</TL> <a href="/admin/system/news/new" class="btn btn-success">
</a> <TL>New entry</TL>
</div> </a>
</div> </div>
</div>
<LazyLoader @ref="LazyLoader" Load="Load"> <LazyLoader @ref="LazyLoader" Load="Load">
@foreach (var entry in Entries) @foreach (var entry in Entries)
{ {
<div class="card mb-6"> <div class="card mb-6">
<div class="card-header"> <div class="card-header">
<h3 class="card-title">@entry.Title</h3> <h3 class="card-title">@entry.Title</h3>
<div class="card-toolbar"> <div class="card-toolbar">
<a href="/admin/system/news/edit/@(entry.Id)"> <a href="/admin/system/news/edit/@(entry.Id)">
<button class="btn btn-sm btn-light me-4"> <button class="btn btn-sm btn-light me-4">
<TL>Edit</TL> <TL>Edit</TL>
</button> </button>
</a> </a>
<WButton CssClasses="btn btn-sm btn-light me-4" <WButton CssClasses="btn btn-sm btn-light me-4"
Text="@SmartTranslateService.Translate("Delete")" Text="@SmartTranslateService.Translate("Delete")"
WorkingText="@SmartTranslateService.Translate("Deleting...")" WorkingText="@SmartTranslateService.Translate("Deleting...")"
OnClick="() => Delete(entry)"> OnClick="() => Delete(entry)">
</WButton> </WButton>
<span class="text-gray-600 fw-semibold">@(Formatter.FormatDateOnly(entry.Date))</span> <span class="text-gray-600 fw-semibold">@(Formatter.FormatDateOnly(entry.Date))</span>
</div>
</div>
<div class="card-body">
@{
var html = (MarkupString)Markdown.ToHtml(entry.Markdown);
}
@(html)
</div> </div>
</div> </div>
} <div class="card-body">
</LazyLoader> @{
</OnlyAdmin> var html = (MarkupString)Markdown.ToHtml(entry.Markdown);
}
@(html)
</div>
</div>
}
</LazyLoader>
@code @code
{ {

View file

@ -9,28 +9,28 @@
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject NewsEntryRepository NewsEntryRepository @inject NewsEntryRepository NewsEntryRepository
<OnlyAdmin> @attribute [PermissionRequired(nameof(Permissions.NewsMessages))]
<div class="card mb-6">
<div class="card-header"> <div class="card mb-6">
<h3 class="card-title w-75"> <div class="card-header">
<input type="text" @bind="Model.Title" placeholder="@SmartTranslateService.Translate("Title...")" class="form-control form-control-flush"/> <h3 class="card-title w-75">
</h3> <input type="text" @bind="Model.Title" placeholder="@SmartTranslateService.Translate("Title...")" class="form-control form-control-flush"/>
<div class="card-toolbar"> </h3>
<span class="text-gray-600 fw-semibold">@(Formatter.FormatDateOnly(Model.Date))</span> <div class="card-toolbar">
</div> <span class="text-gray-600 fw-semibold">@(Formatter.FormatDateOnly(Model.Date))</span>
</div>
<div class="card-body">
<FileEditor @ref="FileEditor" Language="markdown" HideControls="true" InitialData=""/>
</div>
<div class="card-footer">
<WButton CssClasses="btn btn-primary text-end"
OnClick="Save"
Text="@SmartTranslateService.Translate("Save")"
WorkingText="@SmartTranslateService.Translate("Saving...")">
</WButton>
</div> </div>
</div> </div>
</OnlyAdmin> <div class="card-body">
<FileEditor @ref="FileEditor" Language="markdown" HideControls="true" InitialData=""/>
</div>
<div class="card-footer">
<WButton CssClasses="btn btn-primary text-end"
OnClick="Save"
Text="@SmartTranslateService.Translate("Save")"
WorkingText="@SmartTranslateService.Translate("Saving...")">
</WButton>
</div>
</div>
@code @code
{ {
@ -44,9 +44,9 @@
private async Task Save() private async Task Save()
{ {
Model.Markdown = await FileEditor.GetData(); Model.Markdown = await FileEditor.GetData();
NewsEntryRepository.Add(Model); NewsEntryRepository.Add(Model);
NavigationManager.NavigateTo("/admin/system/news"); NavigationManager.NavigateTo("/admin/system/news");
} }
} }

View file

@ -11,26 +11,26 @@
@inject ConfigService ConfigService @inject ConfigService ConfigService
@inject AlertService AlertService @inject AlertService AlertService
<OnlyAdmin> @attribute [PermissionRequired(nameof(Permissions.SystemResources))]
<AdminSystemNavigation Index="5"/>
<div class="card card-body mb-6"> <AdminSystemNavigation Index="5"/>
<div class="text-end">
<WButton CssClasses="btn btn-primary" <div class="card card-body mb-6">
Text="@(SmartTranslateService.Translate("Reload config"))" <div class="text-end">
WorkingText="@(SmartTranslateService.Translate("Reloading"))" <WButton CssClasses="btn btn-primary"
OnClick="ReloadConfig"> Text="@(SmartTranslateService.Translate("Reload config"))"
</WButton> WorkingText="@(SmartTranslateService.Translate("Reloading"))"
</div> OnClick="ReloadConfig">
</WButton>
</div> </div>
</div>
<div class="card card-body"> <div class="card card-body">
<FileManager Access="@(new HostFileAccess(PathBuilder.Dir("storage")))"> <FileManager Access="@(new HostFileAccess(PathBuilder.Dir("storage")))">
</FileManager> </FileManager>
</div> </div>
</OnlyAdmin>
@code @code
{ {
private async Task ReloadConfig() private async Task ReloadConfig()
{ {

View file

@ -13,48 +13,48 @@
@inject EventSystem Event @inject EventSystem Event
@inject ToastService ToastService @inject ToastService ToastService
<OnlyAdmin> @attribute [PermissionRequired(nameof(Permissions.SystemSecurity))]
<AdminSystemNavigation Index="3"/>
<div class="card mb-5"> <AdminSystemNavigation Index="3"/>
<div class="card-header">
<div class="card-title"> <div class="card mb-5">
<TL>Ip Bans</TL> <div class="card-header">
</div> <div class="card-title">
<div class="card-toolbar"> <TL>Ip Bans</TL>
<table class="w-100">
<tr>
<td class="w-100">
<input @bind="Ip" type="text" class="form-control" placeholder="@(SmartTranslateService.Translate("Enter a ip"))"/>
</td>
<td>
<WButton OnClick="AddIpBan"
CssClasses="btn btn-primary ms-2"
Text="@(SmartTranslateService.Translate("Add"))"
WorkingText="@(SmartTranslateService.Translate("Adding"))">
</WButton>
</td>
</tr>
</table>
</div>
</div> </div>
<div class="card-body"> <div class="card-toolbar">
<LazyLoader @ref="LazyLoader" Load="Load"> <table class="w-100">
<Table TableItem="IpBan" Items="IpBans" PageSize="25" TableClass="table table-row-bordered table-row-gray-100 align-middle gs-0 gy-3" TableHeadClass="fw-bold text-muted"> <tr>
<Column TableItem="IpBan" Title="@(SmartTranslateService.Translate("Ip"))" Field="@(x => x.Ip)" Filterable="true" Sortable="false"/> <td class="w-100">
<Column TableItem="IpBan" Title="" Field="@(x => x.Id)" Filterable="false" Sortable="false"> <input @bind="Ip" type="text" class="form-control" placeholder="@(SmartTranslateService.Translate("Enter a ip"))"/>
<Template> </td>
<div class="text-end"> <td>
<DeleteButton Confirm="true" OnClick="() => DeleteIpBan(context)"></DeleteButton> <WButton OnClick="AddIpBan"
</div> CssClasses="btn btn-primary ms-2"
</Template> Text="@(SmartTranslateService.Translate("Add"))"
</Column> WorkingText="@(SmartTranslateService.Translate("Adding"))">
<Pager ShowPageNumber="true" ShowTotalCount="true"/> </WButton>
</Table> </td>
</LazyLoader> </tr>
</table>
</div> </div>
</div> </div>
</OnlyAdmin> <div class="card-body">
<LazyLoader @ref="LazyLoader" Load="Load">
<Table TableItem="IpBan" Items="IpBans" PageSize="25" TableClass="table table-row-bordered table-row-gray-100 align-middle gs-0 gy-3" TableHeadClass="fw-bold text-muted">
<Column TableItem="IpBan" Title="@(SmartTranslateService.Translate("Ip"))" Field="@(x => x.Ip)" Filterable="true" Sortable="false"/>
<Column TableItem="IpBan" Title="" Field="@(x => x.Id)" Filterable="false" Sortable="false">
<Template>
<div class="text-end">
<DeleteButton Confirm="true" OnClick="() => DeleteIpBan(context)"></DeleteButton>
</div>
</Template>
</Column>
<Pager ShowPageNumber="true" ShowTotalCount="true"/>
</Table>
</LazyLoader>
</div>
</div>
@code @code
{ {
@ -83,7 +83,7 @@
Ip = ""; Ip = "";
await InvokeAsync(StateHasChanged); await InvokeAsync(StateHasChanged);
await Event.Emit("ipBan.update"); await Event.Emit("ipBan.update");
await ToastService.Success( await ToastService.Success(

View file

@ -3,33 +3,33 @@
@using Moonlight.Shared.Components.Navigations @using Moonlight.Shared.Components.Navigations
@using global::Sentry @using global::Sentry
<OnlyAdmin> @attribute [PermissionRequired(nameof(Permissions.SystemSentry))]
<AdminSystemNavigation Index="1"/>
<div class="row"> <AdminSystemNavigation Index="1"/>
<div class="col-xxl-6 my-3">
<div class="card"> <div class="row">
<div class="card-header"> <div class="col-xxl-6 my-3">
<span class="card-title"> <div class="card">
<TL>Status</TL> <div class="card-header">
</span> <span class="card-title">
</div> <TL>Status</TL>
<div class="card-body"> </span>
<span class="fs-5"> </div>
@if (SentrySdk.IsEnabled) <div class="card-body">
{ <span class="fs-5">
<TL>Sentry is enabled</TL> @if (SentrySdk.IsEnabled)
} {
else <TL>Sentry is enabled</TL>
{ }
<TL>Sentry is disabled</TL> else
} {
</span> <TL>Sentry is disabled</TL>
</div> }
</span>
</div> </div>
</div> </div>
</div> </div>
</OnlyAdmin> </div>
@code @code
{ {

View file

@ -7,6 +7,7 @@
@using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop @using Microsoft.JSInterop
@using Moonlight @using Moonlight
@using Moonlight.App.Perms
@using Moonlight.Shared.Components @using Moonlight.Shared.Components
@using Moonlight.Shared.Components.StateLogic @using Moonlight.Shared.Components.StateLogic
@using Moonlight.Shared.Components.Alerts @using Moonlight.Shared.Components.Alerts