Implemented api key crud and started adding system page. Added 404 page
This commit is contained in:
@@ -1,11 +0,0 @@
|
||||
namespace Moonlight.ApiServer.Attributes;
|
||||
|
||||
public class RequirePermissionAttribute : Attribute
|
||||
{
|
||||
public string Permission { get; set; }
|
||||
|
||||
public RequirePermissionAttribute(string permission)
|
||||
{
|
||||
Permission = permission;
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,5 @@ public class CoreDataContext : DatabaseContext
|
||||
public override string Prefix { get; } = "Core";
|
||||
|
||||
public DbSet<User> Users { get; set; }
|
||||
public DbSet<ApiKey> ApiKeys { get; set; }
|
||||
}
|
||||
11
Moonlight.ApiServer/Database/Entities/ApiKey.cs
Normal file
11
Moonlight.ApiServer/Database/Entities/ApiKey.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Moonlight.ApiServer.Database.Entities;
|
||||
|
||||
public class ApiKey
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Secret { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string PermissionsJson { get; set; } = "[]";
|
||||
public DateTime ExpiresAt { get; set; }
|
||||
}
|
||||
102
Moonlight.ApiServer/Database/Migrations/20241029134013_AddedApiKeys.Designer.cs
generated
Normal file
102
Moonlight.ApiServer/Database/Migrations/20241029134013_AddedApiKeys.Designer.cs
generated
Normal file
@@ -0,0 +1,102 @@
|
||||
// <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.ApiServer.Database;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.ApiServer.Database.Migrations
|
||||
{
|
||||
[DbContext(typeof(CoreDataContext))]
|
||||
[Migration("20241029134013_AddedApiKeys")]
|
||||
partial class AddedApiKeys
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasDefaultSchema("Core")
|
||||
.HasAnnotation("ProductVersion", "8.0.8")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Moonlight.ApiServer.Database.Entities.ApiKey", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("ExpiresAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("PermissionsJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Secret")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ApiKeys", "Core");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.ApiServer.Database.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("AccessToken")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("PermissionsJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("RefreshTimestamp")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("RefreshToken")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("TokenValidTimestamp")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users", "Core");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.ApiServer.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedApiKeys : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ApiKeys",
|
||||
schema: "Core",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Secret = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Description = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
PermissionsJson = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ExpiresAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ApiKeys", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "ApiKeys",
|
||||
schema: "Core");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,34 @@ namespace Moonlight.ApiServer.Database.Migrations
|
||||
|
||||
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Moonlight.ApiServer.Database.Entities.ApiKey", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("ExpiresAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("PermissionsJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Secret")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ApiKeys", "Core");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.ApiServer.Database.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MoonCore.Blazor.Tailwind.Attributes;
|
||||
using MoonCore.Extended.Abstractions;
|
||||
using MoonCore.Extended.Helpers;
|
||||
using MoonCore.Helpers;
|
||||
using MoonCore.Models;
|
||||
using Moonlight.ApiServer.Database.Entities;
|
||||
using Moonlight.Shared.Http.Requests.Admin.ApiKeys;
|
||||
using Moonlight.Shared.Http.Responses.Admin.ApiKeys;
|
||||
|
||||
namespace Moonlight.ApiServer.Http.Controllers.Admin.ApiKeys;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/admin/apikeys")]
|
||||
public class ApiKeysController : Controller
|
||||
{
|
||||
private readonly CrudHelper<ApiKey, ApiKeyDetailResponse> CrudHelper;
|
||||
private readonly DatabaseRepository<ApiKey> ApiKeyRepository;
|
||||
|
||||
public ApiKeysController(CrudHelper<ApiKey, ApiKeyDetailResponse> crudHelper, DatabaseRepository<ApiKey> apiKeyRepository)
|
||||
{
|
||||
CrudHelper = crudHelper;
|
||||
ApiKeyRepository = apiKeyRepository;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[RequirePermission("admin.apikeys.read")]
|
||||
public async Task<IPagedData<ApiKeyDetailResponse>> Get([FromQuery] int page, [FromQuery] int pageSize = 50)
|
||||
=> await CrudHelper.Get(page, pageSize);
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[RequirePermission("admin.apikeys.read")]
|
||||
public async Task<ApiKeyDetailResponse> GetSingle(int id)
|
||||
=> await CrudHelper.GetSingle(id);
|
||||
|
||||
[HttpPost]
|
||||
[RequirePermission("admin.apikeys.create")]
|
||||
public async Task<CreateApiKeyResponse> Create([FromBody] CreateApiKeyRequest request)
|
||||
{
|
||||
var secret = "api_" + Formatter.GenerateString(32);
|
||||
|
||||
var apiKey = new ApiKey()
|
||||
{
|
||||
Description = request.Description,
|
||||
PermissionsJson = request.PermissionsJson,
|
||||
ExpiresAt = request.ExpiresAt,
|
||||
Secret = secret
|
||||
};
|
||||
|
||||
var finalApiKey = ApiKeyRepository.Add(apiKey);
|
||||
|
||||
return Mapper.Map<CreateApiKeyResponse>(finalApiKey);
|
||||
}
|
||||
|
||||
[HttpPatch("{id}")]
|
||||
[RequirePermission("admin.apikeys.update")]
|
||||
public async Task<ApiKeyDetailResponse> Update([FromRoute] int id, [FromBody] UpdateApiKeyRequest request)
|
||||
=> await CrudHelper.Update(id, request);
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[RequirePermission("admin.apikeys.delete")]
|
||||
public async Task Delete([FromRoute] int id)
|
||||
=> await CrudHelper.Delete(id);
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MoonCore.Blazor.Tailwind.Attributes;
|
||||
using MoonCore.Exceptions;
|
||||
using MoonCore.Extended.Abstractions;
|
||||
using MoonCore.Extended.Helpers;
|
||||
using MoonCore.Models;
|
||||
using Moonlight.ApiServer.Attributes;
|
||||
using Moonlight.ApiServer.Database.Entities;
|
||||
using Moonlight.Shared.Http.Requests.Admin.Users;
|
||||
using Moonlight.Shared.Http.Responses.Admin.Users;
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MoonCore.Blazor.Tailwind.Attributes;
|
||||
using MoonCore.Exceptions;
|
||||
using MoonCore.Extended.Abstractions;
|
||||
using MoonCore.Extended.Helpers;
|
||||
using MoonCore.Extended.OAuth2.ApiServer;
|
||||
using MoonCore.Helpers;
|
||||
using MoonCore.PluginFramework.Services;
|
||||
using MoonCore.Services;
|
||||
using Moonlight.ApiServer.Attributes;
|
||||
using Moonlight.ApiServer.Configuration;
|
||||
using Moonlight.ApiServer.Database.Entities;
|
||||
using Moonlight.ApiServer.Helpers.Authentication;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Moonlight.ApiServer.Attributes;
|
||||
using MoonCore.Blazor.Tailwind.Attributes;
|
||||
using Moonlight.ApiServer.Exceptions;
|
||||
using Moonlight.ApiServer.Helpers.Authentication;
|
||||
|
||||
|
||||
@@ -41,7 +41,8 @@ public static class Startup
|
||||
var logLevels = new Dictionary<string, string>
|
||||
{
|
||||
{ "Default", "Information" },
|
||||
{ "Microsoft.AspNetCore", "Warning" }
|
||||
{ "Microsoft.AspNetCore", "Warning" },
|
||||
{ "System.Net.Http.HttpClient", "Warning" }
|
||||
};
|
||||
|
||||
var logLevelsJson = JsonSerializer.Serialize(logLevels);
|
||||
@@ -113,7 +114,7 @@ public static class Startup
|
||||
databaseHelper.AddDbContext(database);
|
||||
builder.Services.AddScoped(database);
|
||||
}
|
||||
|
||||
|
||||
databaseHelper.GenerateMappings();
|
||||
|
||||
builder.Services.AddSingleton(databaseHelper);
|
||||
@@ -163,7 +164,7 @@ public static class Startup
|
||||
});
|
||||
|
||||
if (!config.Authentication.UseLocalOAuth2) return Task.CompletedTask;
|
||||
|
||||
|
||||
logger.LogInformation("Using local oauth2 provider");
|
||||
|
||||
builder.Services.AddOAuth2Provider(configuration =>
|
||||
|
||||
Reference in New Issue
Block a user