Skip to content

Commit 505bc5b

Browse files
authored
Merge pull request #1089 from hargata/Hargata/server.config.endpoints
Allow users to configure HTTPS and HTTP endpoints entirely within the…
2 parents fce40ae + 8ddd040 commit 505bc5b

8 files changed

Lines changed: 138 additions & 7 deletions

File tree

Controllers/HomeController.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,8 @@ public IActionResult Setup()
597597
EnableAuth = _config.GetServerAuthEnabled(),
598598
DefaultReminderEmail = _config.GetDefaultReminderEmail(),
599599
EnableRootUserOIDC = _config.GetEnableRootUserOIDC(),
600-
CookieLifeSpan = _config.GetAuthCookieLifeSpan().ToString()
600+
CookieLifeSpan = _config.GetAuthCookieLifeSpan().ToString(),
601+
KestrelAppConfig = _config.GetKestrelAppConfig()
601602
};
602603
return View(viewModel);
603604
}

Helper/ConfigHelper.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public interface IConfigHelper
1212
ReminderUrgencyConfig GetReminderUrgencyConfig();
1313
MailConfig GetMailConfig();
1414
UserConfig GetUserConfig(ClaimsPrincipal user);
15+
KestrelAppConfig GetKestrelAppConfig();
1516
bool SaveUserConfig(ClaimsPrincipal user, UserConfig configData);
1617
bool SaveServerConfig(ServerConfig serverConfig);
1718
bool AuthenticateRootUser(string username, string password);
@@ -53,6 +54,12 @@ public ConfigHelper(IConfiguration serverConfig,
5354
_cache = memoryCache;
5455
_logger = logger;
5556
}
57+
58+
public KestrelAppConfig GetKestrelAppConfig()
59+
{
60+
KestrelAppConfig kestrelConfig = _config.GetSection("Kestrel").Get<KestrelAppConfig>() ?? new KestrelAppConfig();
61+
return kestrelConfig;
62+
}
5663
public string GetWebHookUrl()
5764
{
5865
var webhook = CheckString("LUBELOGGER_WEBHOOK");
@@ -269,6 +276,43 @@ public bool SaveServerConfig(ServerConfig serverConfig)
269276
{
270277
serverConfig.CookieLifeSpan = null;
271278
}
279+
if (serverConfig.KestrelAppConfig != null)
280+
{
281+
if (serverConfig.KestrelAppConfig.Endpoints.Http != null)
282+
{
283+
//validate http endpoint
284+
if (string.IsNullOrWhiteSpace(serverConfig.KestrelAppConfig.Endpoints.Http.Url))
285+
{
286+
serverConfig.KestrelAppConfig.Endpoints.Http = null;
287+
}
288+
}
289+
if (serverConfig.KestrelAppConfig.Endpoints.HttpsInlineCertFile != null)
290+
{
291+
//https endpoint provided
292+
if (string.IsNullOrWhiteSpace(serverConfig.KestrelAppConfig.Endpoints.HttpsInlineCertFile.Url))
293+
{
294+
serverConfig.KestrelAppConfig.Endpoints.HttpsInlineCertFile = null;
295+
}
296+
else if (serverConfig.KestrelAppConfig.Endpoints.HttpsInlineCertFile.Certificate != null)
297+
{
298+
if (string.IsNullOrWhiteSpace(serverConfig.KestrelAppConfig.Endpoints.HttpsInlineCertFile.Certificate.Password))
299+
{
300+
//cert not null but password is null
301+
serverConfig.KestrelAppConfig.Endpoints.HttpsInlineCertFile.Certificate.Password = null;
302+
}
303+
if (string.IsNullOrWhiteSpace(serverConfig.KestrelAppConfig.Endpoints.HttpsInlineCertFile.Certificate.Path))
304+
{
305+
//cert not null but path is null
306+
serverConfig.KestrelAppConfig.Endpoints.HttpsInlineCertFile.Certificate = null;
307+
}
308+
}
309+
}
310+
if (serverConfig.KestrelAppConfig.Endpoints.Http == null && serverConfig.KestrelAppConfig.Endpoints.HttpsInlineCertFile == null)
311+
{
312+
//if no endpoints are provided
313+
serverConfig.KestrelAppConfig = null;
314+
}
315+
}
272316
try
273317
{
274318
File.WriteAllText(StaticHelper.ServerConfigPath, JsonSerializer.Serialize(serverConfig));

Models/ServerConfig.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,8 @@ public class ServerConfig
7777
[JsonPropertyName("LUBELOGGER_COOKIE_LIFESPAN")]
7878
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
7979
public string? CookieLifeSpan { get; set; } = string.Empty;
80+
[JsonPropertyName("Kestrel")]
81+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
82+
public KestrelAppConfig? KestrelAppConfig { get; set; }
8083
}
8184
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace CarCareTracker.Models
4+
{
5+
public class KestrelAppConfig
6+
{
7+
public KestrelAppConfigEndpoints Endpoints { get; set; } = new KestrelAppConfigEndpoints();
8+
}
9+
public class KestrelAppConfigEndpoints
10+
{
11+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
12+
public KestrelAppConfigHttpEndpoint? Http { get; set; } = new KestrelAppConfigHttpEndpoint();
13+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
14+
public KestrelAppConfigHttpsEndpoint? HttpsInlineCertFile { get; set; } = new KestrelAppConfigHttpsEndpoint();
15+
}
16+
public class KestrelAppConfigHttpEndpoint
17+
{
18+
public string? Url { get; set; } = string.Empty;
19+
}
20+
public class KestrelAppConfigHttpsEndpoint
21+
{
22+
public string? Url { get; set; } = string.Empty;
23+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
24+
public KestrelAppConfigHttpsCertificate? Certificate { get; set; } = new KestrelAppConfigHttpsCertificate();
25+
}
26+
public class KestrelAppConfigHttpsCertificate
27+
{
28+
public string? Path { get; set; }
29+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
30+
public string? Password { get; set; }
31+
}
32+
}

Models/Settings/ServerSettingsViewModel.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ public class ServerSettingsViewModel
2323
public bool EnableAuth { get; set; }
2424
public List<string> AvailableLocales { get; set; }
2525
public string CookieLifeSpan { get; set; }
26+
public KestrelAppConfig KestrelAppConfig { get; set; }
2627
}
2728
}

