Added api keys and api ui
This commit is contained in:
@@ -251,11 +251,9 @@ public class CoreFeature : MoonlightFeature
|
|||||||
|
|
||||||
// Api
|
// Api
|
||||||
if (config.Development.EnableApiReference)
|
if (config.Development.EnableApiReference)
|
||||||
{
|
|
||||||
app.MapSwagger("/api/core/reference/openapi/{documentName}");
|
app.MapSwagger("/api/core/reference/openapi/{documentName}");
|
||||||
|
|
||||||
await pluginService.RegisterImplementation<IApiDefinition>(new InternalApiDefinition());
|
await pluginService.RegisterImplementation<IApiDefinition>(new InternalApiDefinition());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task OnUiInitialized(UiInitContext context)
|
public override Task OnUiInitialized(UiInitContext context)
|
||||||
@@ -269,6 +267,7 @@ public class CoreFeature : MoonlightFeature
|
|||||||
context.AddSidebarItem("Dashboard", "bxs-dashboard", "/admin", needsExactMatch: true, isAdmin: true,
|
context.AddSidebarItem("Dashboard", "bxs-dashboard", "/admin", needsExactMatch: true, isAdmin: true,
|
||||||
index: int.MinValue);
|
index: int.MinValue);
|
||||||
context.AddSidebarItem("Users", "bxs-group", "/admin/users", needsExactMatch: false, isAdmin: true);
|
context.AddSidebarItem("Users", "bxs-group", "/admin/users", needsExactMatch: false, isAdmin: true);
|
||||||
|
context.AddSidebarItem("API", "bx-code-curly", "/admin/api", needsExactMatch: false, isAdmin: true);
|
||||||
context.AddSidebarItem("System", "bxs-component", "/admin/sys", needsExactMatch: false, isAdmin: true);
|
context.AddSidebarItem("System", "bxs-component", "/admin/sys", needsExactMatch: false, isAdmin: true);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ public class DataContext : DbContext
|
|||||||
|
|
||||||
// Core
|
// Core
|
||||||
public DbSet<User> Users { get; set; }
|
public DbSet<User> Users { get; set; }
|
||||||
|
public DbSet<ApiKey> ApiKeys { get; set; }
|
||||||
|
|
||||||
// Servers
|
// Servers
|
||||||
public DbSet<Server> Servers { get; set; }
|
public DbSet<Server> Servers { get; set; }
|
||||||
|
|||||||
11
Moonlight/Core/Database/Entities/ApiKey.cs
Normal file
11
Moonlight/Core/Database/Entities/ApiKey.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace Moonlight.Core.Database.Entities;
|
||||||
|
|
||||||
|
public class ApiKey
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Key { get; set; } = "";
|
||||||
|
public string Description { get; set; } = "";
|
||||||
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||||
|
public DateTime ExpiresAt { get; set; } = DateTime.UtcNow;
|
||||||
|
public string PermissionJson { get; set; } = "[]";
|
||||||
|
}
|
||||||
657
Moonlight/Core/Database/Migrations/20240605120928_AddedApiKeys.Designer.cs
generated
Normal file
657
Moonlight/Core/Database/Migrations/20240605120928_AddedApiKeys.Designer.cs
generated
Normal file
@@ -0,0 +1,657 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Moonlight.Core.Database;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Database.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DataContext))]
|
||||||
|
[Migration("20240605120928_AddedApiKeys")]
|
||||||
|
partial class AddedApiKeys
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "8.0.6")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
|
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Core.Database.Entities.ApiKey", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ExpiresAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("PermissionJson")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ApiKeys");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Flags")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Password")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int>("Permissions")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<DateTime>("TokenValidTimestamp")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<bool>("Totp")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("TotpSecret")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Username")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("Cpu")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<bool>("DisablePublicNetwork")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<int>("Disk")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("DockerImageIndex")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("ImageId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("MainAllocationId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("Memory")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int?>("NetworkId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("NodeId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("OverrideStartupCommand")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int>("OwnerId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<bool>("UseVirtualDisk")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ImageId");
|
||||||
|
|
||||||
|
b.HasIndex("MainAllocationId");
|
||||||
|
|
||||||
|
b.HasIndex("NetworkId");
|
||||||
|
|
||||||
|
b.HasIndex("NodeId");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerId");
|
||||||
|
|
||||||
|
b.ToTable("Servers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerAllocation", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("IpAddress")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Note")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int>("Port")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerNodeId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerNodeId");
|
||||||
|
|
||||||
|
b.ToTable("ServerAllocations");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerBackup", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<bool>("Completed")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<long>("Size")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<bool>("Successful")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("ServerBackup");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerDockerImage", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<bool>("AutoPull")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("DisplayName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerImageId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ServerImageId");
|
||||||
|
|
||||||
|
b.ToTable("ServerDockerImages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImage", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("AllocationsNeeded")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<bool>("AllowDockerImageChange")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("Author")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int>("DefaultDockerImage")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("DonateUrl")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("InstallDockerImage")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("InstallScript")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("InstallShell")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("OnlineDetection")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("ParseConfiguration")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("StartupCommand")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("StopCommand")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("UpdateUrl")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ServerImages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImageVariable", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<bool>("AllowEdit")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<bool>("AllowView")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("DefaultValue")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("DisplayName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Filter")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerImageId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("Type")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ServerImageId");
|
||||||
|
|
||||||
|
b.ToTable("ServerImageVariables");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNetwork", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int>("NodeId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NodeId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("ServerNetworks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNode", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Fqdn")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int>("FtpPort")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("HttpPort")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<bool>("Ssl")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("Token")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ServerNodes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerSchedule", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("ExecutionSeconds")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastRun")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("ServerSchedules");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerScheduleItem", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Action")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("DataJson")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int>("Priority")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerScheduleId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ServerScheduleId");
|
||||||
|
|
||||||
|
b.ToTable("ServerScheduleItems");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerVariable", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("ServerVariables");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", "Image")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ImageId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.ServerAllocation", "MainAllocation")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("MainAllocationId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.ServerNetwork", "Network")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("NetworkId");
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", "Node")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("NodeId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.Core.Database.Entities.User", "Owner")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OwnerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Image");
|
||||||
|
|
||||||
|
b.Navigation("MainAllocation");
|
||||||
|
|
||||||
|
b.Navigation("Network");
|
||||||
|
|
||||||
|
b.Navigation("Node");
|
||||||
|
|
||||||
|
b.Navigation("Owner");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerAllocation", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.Server", null)
|
||||||
|
.WithMany("Allocations")
|
||||||
|
.HasForeignKey("ServerId");
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", null)
|
||||||
|
.WithMany("Allocations")
|
||||||
|
.HasForeignKey("ServerNodeId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerBackup", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.Server", null)
|
||||||
|
.WithMany("Backups")
|
||||||
|
.HasForeignKey("ServerId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerDockerImage", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", null)
|
||||||
|
.WithMany("DockerImages")
|
||||||
|
.HasForeignKey("ServerImageId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImageVariable", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", null)
|
||||||
|
.WithMany("Variables")
|
||||||
|
.HasForeignKey("ServerImageId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNetwork", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", "Node")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("NodeId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.Core.Database.Entities.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Node");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerSchedule", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.Server", null)
|
||||||
|
.WithMany("Schedules")
|
||||||
|
.HasForeignKey("ServerId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerScheduleItem", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.ServerSchedule", null)
|
||||||
|
.WithMany("Items")
|
||||||
|
.HasForeignKey("ServerScheduleId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerVariable", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.Features.Servers.Entities.Server", null)
|
||||||
|
.WithMany("Variables")
|
||||||
|
.HasForeignKey("ServerId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Allocations");
|
||||||
|
|
||||||
|
b.Navigation("Backups");
|
||||||
|
|
||||||
|
b.Navigation("Schedules");
|
||||||
|
|
||||||
|
b.Navigation("Variables");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImage", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("DockerImages");
|
||||||
|
|
||||||
|
b.Navigation("Variables");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNode", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Allocations");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerSchedule", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Items");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Database.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddedApiKeys : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "ApiKeys",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
Key = table.Column<string>(type: "longtext", nullable: false)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
Description = table.Column<string>(type: "longtext", nullable: false)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||||
|
ExpiresAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||||
|
PermissionJson = table.Column<string>(type: "longtext", nullable: false)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_ApiKeys", x => x.Id);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "ApiKeys");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using Moonlight.Core.Database;
|
using Moonlight.Core.Database;
|
||||||
|
|
||||||
@@ -16,15 +17,50 @@ namespace Moonlight.Core.Database.Migrations
|
|||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "7.0.2")
|
.HasAnnotation("ProductVersion", "8.0.6")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
|
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.Core.Database.Entities.ApiKey", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ExpiresAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("PermissionJson")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ApiKeys");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b =>
|
modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
b.Property<DateTime>("CreatedAt")
|
||||||
.HasColumnType("datetime(6)");
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
@@ -68,6 +104,8 @@ namespace Moonlight.Core.Database.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<int>("Cpu")
|
b.Property<int>("Cpu")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
@@ -129,6 +167,8 @@ namespace Moonlight.Core.Database.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<string>("IpAddress")
|
b.Property<string>("IpAddress")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("longtext");
|
.HasColumnType("longtext");
|
||||||
@@ -161,6 +201,8 @@ namespace Moonlight.Core.Database.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<bool>("Completed")
|
b.Property<bool>("Completed")
|
||||||
.HasColumnType("tinyint(1)");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
@@ -189,6 +231,8 @@ namespace Moonlight.Core.Database.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<bool>("AutoPull")
|
b.Property<bool>("AutoPull")
|
||||||
.HasColumnType("tinyint(1)");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
@@ -216,6 +260,8 @@ namespace Moonlight.Core.Database.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<int>("AllocationsNeeded")
|
b.Property<int>("AllocationsNeeded")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
@@ -278,6 +324,8 @@ namespace Moonlight.Core.Database.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<bool>("AllowEdit")
|
b.Property<bool>("AllowEdit")
|
||||||
.HasColumnType("tinyint(1)");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
@@ -322,6 +370,8 @@ namespace Moonlight.Core.Database.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("longtext");
|
.HasColumnType("longtext");
|
||||||
@@ -347,6 +397,8 @@ namespace Moonlight.Core.Database.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<string>("Fqdn")
|
b.Property<string>("Fqdn")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("longtext");
|
.HasColumnType("longtext");
|
||||||
@@ -379,6 +431,8 @@ namespace Moonlight.Core.Database.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<int>("ExecutionSeconds")
|
b.Property<int>("ExecutionSeconds")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
@@ -405,6 +459,8 @@ namespace Moonlight.Core.Database.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<string>("Action")
|
b.Property<string>("Action")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("longtext");
|
.HasColumnType("longtext");
|
||||||
@@ -432,6 +488,8 @@ namespace Moonlight.Core.Database.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<string>("Key")
|
b.Property<string>("Key")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("longtext");
|
.HasColumnType("longtext");
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using MoonCore.Services;
|
using MoonCore.Services;
|
||||||
using Moonlight.Core.Attributes;
|
using Moonlight.Core.Attributes;
|
||||||
using Moonlight.Core.Configuration;
|
using Moonlight.Core.Configuration;
|
||||||
@@ -20,7 +21,7 @@ public class ApiReferenceController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<ActionResult> Get([FromQuery] string document)
|
public async Task<ActionResult> Get([FromQuery][RegularExpression("^[a-z0-9_\\-]+$")] string document)
|
||||||
{
|
{
|
||||||
if (!ConfigService.Get().Development.EnableApiReference)
|
if (!ConfigService.Get().Development.EnableApiReference)
|
||||||
return BadRequest("Api reference is disabled");
|
return BadRequest("Api reference is disabled");
|
||||||
@@ -34,6 +35,7 @@ public class ApiReferenceController : Controller
|
|||||||
"<title>Moonlight Api Reference</title>\n" +
|
"<title>Moonlight Api Reference</title>\n" +
|
||||||
"<meta charset=\"utf-8\" />\n" +
|
"<meta charset=\"utf-8\" />\n" +
|
||||||
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n" +
|
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n" +
|
||||||
|
"<link rel=\"stylesheet\" type=\"text/css\" href=\"/api/core/asset/Core/css/scalar.css\" />\n"+
|
||||||
"</head>\n" +
|
"</head>\n" +
|
||||||
"<body>\n" +
|
"<body>\n" +
|
||||||
$"<script id=\"api-reference\" data-url=\"/api/core/reference/openapi/{document}\"></script>\n" +
|
$"<script id=\"api-reference\" data-url=\"/api/core/reference/openapi/{document}\"></script>\n" +
|
||||||
|
|||||||
18
Moonlight/Core/Models/Forms/ApiKeys/CreateApiKeyForm.cs
Normal file
18
Moonlight/Core/Models/Forms/ApiKeys/CreateApiKeyForm.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Models.Forms.ApiKeys;
|
||||||
|
|
||||||
|
public class CreateApiKeyForm
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "You need to provide a description")]
|
||||||
|
[Description("Write a note here for which application the api key is used for")]
|
||||||
|
public string Description { get; set; } = "";
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "You need to specify the expiration date of the api key")]
|
||||||
|
[Description("Specify when the api key should expire")]
|
||||||
|
public DateTime ExpiresAt { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "You need to specify what permissions the api key should have")]
|
||||||
|
public string Permissions { get; set; } = "[]";
|
||||||
|
}
|
||||||
18
Moonlight/Core/Models/Forms/ApiKeys/UpdateApiKeyForm.cs
Normal file
18
Moonlight/Core/Models/Forms/ApiKeys/UpdateApiKeyForm.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Models.Forms.ApiKeys;
|
||||||
|
|
||||||
|
public class UpdateApiKeyForm
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "You need to provide a description")]
|
||||||
|
[Description("Write a note here for which application the api key is used for")]
|
||||||
|
public string Description { get; set; } = "";
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "You need to specify the expiration date of the api key")]
|
||||||
|
[Description("Specify when the api key should expire")]
|
||||||
|
public DateTime ExpiresAt { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "You need to specify what permissions the api key should have")]
|
||||||
|
public string Permissions { get; set; } = "[]";
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<div class="row mb-3">
|
||||||
|
<ul class="nav nav-tabs nav-line-tabs nav-line-tabs-2x mb-5 fs-6 border-bottom-0">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text-white @(Index == 0 ? "active" : "")" href="/admin/api">Registered APIs</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text-white @(Index == 1 ? "active" : "")" href="/admin/api/keys">API Keys</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
[Parameter] public int Index { get; set; } = 0;
|
||||||
|
}
|
||||||
80
Moonlight/Core/UI/Views/Admin/Api/Index.razor
Normal file
80
Moonlight/Core/UI/Views/Admin/Api/Index.razor
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
@page "/admin/api"
|
||||||
|
|
||||||
|
@using MoonCore.Services
|
||||||
|
@using Moonlight.Core.Configuration
|
||||||
|
@using Moonlight.Core.Interfaces
|
||||||
|
@using Moonlight.Core.Services
|
||||||
|
@using Moonlight.Core.UI.Components.Navigations
|
||||||
|
|
||||||
|
@inject PluginService PluginService
|
||||||
|
@inject ConfigService<CoreConfiguration> ConfigService
|
||||||
|
|
||||||
|
@attribute [RequirePermission(9998)]
|
||||||
|
|
||||||
|
<AdminApiNavigation Index="0" />
|
||||||
|
|
||||||
|
<Tooltip>
|
||||||
|
These apis allow other applications to communicate with moonlight and for example create a new user.
|
||||||
|
These apis are still work in progress and might change a lot so dont be mad at me if i change how they work.
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
<div class="mt-5">
|
||||||
|
<div class="card card-body py-3 px-5">
|
||||||
|
<LazyLoader Load="LoadApis">
|
||||||
|
<CrudTable TItem="ApiModel" ItemSource="Apis" PageSize="100" ShowPagination="false">
|
||||||
|
<CrudColumn TItem="ApiModel" Field="@(x => x.Id)" Title="Id" />
|
||||||
|
<CrudColumn TItem="ApiModel" Field="@(x => x.Name)" Title="Name" />
|
||||||
|
<CrudColumn TItem="ApiModel" Field="@(x => x.Version)" Title="Version" />
|
||||||
|
<CrudColumn TItem="ApiModel">
|
||||||
|
<Template>
|
||||||
|
<div class="text-end">
|
||||||
|
@if (ConfigService.Get().Development.EnableApiReference)
|
||||||
|
{
|
||||||
|
<a href="/api/core/reference?document=@(context.Id)" target="_blank" class="btn btn-primary">
|
||||||
|
<i class="bx bx-sm bx-link"></i>
|
||||||
|
Reference
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<button type="button" class="btn btn-primary disabled" disabled="disabled">
|
||||||
|
<i class="bx bx-sm bx-link"></i>
|
||||||
|
Enable reference in settings
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</Template>
|
||||||
|
</CrudColumn>
|
||||||
|
</CrudTable>
|
||||||
|
</LazyLoader>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
private ApiModel[] Apis;
|
||||||
|
|
||||||
|
private async Task LoadApis(LazyLoader _)
|
||||||
|
{
|
||||||
|
List<ApiModel> models = new();
|
||||||
|
|
||||||
|
foreach (var definition in await PluginService.GetImplementations<IApiDefinition>())
|
||||||
|
{
|
||||||
|
models.Add(new()
|
||||||
|
{
|
||||||
|
Id = definition.GetId(),
|
||||||
|
Name = definition.GetName(),
|
||||||
|
Version = definition.GetVersion()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Apis = models.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ApiModel
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Version { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
68
Moonlight/Core/UI/Views/Admin/Api/Keys.razor
Normal file
68
Moonlight/Core/UI/Views/Admin/Api/Keys.razor
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
@page "/admin/api/keys"
|
||||||
|
|
||||||
|
@using MoonCore.Abstractions
|
||||||
|
@using MoonCore.Helpers
|
||||||
|
@using MoonCoreUI.Services
|
||||||
|
@using Moonlight.Core.Database.Entities
|
||||||
|
@using Moonlight.Core.Models.Forms.ApiKeys
|
||||||
|
@using Moonlight.Core.UI.Components.Navigations
|
||||||
|
|
||||||
|
@inject ClipboardService ClipboardService
|
||||||
|
@inject ToastService ToastService
|
||||||
|
|
||||||
|
@attribute [RequirePermission(9998)]
|
||||||
|
|
||||||
|
<AdminApiNavigation Index="1" />
|
||||||
|
|
||||||
|
<div class="mt-5">
|
||||||
|
<AutoCrud TItem="ApiKey"
|
||||||
|
TCreateForm="CreateApiKeyForm"
|
||||||
|
TUpdateForm="UpdateApiKeyForm"
|
||||||
|
Loader="ApiKeysLoader"
|
||||||
|
ValidateAdd="ValidateAdd">
|
||||||
|
<View>
|
||||||
|
<CrudColumn TItem="ApiKey" Field="@(x => x.Key)" Title="Key">
|
||||||
|
<Template>
|
||||||
|
@{
|
||||||
|
var apiKeyHalf = Formatter.CutInHalf(context!.Key);
|
||||||
|
var bogusHalf = Formatter.IntToStringWithLeadingZeros(69, apiKeyHalf.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<span class="blur-unless-hover">@apiKeyHalf</span>
|
||||||
|
<span class="blur d-none d-lg-inline">@bogusHalf</span>
|
||||||
|
</div>
|
||||||
|
</Template>
|
||||||
|
</CrudColumn>
|
||||||
|
<CrudColumn TItem="ApiKey" Field="@(x => x.Description)" Title="Description"/>
|
||||||
|
<CrudColumn TItem="ApiKey" Field="@(x => x.CreatedAt)" Title="Created at">
|
||||||
|
<Template>
|
||||||
|
@Formatter.FormatDate(context!.CreatedAt)
|
||||||
|
</Template>
|
||||||
|
</CrudColumn>
|
||||||
|
<CrudColumn TItem="ApiKey" Field="@(x => x.ExpiresAt)" Title="Expires at">
|
||||||
|
<Template>
|
||||||
|
@Formatter.FormatDate(context!.ExpiresAt)
|
||||||
|
</Template>
|
||||||
|
</CrudColumn>
|
||||||
|
<CrudColumn TItem="ApiKey" Field="@(x => x.PermissionJson)" Title="Permissions" />
|
||||||
|
</View>
|
||||||
|
</AutoCrud>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
private IEnumerable<ApiKey> ApiKeysLoader(Repository<ApiKey> repository)
|
||||||
|
{
|
||||||
|
return repository.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ValidateAdd(ApiKey apiKey)
|
||||||
|
{
|
||||||
|
var key = Formatter.GenerateString(32);
|
||||||
|
apiKey.Key = key;
|
||||||
|
|
||||||
|
await ClipboardService.Copy(key);
|
||||||
|
await ToastService.Info("Copied api key into your clipboard");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -87,6 +87,10 @@
|
|||||||
<PackageReference Include="Blazor.ContextMenu" Version="1.17.0" />
|
<PackageReference Include="Blazor.ContextMenu" Version="1.17.0" />
|
||||||
<PackageReference Include="BlazorTable" Version="1.17.0" />
|
<PackageReference Include="BlazorTable" Version="1.17.0" />
|
||||||
<PackageReference Include="JWT" Version="10.1.1" />
|
<PackageReference Include="JWT" Version="10.1.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.6">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
<PackageReference Include="MimeTypes" Version="2.4.1">
|
<PackageReference Include="MimeTypes" Version="2.4.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
|||||||
Reference in New Issue
Block a user