Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
58 changes: 36 additions & 22 deletions src/SF.PhotoPixels.API/Extensions/AppConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using Serilog.Debugging;
using Serilog.Sinks.Grafana.Loki;
using Serilog;
using HealthChecks.Network.Core;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using FFMpegCore;
using Microsoft.Extensions.Hosting;
using HealthChecks.Network.Core;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Options;
using Serilog;
using Serilog.Debugging;
using Serilog.Sinks.Grafana.Loki;
using SF.PhotoPixels.Infrastructure.Options;

namespace SF.PhotoPixels.API.Extensions
{
Expand All @@ -26,6 +27,7 @@ public static TelemetryConfiguration ConfigureTelemetry(this WebApplicationBuild
AppName = appName,
};
builder.Configuration.Bind(TelemetryConfiguration.SectionName, telemetryConfiguration);

return telemetryConfiguration;
}

Expand Down Expand Up @@ -59,17 +61,29 @@ public static void ConfigureLogging(this WebApplicationBuilder builder, Telemetr

public static void ConfigureHealthChecks(this WebApplicationBuilder builder)
{
var smtpOptions = builder.Configuration.GetSection("EmailConfiguration");
var smtpOptions = builder.Configuration.GetSection("EmailConfiguration").Get<SmtpOptions>();

builder.Services.AddHealthChecks()
var healthCheckBuilder = builder.Services.AddHealthChecks()
.AddNpgSql(builder.Configuration.GetConnectionString("PhotosMetadata"))
.AddPingHealthCheck(options => options.AddHost("localhost", 1000))
.AddPingHealthCheck(options => options.AddHost("localhost", 1000));

if (smtpOptions is null)
{
return;
}

if (!smtpOptions.IsValidConfiguration())
{
return;
}

healthCheckBuilder
.AddSmtpHealthCheck(setup =>
{
setup.Host = smtpOptions.GetValue<string>("Host");
setup.Port = smtpOptions.GetValue<int>("Port");
setup.ConnectionType = smtpOptions.GetValue<bool>("UseSsl") == true ? SmtpConnectionType.SSL : SmtpConnectionType.TLS;
setup.LoginWith(smtpOptions.GetValue<string>("Username"), smtpOptions.GetValue<string>("Password"));
setup.Host = smtpOptions.Host;
setup.Port = smtpOptions.Port ?? 22;
setup.ConnectionType = smtpOptions.UseSsl ? SmtpConnectionType.SSL : SmtpConnectionType.TLS;
setup.LoginWith(smtpOptions.Username, smtpOptions.Password);
});
}

Expand Down Expand Up @@ -107,12 +121,13 @@ public static string GetRootDirectory()
public static void ConfigureWebServersUpperLimitOptions(this WebApplicationBuilder builder)
{
var upperLimit = builder.Configuration.GetValue<int>("UploadFileUpperLimit");

if (upperLimit == 0)
{
upperLimit = defaultUpperLimit; // default value 50 MB
}

builder.Services.Configure<Microsoft.AspNetCore.Http.Features.FormOptions>(options =>
builder.Services.Configure<FormOptions>(options =>
{
options.MultipartBodyLengthLimit = upperLimit;
});
Expand Down Expand Up @@ -153,13 +168,12 @@ public static void ConfigureFFmpegVideoSupport(this WebApplication app)
}

// configure ffmpeg global options
var binaryFolder = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ?
"/bin"
var binaryFolder = RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
? "/bin"
: ffmpegWindowsBinaryFolder;

var temporaryFilesFolder = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ?
"/tmp" :
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "sf-photos", "temp");
var temporaryFilesFolder = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "/tmp" : Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "sf-photos", "temp");

if (!Directory.Exists(temporaryFilesFolder))
{
Directory.CreateDirectory(temporaryFilesFolder);
Expand All @@ -173,4 +187,4 @@ public static void ConfigureFFmpegVideoSupport(this WebApplication app)
GlobalFFOptions.Configure(ffOptions);
}
}
}
}
59 changes: 33 additions & 26 deletions src/SF.PhotoPixels.API/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,40 +32,46 @@
builder.Services.AddScoped<IAuthorizationHandler, RequireAdminRoleAuthorizationHandler>();

