Compare commits
No commits in common. "565252382c10020c6899aaece6437758757e1bdc" and "c189cc69557a01bbeeb699232798c1f8607d88ab" have entirely different histories.
565252382c
...
c189cc6955
@ -1,26 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Mirea.Api.Endpoint.Common.Attributes;
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
|
||||||
public class CacheMaxAgeAttribute : Attribute
|
|
||||||
{
|
|
||||||
public int MaxAge { get; }
|
|
||||||
|
|
||||||
public CacheMaxAgeAttribute(int days = 0, int hours = 0, int minutes = 0)
|
|
||||||
{
|
|
||||||
MaxAge = (int)new TimeSpan(days, hours, minutes, 0).TotalSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CacheMaxAgeAttribute(int minutes) : this(0, 0, minutes)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public CacheMaxAgeAttribute(bool usingSetting = false)
|
|
||||||
{
|
|
||||||
if (usingSetting)
|
|
||||||
MaxAge = -1;
|
|
||||||
else
|
|
||||||
MaxAge = 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,7 +6,7 @@ namespace Mirea.Api.Endpoint.Common.Services;
|
|||||||
|
|
||||||
public static class UrlHelper
|
public static class UrlHelper
|
||||||
{
|
{
|
||||||
public static string GetCurrentDomain(this HttpContext context) =>
|
public static string CurrentDomain(HttpContext context) =>
|
||||||
context.Request.Headers["X-Forwarded-Host"].FirstOrDefault() ?? context.Request.Host.Host;
|
context.Request.Headers["X-Forwarded-Host"].FirstOrDefault() ?? context.Request.Host.Host;
|
||||||
|
|
||||||
private static string CreateSubPath(string? path)
|
private static string CreateSubPath(string? path)
|
||||||
|
@ -74,11 +74,9 @@ public partial class SetupController(
|
|||||||
Response.Cookies.Append("AuthToken", token, new CookieOptions
|
Response.Cookies.Append("AuthToken", token, new CookieOptions
|
||||||
{
|
{
|
||||||
Path = UrlHelper.GetSubPathWithoutFirstApiName + "api",
|
Path = UrlHelper.GetSubPathWithoutFirstApiName + "api",
|
||||||
Domain = HttpContext.GetCurrentDomain(),
|
Domain = UrlHelper.CurrentDomain(ControllerContext.HttpContext),
|
||||||
#if !DEBUG
|
|
||||||
Secure = true,
|
Secure = true,
|
||||||
HttpOnly = true
|
HttpOnly = true
|
||||||
#endif
|
|
||||||
});
|
});
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
|
@ -30,11 +30,9 @@ public class AuthController(IOptionsSnapshot<Admin> user, AuthService auth, Pass
|
|||||||
{
|
{
|
||||||
Expires = expires,
|
Expires = expires,
|
||||||
Path = UrlHelper.GetSubPathWithoutFirstApiName + "api",
|
Path = UrlHelper.GetSubPathWithoutFirstApiName + "api",
|
||||||
Domain = HttpContext.GetCurrentDomain(),
|
Domain = UrlHelper.CurrentDomain(ControllerContext.HttpContext),
|
||||||
#if !DEBUG
|
|
||||||
Secure = true,
|
Secure = true,
|
||||||
HttpOnly = true
|
HttpOnly = true
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Response.Cookies.Append(name, value, cookieOptions);
|
Response.Cookies.Append(name, value, cookieOptions);
|
||||||
|
@ -17,14 +17,11 @@ using System.Threading.Tasks;
|
|||||||
namespace Mirea.Api.Endpoint.Controllers.V1;
|
namespace Mirea.Api.Endpoint.Controllers.V1;
|
||||||
|
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0")]
|
||||||
[CacheMaxAge(true)]
|
|
||||||
public class ScheduleController(IMediator mediator, IOptionsSnapshot<GeneralConfig> config) : BaseController
|
public class ScheduleController(IMediator mediator, IOptionsSnapshot<GeneralConfig> config) : BaseController
|
||||||
{
|
{
|
||||||
[CacheMaxAge(1, 0)]
|
|
||||||
[HttpGet("StartTerm")]
|
[HttpGet("StartTerm")]
|
||||||
public ActionResult<DateOnly> GetStartTerm() => config.Value.ScheduleSettings!.StartTerm;
|
public ActionResult<DateOnly> GetStartTerm() => config.Value.ScheduleSettings!.StartTerm;
|
||||||
|
|
||||||
[CacheMaxAge(1, 0)]
|
|
||||||
[HttpGet("PairPeriod")]
|
[HttpGet("PairPeriod")]
|
||||||
public ActionResult<Dictionary<int, PairPeriodTime>> GetPairPeriod() => config.Value.ScheduleSettings!.PairPeriod.ConvertToDto();
|
public ActionResult<Dictionary<int, PairPeriodTime>> GetPairPeriod() => config.Value.ScheduleSettings!.PairPeriod.ConvertToDto();
|
||||||
|
|
||||||
@ -199,4 +196,4 @@ public class ScheduleController(IMediator mediator, IOptionsSnapshot<GeneralConf
|
|||||||
Professors = professors,
|
Professors = professors,
|
||||||
LectureHalls = lectureHalls
|
LectureHalls = lectureHalls
|
||||||
});
|
});
|
||||||
}
|
}
|
@ -1,81 +0,0 @@
|
|||||||
using Cronos;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Mirea.Api.Endpoint.Common.Attributes;
|
|
||||||
using Mirea.Api.Endpoint.Common.Settings;
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Mirea.Api.Endpoint.Middleware;
|
|
||||||
|
|
||||||
public class CacheMaxAgeMiddleware(RequestDelegate next, IServiceProvider serviceProvider)
|
|
||||||
{
|
|
||||||
public async Task InvokeAsync(HttpContext context)
|
|
||||||
{
|
|
||||||
if (!context.Response.StatusCode.ToString().StartsWith('2'))
|
|
||||||
{
|
|
||||||
await next(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var endpoint = context.GetEndpoint();
|
|
||||||
|
|
||||||
var actionDescriptor = endpoint?.Metadata.GetMetadata<Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor>();
|
|
||||||
|
|
||||||
if (actionDescriptor == null)
|
|
||||||
{
|
|
||||||
await next(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var controllerType = actionDescriptor.ControllerTypeInfo;
|
|
||||||
var methodInfo = actionDescriptor.MethodInfo;
|
|
||||||
|
|
||||||
var maxAgeAttribute = methodInfo.GetCustomAttribute<CacheMaxAgeAttribute>() ?? controllerType.GetCustomAttribute<CacheMaxAgeAttribute>();
|
|
||||||
|
|
||||||
if (maxAgeAttribute == null)
|
|
||||||
{
|
|
||||||
await next(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (maxAgeAttribute.MaxAge)
|
|
||||||
{
|
|
||||||
case < 0:
|
|
||||||
{
|
|
||||||
DateTime? nextDate;
|
|
||||||
var now = DateTime.UtcNow;
|
|
||||||
|
|
||||||
using (var scope = serviceProvider.CreateScope())
|
|
||||||
{
|
|
||||||
var updateCronString = scope.ServiceProvider.GetRequiredService<IOptionsSnapshot<GeneralConfig>>().Value.ScheduleSettings?.CronUpdateSchedule;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(updateCronString) ||
|
|
||||||
!CronExpression.TryParse(updateCronString, CronFormat.Standard, out var updateCron))
|
|
||||||
{
|
|
||||||
await next(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nextDate = updateCron.GetNextOccurrence(now);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nextDate.HasValue)
|
|
||||||
{
|
|
||||||
await next(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
context.Response.Headers.CacheControl = "max-age=" + (int)(nextDate.Value - now).TotalSeconds;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case > 0:
|
|
||||||
context.Response.Headers.CacheControl = "max-age=" + maxAgeAttribute.MaxAge;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
await next(context);
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,7 +11,7 @@ namespace Mirea.Api.Endpoint.Middleware;
|
|||||||
|
|
||||||
public class CustomExceptionHandlerMiddleware(RequestDelegate next)
|
public class CustomExceptionHandlerMiddleware(RequestDelegate next)
|
||||||
{
|
{
|
||||||
public async Task InvokeAsync(HttpContext context)
|
public async Task Invoke(HttpContext context)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@ namespace Mirea.Api.Endpoint.Middleware;
|
|||||||
|
|
||||||
public class JwtRevocationMiddleware(RequestDelegate next)
|
public class JwtRevocationMiddleware(RequestDelegate next)
|
||||||
{
|
{
|
||||||
public async Task InvokeAsync(HttpContext context, IRevokedToken revokedTokenStore)
|
public async Task Invoke(HttpContext context, IRevokedToken revokedTokenStore)
|
||||||
{
|
{
|
||||||
if (context.Request.Headers.ContainsKey("Authorization"))
|
if (context.Request.Headers.ContainsKey("Authorization"))
|
||||||
{
|
{
|
||||||
|
@ -13,7 +13,7 @@ public class MaintenanceModeMiddleware(RequestDelegate next, IMaintenanceModeSer
|
|||||||
return endpoint?.Metadata.GetMetadata<MaintenanceModeIgnoreAttribute>() != null;
|
return endpoint?.Metadata.GetMetadata<MaintenanceModeIgnoreAttribute>() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task InvokeAsync(HttpContext context)
|
public async Task Invoke(HttpContext context)
|
||||||
{
|
{
|
||||||
if (!maintenanceModeService.IsMaintenanceMode && !maintenanceModeNotConfigureService.IsMaintenanceMode || IsIgnoreMaintenanceMode(context))
|
if (!maintenanceModeService.IsMaintenanceMode && !maintenanceModeNotConfigureService.IsMaintenanceMode || IsIgnoreMaintenanceMode(context))
|
||||||
await next(context);
|
await next(context);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
@ -95,15 +94,13 @@ public class Program
|
|||||||
builder.Services.AddJwtToken(builder.Configuration);
|
builder.Services.AddJwtToken(builder.Configuration);
|
||||||
builder.Services.AddSecurity(builder.Configuration);
|
builder.Services.AddSecurity(builder.Configuration);
|
||||||
|
|
||||||
builder.Services.AddDataProtection()
|
|
||||||
.PersistKeysToFileSystem(new DirectoryInfo(PathBuilder.Combine("DataProtection")));
|
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
app.UseForwardedHeaders();
|
app.UseForwardedHeaders();
|
||||||
app.UseStaticFiles(UrlHelper.GetSubPath.TrimEnd('/'));
|
app.UseStaticFiles(UrlHelper.GetSubPath.TrimEnd('/'));
|
||||||
app.UseCors("AllowAll");
|
app.UseCors("AllowAll");
|
||||||
app.UseCustomSerilog();
|
app.UseCustomSerilog();
|
||||||
|
app.UseForwardedHeaders();
|
||||||
|
|
||||||
using (var scope = app.Services.CreateScope())
|
using (var scope = app.Services.CreateScope())
|
||||||
{
|
{
|
||||||
@ -125,10 +122,9 @@ public class Program
|
|||||||
|
|
||||||
app.UseCustomSwagger(app.Services);
|
app.UseCustomSwagger(app.Services);
|
||||||
|
|
||||||
app.UseMiddleware<CustomExceptionHandlerMiddleware>();
|
|
||||||
app.UseMiddleware<MaintenanceModeMiddleware>();
|
app.UseMiddleware<MaintenanceModeMiddleware>();
|
||||||
|
app.UseMiddleware<CustomExceptionHandlerMiddleware>();
|
||||||
app.UseMiddleware<JwtRevocationMiddleware>();
|
app.UseMiddleware<JwtRevocationMiddleware>();
|
||||||
app.UseMiddleware<CacheMaxAgeMiddleware>();
|
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user