-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
121 lines (98 loc) · 3.8 KB
/
Program.cs
File metadata and controls
121 lines (98 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text.Json;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Options;
using Scon;
using Scon.Models;
using Scon.Services;
var builder = WebApplication.CreateSlimBuilder(args);
// Logging
builder.Logging.AddConsole();
var sconOptions = SconOptions.ParseFromEnvironment();
builder.Services.Configure<SconOptions>(options =>
{
options.BaseUrl = sconOptions.BaseUrl;
options.DiscordClientId = sconOptions.DiscordClientId;
options.DiscordClientSecret = sconOptions.DiscordClientSecret;
options.DiscordAuthorizedGuildId = sconOptions.DiscordAuthorizedGuildId;
options.DiscordAuthorizedRoleId = sconOptions.DiscordAuthorizedRoleId;
options.SconTailCmd = sconOptions.SconTailCmd;
options.SconSendCmd = sconOptions.SconSendCmd;
});
// Services
builder.Services.AddSingleton<ConsoleService>();
builder.Services.AddHostedService(sp => sp.GetRequiredService<ConsoleService>());
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
options.KnownIPNetworks.Clear();
options.KnownProxies.Clear();
});
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonContext.Default);
});
// Authentication
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "Discord";
})
.AddCookie(options =>
{
options.LoginPath = "/login";
options.LogoutPath = "/logout";
options.ExpireTimeSpan = TimeSpan.FromHours(6);
options.AccessDeniedPath = "/unauthorized";
})
.AddDiscord(options =>
{
options.ClientId = sconOptions.DiscordClientId;
options.ClientSecret = sconOptions.DiscordClientSecret;
options.SaveTokens = true;
options.AccessDeniedPath = "/unauthorized";
options.Scope.Add("guilds.members.read"); // Required to check roles in a specific guild
options.Events.OnCreatingTicket = async context =>
{
var accessToken = context.AccessToken;
var guildId = sconOptions.DiscordAuthorizedGuildId;
var requiredRole = sconOptions.DiscordAuthorizedRoleId.ToString();
var request = new HttpRequestMessage(HttpMethod.Get, $"https://discord.com/api/users/@me/guilds/{guildId}/member");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await context.Backchannel.SendAsync(request, context.HttpContext.RequestAborted);
if (!response.IsSuccessStatusCode)
{
context.Fail("Failed to fetch guild member info or user not in guild.");
return;
}
var member = await response.Content.ReadFromJsonAsync(AppJsonContext.Default.DiscordGuildMember);
if (member is null || !member.Roles.Contains(requiredRole))
{
context.Fail("User does not have the required role.");
return;
}
if (context.Identity?.Name.IsEmpty() != false)
{
context.Fail("User identity is missing.");
return;
}
// Sanitized Username
var username = member.Nickname ?? context.Identity.Name!;
var sanitized = username.ConsoleSafe().Cut(24).OrDefault("Unknown");
context.Identity.AddClaim(new("SconUser", sanitized));
};
});
builder.Services.AddAuthorizationBuilder()
.AddPolicy("Auth", policy => policy
.RequireAuthenticatedUser()
.RequireClaim("SconUser")
);
var app = builder.Build();
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
app.MapRoutes();
app.Run();