Added authentication for the node against the api server. Cleaned up routes

This commit is contained in:
2025-03-01 17:32:43 +01:00
parent 6d61e026c1
commit ef7f866ded
15 changed files with 678 additions and 260 deletions

View File

@@ -1,40 +1,87 @@
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using MoonCore.Attributes;
using MoonCore.Helpers;
using MoonCore.Models;
using MoonlightServers.Daemon.Configuration;
using MoonlightServers.DaemonShared.PanelSide.Http.Responses;
namespace MoonlightServers.Daemon.Services;
[Singleton]
public class RemoteService
{
private readonly AppConfiguration Configuration;
private readonly HttpApiClient ApiClient;
public RemoteService(AppConfiguration configuration)
{
Configuration = configuration;
}
public Task<HttpApiClient> CreateHttpClient()
{
var formattedUrl = Configuration.Remote.Url.EndsWith('/')
? Configuration.Remote.Url
: Configuration.Remote.Url + "/";
var httpClient = new HttpClient()
{
BaseAddress = new Uri(formattedUrl)
};
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {Configuration.Security.Token}");
var apiClient = new HttpApiClient(httpClient);
return Task.FromResult(apiClient);
ApiClient = CreateHttpClient(configuration);
}
public async Task GetStatus()
{
using var apiClient = await CreateHttpClient();
await apiClient.Get("api/servers/remote/node/trip");
await ApiClient.Get("api/remote/servers/node/trip");
}
public async Task<PagedData<ServerDataResponse>> GetServers(int page, int perPage)
{
return await ApiClient.GetJson<PagedData<ServerDataResponse>>(
$"api/remote/servers?page={page}&pageSize={perPage}"
);
}
public async Task<ServerInstallDataResponse> GetServerInstallation(int serverId)
{
return await ApiClient.GetJson<ServerInstallDataResponse>(
$"api/remote/servers/{serverId}/install"
);
}
#region Helpers
private HttpApiClient CreateHttpClient(AppConfiguration configuration)
{
var formattedUrl = configuration.Remote.Url.EndsWith('/')
? configuration.Remote.Url
: configuration.Remote.Url + "/";
var httpClient = new HttpClient()
{
BaseAddress = new Uri(formattedUrl)
};
var jwt = GenerateJwt(configuration);
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwt}");
return new HttpApiClient(httpClient);
}
private string GenerateJwt(AppConfiguration configuration)
{
var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
var securityTokenDesc = new SecurityTokenDescriptor()
{
Expires = DateTime.UtcNow.AddYears(1), // TODO: Document somewhere
IssuedAt = DateTime.UtcNow,
Issuer = configuration.Security.TokenId,
Audience = configuration.Remote.Url,
NotBefore = DateTime.UtcNow.AddSeconds(-1),
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(configuration.Security.Token)
),
SecurityAlgorithms.HmacSha256
)
};
var securityToken = jwtSecurityTokenHandler.CreateJwtSecurityToken(securityTokenDesc);
securityToken.Header.Add("kid", configuration.Security.TokenId);
return jwtSecurityTokenHandler.WriteToken(securityToken);
}
#endregion
}

View File

@@ -40,12 +40,9 @@ public class ServerService : IHostedLifecycleService
// Loading models and converting them
Logger.LogInformation("Fetching servers from panel");
using var apiClient = await RemoteService.CreateHttpClient();
var servers = await PagedData<ServerDataResponse>.All(async (page, pageSize) =>
await apiClient.GetJson<PagedData<ServerDataResponse>>(
$"api/servers/remote/servers?page={page}&pageSize={pageSize}"
)
await RemoteService.GetServers(page, pageSize)
);
var configurations = servers.Select(x => new ServerConfiguration()