Views/Home/Setup.cshtml

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,38 @@
163163
</form>
164164
</div>
165165
<div class="setup-wizard-content" data-page="3" style="display:none;">
166+
<div class="d-flex justify-content-between align-items-center">
167+
<span class="display-5">@translator.Translate(userLanguage, "Server Endpoints")</span>
168+
<div class="form-check form-switch">
169+
<input class="form-check-input" type="checkbox" onchange="nextOnSkip(this)" role="switch" id="skipHTTPS">
170+
<label class="form-check-label" for="skipHTTPS">@translator.Translate(userLanguage, "Skip")</label>
171+
</div>
172+
</div>
173+
<hr />
174+
<form class="form-inline">
175+
<div class="form-group">
176+
<label for="inputHTTPURL">@translator.Translate(userLanguage, "Http Endpoint")</label>
177+
<input type="text" id="inputHTTPURL" class="form-control" placeholder="@translator.Translate(userLanguage, "Not Configured")" value="@Model.KestrelAppConfig.Endpoints.Http.Url">
178+
<small class="text-body-secondary">@translator.Translate(userLanguage, "Restart Required")</small>
179+
</div>
180+
<div class="form-group">
181+
<label for="inputHTTPSURL">@translator.Translate(userLanguage, "Https Endpoint")</label>
182+
<input type="text" id="inputHTTPSURL" class="form-control" placeholder="@translator.Translate(userLanguage, "Not Configured")" value="@Model.KestrelAppConfig.Endpoints.HttpsInlineCertFile.Url">
183+
<small class="text-body-secondary">@translator.Translate(userLanguage, "Restart Required")</small>
184+
</div>
185+
<div class="form-group">
186+
<label for="inputHTTPSCertLocation">@translator.Translate(userLanguage, "HTTPS Certificate Location")</label>
187+
<input type="text" id="inputHTTPSCertLocation" class="form-control" placeholder="@translator.Translate(userLanguage, "Not Configured")" value="@Model.KestrelAppConfig.Endpoints.HttpsInlineCertFile.Certificate.Path">
188+
<small class="text-body-secondary">@translator.Translate(userLanguage, "Restart Required")</small>
189+
</div>
190+
<div class="form-group">
191+
<label for="inputHTTPSCertPassword">@translator.Translate(userLanguage, "HTTPS Certificate Password")</label>
192+
<input type="text" id="inputHTTPSCertPassword" class="form-control" placeholder="@translator.Translate(userLanguage, "Not Configured")" value="@Model.KestrelAppConfig.Endpoints.HttpsInlineCertFile.Certificate.Password">
193+
<small class="text-body-secondary">@translator.Translate(userLanguage, "Restart Required")</small>
194+
</div>
195+
</form>
196+
</div>
197+
<div class="setup-wizard-content" data-page="4" style="display:none;">
166198
<div class="d-flex justify-content-between align-items-center">
167199
<span class="display-5">@translator.Translate(userLanguage, "Single Sign On")</span>
168200
<div class="form-check form-switch">
@@ -236,7 +268,7 @@
236268
</div>
237269
</form>
238270
</div>
239-
<div class="setup-wizard-content" data-page="4" style="display:none;">
271+
<div class="setup-wizard-content" data-page="5" style="display:none;">
240272
<span class="display-5">@translator.Translate(userLanguage, "Miscellaneous")</span>
241273
<hr />
242274
<form class="form-inline">
@@ -284,7 +316,7 @@
284316
</div>
285317
</form>
286318
</div>
287-
<div class="setup-wizard-content" data-page="5" style="display:none;">
319+
<div class="setup-wizard-content" data-page="6" style="display:none;">
288320
<div class="d-flex text-center align-items-center justify-content-center flex-column" style="height:100%;">
289321
<div><span class="display-5">@translator.Translate(userLanguage, "Server Settings Saved")<span class="text-success"><i class="bi bi-check-lg"></i></span></span></div>
290322
<div class="mt-2"><a class="btn btn-secondary me-2" onclick="loadSetupPage(0)">@translator.Translate(userLanguage, "Restart Wizard")</a><a class="btn btn-primary" onclick="returnToGarage()">@translator.Translate(userLanguage, "Return to Garage")</a></div>

