Add swagger, tidy up, fix docker, and add docker-compose.yml
This commit is contained in:
parent
ba9f063fd6
commit
1c597e2115
24
Dockerfile
24
Dockerfile
|
@ -4,20 +4,30 @@ WORKDIR /app
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
EXPOSE 8081
|
EXPOSE 8081
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||||||
|
ARG TARGETARCH
|
||||||
|
ARG BUILDPLATFORM
|
||||||
ARG BUILD_CONFIGURATION=Release
|
ARG BUILD_CONFIGURATION=Release
|
||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY ["Galaeth.CoreApi/Galaeth.CoreApi.csproj", "Galaeth.CoreApi/"]
|
|
||||||
RUN dotnet restore "Galaeth.CoreApi/Galaeth.CoreApi.csproj"
|
COPY ["Galaeth.ApiServer/Galaeth.ApiServer.csproj", "Galaeth.ApiServer/"]
|
||||||
|
COPY ["Galaeth.Core/Galaeth.Core.csproj", "Galaeth.Core/"]
|
||||||
|
COPY ["Galaeth.Services/Galaeth.Services.csproj", "Galaeth.Services/"]
|
||||||
|
COPY ["Galaeth.DAL/Galaeth.DAL.csproj", "Galaeth.DAL/"]
|
||||||
|
|
||||||
|
RUN dotnet restore "Galaeth.ApiServer/Galaeth.ApiServer.csproj"
|
||||||
COPY . .
|
COPY . .
|
||||||
WORKDIR "/src/Galaeth.CoreApi"
|
WORKDIR "/src/Galaeth.ApiServer"
|
||||||
RUN dotnet build "Galaeth.CoreApi.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
RUN dotnet build "Galaeth.ApiServer.csproj" -c $BUILD_CONFIGURATION -a $TARGETARCH -o /app/build
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
ARG TARGETARCH
|
||||||
ARG BUILD_CONFIGURATION=Release
|
ARG BUILD_CONFIGURATION=Release
|
||||||
RUN dotnet publish "Galaeth.CoreApi.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
|
||||||
|
RUN dotnet publish "Galaeth.ApiServer.csproj" --no-restore -c $BUILD_CONFIGURATION -a $TARGETARCH -o /app/publish /p:UseAppHost=false
|
||||||
|
|
||||||
FROM base AS final
|
FROM base AS final
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=publish /app/publish .
|
COPY --from=publish /app/publish .
|
||||||
ENTRYPOINT ["dotnet", "Galaeth.CoreApi.dll"]
|
ENTRYPOINT ["dotnet", "Galaeth.ApiServer.dll"]
|
||||||
|
|
|
@ -5,7 +5,6 @@ using Galaeth.Services.Interfaces;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using MyCSharp.HttpUserAgentParser.AspNetCore;
|
using MyCSharp.HttpUserAgentParser.AspNetCore;
|
||||||
using Toycloud.AspNetCore.Mvc.ModelBinding;
|
|
||||||
|
|
||||||
namespace Galaeth.ApiServer.Controllers;
|
namespace Galaeth.ApiServer.Controllers;
|
||||||
|
|
||||||
|
@ -40,7 +39,7 @@ public class AuthenticationController : ApiController
|
||||||
/// <returns>If successful, instance of <see cref="AccessTokensDto"/>.</returns>
|
/// <returns>If successful, instance of <see cref="AccessTokensDto"/>.</returns>
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[HttpPost("login")]
|
[HttpPost("login")]
|
||||||
public async Task<IActionResult> Authenticate([FromBodyOrDefault] AuthenticateRequest request)
|
public async Task<IActionResult> Authenticate(AuthenticateRequest request)
|
||||||
{
|
{
|
||||||
if (request is null)
|
if (request is null)
|
||||||
{
|
{
|
||||||
|
@ -72,7 +71,7 @@ public class AuthenticationController : ApiController
|
||||||
/// <returns>If successful, instance of <see cref="AccessTokensDto"/>.</returns>
|
/// <returns>If successful, instance of <see cref="AccessTokensDto"/>.</returns>
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[HttpPost("refresh")]
|
[HttpPost("refresh")]
|
||||||
public async Task<IActionResult> RefreshSession([FromBodyOrDefault] RefreshUserAuthRequest userAuthRequest)
|
public async Task<IActionResult> RefreshSession(RefreshUserAuthRequest userAuthRequest)
|
||||||
{
|
{
|
||||||
if (userAuthRequest is null)
|
if (userAuthRequest is null)
|
||||||
{
|
{
|
||||||
|
@ -101,7 +100,7 @@ public class AuthenticationController : ApiController
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Instance of <see cref="ChangePasswordRequest"/>.</param>
|
/// <param name="request">Instance of <see cref="ChangePasswordRequest"/>.</param>
|
||||||
[HttpPost("pwd")]
|
[HttpPost("pwd")]
|
||||||
public async Task<IActionResult> ChangePassword([FromBodyOrDefault] ChangePasswordRequest request)
|
public async Task<IActionResult> ChangePassword(ChangePasswordRequest request)
|
||||||
{
|
{
|
||||||
if (request is null)
|
if (request is null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,17 +11,17 @@ namespace Galaeth.ApiServer.Controllers;
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("v1/me")]
|
[Route("v1/me")]
|
||||||
public class UserSelfController : ApiController
|
public class MeController : ApiController
|
||||||
{
|
{
|
||||||
private readonly IIdentityProvider _identityProvider;
|
private readonly IIdentityProvider _identityProvider;
|
||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="UserSelfController"/> class.
|
/// Initializes a new instance of the <see cref="MeController"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="identityProvider">Instance of <see cref="IIdentityProvider"/>.</param>
|
/// <param name="identityProvider">Instance of <see cref="IIdentityProvider"/>.</param>
|
||||||
/// <param name="userService">Instance of <see cref="IUserService"/>.</param>
|
/// <param name="userService">Instance of <see cref="IUserService"/>.</param>
|
||||||
public UserSelfController(
|
public MeController(
|
||||||
IIdentityProvider identityProvider,
|
IIdentityProvider identityProvider,
|
||||||
IUserService userService)
|
IUserService userService)
|
||||||
{
|
{
|
|
@ -24,7 +24,9 @@
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Toycloud.AspNetCore.Mvc.ModelBinding.BodyOrDefaultBinding" Version="1.2.1" />
|
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="7.0.0" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="7.0.0" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="7.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Galaeth.ApiServer.Models;
|
namespace Galaeth.ApiServer.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -8,10 +10,12 @@ public class ChangePasswordRequest
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user's old password.
|
/// The user's old password.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonPropertyName("oldPassword")]
|
||||||
public string OldPassword { get; set; }
|
public string OldPassword { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user's new password.
|
/// The user's new password.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonPropertyName("newPassword")]
|
||||||
public string NewPassword { get; set; }
|
public string NewPassword { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,10 @@ using Galaeth.Core.Configuration;
|
||||||
using Galaeth.Services.Configuration;
|
using Galaeth.Services.Configuration;
|
||||||
using Galaeth.Services.Profiles;
|
using Galaeth.Services.Profiles;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
using MyCSharp.HttpUserAgentParser.AspNetCore.DependencyInjection;
|
using MyCSharp.HttpUserAgentParser.AspNetCore.DependencyInjection;
|
||||||
using MyCSharp.HttpUserAgentParser.MemoryCache.DependencyInjection;
|
using MyCSharp.HttpUserAgentParser.MemoryCache.DependencyInjection;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Galaeth.ApiServer;
|
namespace Galaeth.ApiServer;
|
||||||
|
|
||||||
|
@ -32,9 +32,6 @@ internal static class Program
|
||||||
|
|
||||||
Log.Logger = new LoggerConfiguration()
|
Log.Logger = new LoggerConfiguration()
|
||||||
.Enrich.FromLogContext()
|
.Enrich.FromLogContext()
|
||||||
.MinimumLevel.Override("Default", LogEventLevel.Warning)
|
|
||||||
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
|
|
||||||
.MinimumLevel.Override("System", LogEventLevel.Warning)
|
|
||||||
.WriteTo.Console()
|
.WriteTo.Console()
|
||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
|
|
||||||
|
@ -56,6 +53,32 @@ internal static class Program
|
||||||
builder.Services.AddHttpContextAccessor();
|
builder.Services.AddHttpContextAccessor();
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen(setup =>
|
||||||
|
{
|
||||||
|
var jwtSecurityScheme = new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
BearerFormat = "JWT",
|
||||||
|
Name = "JWT Authentication",
|
||||||
|
In = ParameterLocation.Header,
|
||||||
|
Type = SecuritySchemeType.Http,
|
||||||
|
Scheme = JwtBearerDefaults.AuthenticationScheme,
|
||||||
|
Description = "Paste your access token below",
|
||||||
|
Reference = new OpenApiReference
|
||||||
|
{
|
||||||
|
Id = JwtBearerDefaults.AuthenticationScheme,
|
||||||
|
Type = ReferenceType.SecurityScheme,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
setup.AddSecurityDefinition(jwtSecurityScheme.Reference.Id, jwtSecurityScheme);
|
||||||
|
|
||||||
|
setup.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||||
|
{
|
||||||
|
{ jwtSecurityScheme, Array.Empty<string>() },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Setup authentication.
|
// Setup authentication.
|
||||||
var jwtConfig = new JwtConfiguration();
|
var jwtConfig = new JwtConfiguration();
|
||||||
builder.Configuration.Bind("JWT", jwtConfig);
|
builder.Configuration.Bind("JWT", jwtConfig);
|
||||||
|
@ -83,6 +106,12 @@ internal static class Program
|
||||||
app.UseMiddleware<ExceptionMiddleware>();
|
app.UseMiddleware<ExceptionMiddleware>();
|
||||||
app.UseMiddleware<StatusCodeMiddleware>();
|
app.UseMiddleware<StatusCodeMiddleware>();
|
||||||
|
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
}
|
||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
|
|
30
docker-compose.yml
Normal file
30
docker-compose.yml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
services:
|
||||||
|
api-server:
|
||||||
|
image: forge.alveus.dev/misc/galaeth-api:latest
|
||||||
|
build: .
|
||||||
|
container_name: "galaeth-api-server"
|
||||||
|
restart: on-failure
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
environment:
|
||||||
|
ASPNETCORE_ENVIRONMENT: 'Development'
|
||||||
|
EmailDomainBlacklist__Enabled: false
|
||||||
|
Database__ConnectionString: 'Server=postgres;Port=5432;User Id=postgres;Password=postgres;Database=galaeth'
|
||||||
|
InitialUser__Username: 'admin'
|
||||||
|
InitialUser__Email: 'admin@change.me'
|
||||||
|
InitialUser__Password: 'Change!Me1234'
|
||||||
|
JWT__SecretKey: "11ca143299193d9968d31cb85cb30991820ed9dc231aac902ba38abf25b7b6f904e1d614391001e49d8b8af28c4f79b48bb7853ef20bf06a38c17cf8c3f694c0"
|
||||||
|
JWT__Issuer: 'localdev'
|
||||||
|
JWT__Audience: 'localdev'
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:17.1-bookworm
|
||||||
|
container_name: postgres
|
||||||
|
restart: on-failure
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: 'postgres'
|
||||||
|
POSTGRES_PASSWORD: 'postgres'
|
||||||
|
POSTGRES_DB: 'galaeth'
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue