Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
FROM node:current-alpine as react-builder
COPY ./ui /ui
WORKDIR /ui
RUN corepack yarn && \
RUN rm /usr/local/bin/yarn* && \
npm install -g corepack@latest && \
corepack yarn && \
corepack yarn build

FROM mcr.microsoft.com/dotnet/sdk:10.0 as aspnet-builder
Expand Down
24 changes: 12 additions & 12 deletions backend/PlexSSO.Test/Service/Auth/AuthenticationValidatorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public void Validate_WithNoAccess_CustomControl_ReturnsCustomisedAccessDeniedMes
var serviceName = new ServiceName(_config!.AccessControls.Keys.First());
var serviceUri = new ServiceUri("/");

_config.AccessControls[serviceName.Value].First().BlockMessage = "Test Access Denied Message";
_config!.AccessControls[serviceName.Value].First().BlockMessage = "Test Access Denied Message";

var result = validator.ValidateAuthenticationStatus(identity, serviceName, serviceUri);

Expand All @@ -88,7 +88,7 @@ public void Validate_WithNoAccess_CustomControl_ReturnsCustomisedAccessDeniedMes
blocked: true,
accessTier: AccessTier.NoAccess,
status: 403,
message: _config.AccessControls.Values.First().First().BlockMessage
message: _config!.AccessControls.Values.First().First().BlockMessage
));
}

Expand All @@ -101,8 +101,8 @@ public void Validate_WithExemptAccess_CustomControl_IsAllowed()
var serviceName = new ServiceName(_config!.AccessControls.Keys.First());
var serviceUri = new ServiceUri("/");

_config.AccessControls[serviceName.Value].First().BlockMessage = "Test Access Denied Message";
_config.AccessControls[serviceName.Value].First().Exempt = [username];
_config!.AccessControls[serviceName.Value].First().BlockMessage = "Test Access Denied Message";
_config!.AccessControls[serviceName.Value].First().Exempt = [username];

var result = validator.ValidateAuthenticationStatus(identity, serviceName, serviceUri);

Expand Down Expand Up @@ -132,7 +132,7 @@ public void Validate_WithNoAccess_DefaultControl_ReturnsCustomisedAccessDeniedMe
blocked: true,
accessTier: AccessTier.NoAccess,
status: 403,
message: _config.DefaultAccessDeniedMessage
message: _config!.DefaultAccessDeniedMessage
));
}

Expand Down Expand Up @@ -191,13 +191,13 @@ public void Validate_WithAccess_CustomBlockControl_IsAllowed(AccessTier[] blocke
AccessTier[] allowedAccessTiers)
{
// NoAccess is permanently blocked
AccessTier[] allBlockedAccessTiers = [.. blockedAccessTiers, AccessTier.NoAccess];
var allBlockedAccessTiers = blockedAccessTiers.Concat([AccessTier.NoAccess]).ToArray();

var validator = CreateValidator();
var serviceName = new ServiceName("status");
var serviceUri = new ServiceUri("/");

_config.AccessControls = new Dictionary<string, PlexSsoConfig.AccessControl[]>()
_config!.AccessControls = new Dictionary<string, PlexSsoConfig.AccessControl[]>()
{
{
"status", new[]
Expand All @@ -223,7 +223,7 @@ public void Validate_WithAccess_CustomBlockControl_IsAllowed(AccessTier[] blocke
blocked: true,
accessTier: AccessTier.NoAccess,
status: 403,
message: _config.AccessControls.Values.First().First().BlockMessage
message: _config!.AccessControls.Values.First().First().BlockMessage
));
}

Expand Down Expand Up @@ -253,13 +253,13 @@ public void Validate_WithAccess_CustomAllowControl_IsAllowed(AccessTier[] allowe
AccessTier[] blockedAccessTiers)
{
// NoAccess are permanently blocked
AccessTier[] allBlockedAccessTiers = [.. blockedAccessTiers, AccessTier.NoAccess];
var allBlockedAccessTiers = blockedAccessTiers.Concat([AccessTier.NoAccess]).ToArray();

var validator = CreateValidator();
var serviceName = new ServiceName("status");
var serviceUri = new ServiceUri("/");

_config.AccessControls = new Dictionary<string, PlexSsoConfig.AccessControl[]>()
_config!.AccessControls = new Dictionary<string, PlexSsoConfig.AccessControl[]>()
{
{
"status", new[]
Expand All @@ -286,8 +286,8 @@ public void Validate_WithAccess_CustomAllowControl_IsAllowed(AccessTier[] allowe
accessTier: AccessTier.NoAccess,
status: 403,
message: blockedAccessTier == AccessTier.NoAccess
? _config.DefaultAccessDeniedMessage
: _config.AccessControls.Values.First().First().BlockMessage
? _config!.DefaultAccessDeniedMessage
: _config!.AccessControls.Values.First().First().BlockMessage
));
}

Expand Down
51 changes: 26 additions & 25 deletions backend/PlexSSO/Program.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using PlexSSO.Extensions;
using PlexSSO.Model;
using PlexSSO.Model.Internal;
using PlexSSO.Service.HealthCheck;
using PlexSSO;

namespace PlexSSO
{
public class Program
{
public static async Task Main(string[] args)
{
if (args.Contains("--healthcheck"))
{
await HealthChecker.CheckHealth($"http://127.0.0.1:{Constants.PortNumber}{Constants.HealthcheckPath}");
return;
}
// Top-level statements - minimal hosting model
var argsList = args ?? [];

WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddCommandLine(args, typeof(PlexSsoConfig).GetAnnotatedCliArgumentsAsDictionary());
})
.ConfigureKestrel((context, options) => options.AddServerHeader = false)
.UseStartup<Startup>()
.UseUrls($"http://0.0.0.0:{Constants.PortNumber}/")
.Build()
.Run();
}
}
if (argsList.Contains("--healthcheck"))
{
await HealthChecker.CheckHealth($"http://127.0.0.1:{Constants.PortNumber}{Constants.HealthcheckPath}");
return;
}

var builder = WebApplication.CreateBuilder(args);

// Allow CLI args to map to our annotated config
builder.Configuration.AddCommandLine(argsList, typeof(PlexSsoConfig).GetAnnotatedCliArgumentsAsDictionary());

// Configure web host to use Startup for separation of concerns
builder.Host.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel((context, options) => options.AddServerHeader = false);
webBuilder.UseUrls($"http://0.0.0.0:{Constants.PortNumber}/");
webBuilder.UseStartup<Startup>();
});

var host = builder.Build();
await host.RunAsync();
3 changes: 1 addition & 2 deletions backend/PlexSSO/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Antiforgery;
Expand Down Expand Up @@ -86,7 +85,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAntifor
app.Use((context, next) => {
var tokens = antiForgery.GetAndStoreTokens(context);
context.Response.Cookies.Append(Constants.CsrfHeaderName, tokens.RequestToken, new CookieOptions { HttpOnly = false });
context.Response.Headers.TryAdd(Constants.PoweredByHeaderName, Constants.PoweredByHeaderValue);
context.Response.Headers.Append(Constants.PoweredByHeaderName, Constants.PoweredByHeaderValue);
return next.Invoke();
});
app.UseStaticFiles();
Expand Down