wwwroot/defaults/en_US.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

wwwroot/js/serversettings.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,19 @@ function determineSetupButtons() {
1010
let currentVisiblePage = $(".setup-wizard-content:visible").attr('data-page');
1111
switch (currentVisiblePage) {
1212
case '0':
13-
case '5':
13+
case '6':
1414
$(".setup-wizard-nav").hide();
1515
break;
1616
case '1':
1717
case '2':
1818
case '3':
19+
case '4':
1920
$(".setup-wizard-nav").show();
2021
$(".btn-prev").show();
2122
$(".btn-next").show();
2223
$(".btn-save").hide();
2324
break;
24-
case '4':
25+
case '5':
2526
$(".setup-wizard-nav").show();
2627
$(".btn-prev").show();
2728
$(".btn-next").hide();
@@ -98,7 +99,21 @@ function saveSetup() {
9899
VeryUrgentDistance: $("#inputVeryUrgentDistance").val()
99100
},
100101
DefaultReminderEmail: $("#inputDefaultReminderEmail").val(),
101-
EnableRootUserOIDC: $("#inputOIDCRootUser").val()
102+
EnableRootUserOIDC: $("#inputOIDCRootUser").val(),
103+
KestrelAppConfig: {
104+
Endpoints: {
105+
Http: {
106+
Url: $("#inputHTTPURL").val()
107+
},
108+
HttpsInlineCertFile: {
109+
Url: $("#inputHTTPSURL").val(),
110+
Certificate: {
111+
Path: $("#inputHTTPSCertLocation").val(),
112+
Password: $("#inputHTTPSCertPassword").val()
113+
}
114+
}
115+
}
116+
}
102117
};
103118
let registrationMode = $("#inputRegistrationMode");
104119
if (registrationMode.length > 0) {
@@ -127,6 +142,9 @@ function saveSetup() {
127142
if ($("#skipPostgres").is(":checked")) {
128143
setupData["PostgresConnection"] = null;
129144
}
145+
if ($("#skipHTTPS").is(":checked")) {
146+
setupData["KestrelAppConfig"] = null;
147+
}
130148
let rootUserOIDC = $("#inputOIDCRootUser");
131149
if (rootUserOIDC.length > 0) {
132150
setupData["EnableRootUserOIDC"] = $("#inputOIDCRootUser").val();

0 commit comments

Comments
 (0)