builder.Services.AddAuthorization(options =>
{
var lockedDown = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
options.FallbackPolicy = lockedDown;
options.DefaultPolicy = lockedDown;

options.AddPolicy(RequireAdminRoleAttribute.PolicyName, policyBuilder => policyBuilder.Requirements.Add(new RequireAdminRoleRequirement()));
})
.AddControllers(options => { options.Filters.Add(new AuthorizeFilter()); });
{
var lockedDown = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
options.FallbackPolicy = lockedDown;
options.DefaultPolicy = lockedDown;

options.AddPolicy(RequireAdminRoleAttribute.PolicyName, policyBuilder => policyBuilder.Requirements.Add(new RequireAdminRoleRequirement()));
})
.AddControllers(options =>
{
options.Filters.Add(new AuthorizeFilter());
});

builder.Services.AddInfrastructureServices(builder.Configuration, builder.Environment.IsDevelopment())
.AddApplicationServices(builder.Configuration);

builder.Services.AddIdentityCore<User>(opt =>
{
opt.User.RequireUniqueEmail = true;
opt.Password.RequiredLength = 8;
opt.ClaimsIdentity.UserIdClaimType = CustomClaims.Id;
opt.ClaimsIdentity.EmailClaimType = CustomClaims.Email;
})
{
opt.User.RequireUniqueEmail = true;
opt.Password.RequiredLength = 8;
opt.ClaimsIdentity.UserIdClaimType = CustomClaims.Id;
opt.ClaimsIdentity.EmailClaimType = CustomClaims.Email;
})
.AddUserStore<UserStore>()
.AddSignInManager()
.AddClaimsPrincipalFactory<PrincipalFactory>()
.AddDefaultTokenProviders();

builder.Services.Configure<SmtpOptions>(builder.Configuration.GetSection("EmailConfiguration"));
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = BearerTokenDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = BearerTokenDefaults.AuthenticationScheme;
options.DefaultScheme = BearerTokenDefaults.AuthenticationScheme;
options.DefaultSignInScheme = BearerTokenDefaults.AuthenticationScheme;
options.DefaultSignOutScheme = BearerTokenDefaults.AuthenticationScheme;
})
.AddCustomBearerToken(options => { options.BearerTokenExpiration = TimeSpan.FromMinutes(10); });
{
options.DefaultAuthenticateScheme = BearerTokenDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = BearerTokenDefaults.AuthenticationScheme;
options.DefaultScheme = BearerTokenDefaults.AuthenticationScheme;
options.DefaultSignInScheme = BearerTokenDefaults.AuthenticationScheme;
options.DefaultSignOutScheme = BearerTokenDefaults.AuthenticationScheme;
})
.AddCustomBearerToken(options =>
{
options.BearerTokenExpiration = TimeSpan.FromMinutes(10);
});

builder.Services.AddSwaggerDocumentation();

Expand Down Expand Up @@ -119,9 +125,10 @@
app.UseRouting();

app.MapHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
}).RequireAuthorization("RequireAdminRole");
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
})
.AllowAnonymous();

app.UseAuthentication();
app.UseAuthorization();
Expand All @@ -142,4 +149,4 @@

await app.RunAsync();

public partial class Program { }
public partial class Program;
5 changes: 3 additions & 2 deletions src/SF.PhotoPixels.API/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "https://localhost:7290;http://localhost:5078"
},
"IIS Express": {
Expand All @@ -42,7 +42,8 @@
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:39898"
"applicationUrl": "http://localhost:39898",
"sslPort": 0
}
}
}
17 changes: 16 additions & 1 deletion src/SF.PhotoPixels.Infrastructure/Options/SmtpOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,19 @@ public class SmtpOptions
public required bool UseSsl { get; set; } = true;

public required bool CheckCertificateRevocation { get; set; } = true;
}

public bool IsValidConfiguration()
{
if (string.IsNullOrWhiteSpace(Host))
{
return false;
}

if (Port is null or 0)
{
return false;
}

return true;
}
}
Loading