mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 22:14:26 +01:00
Do not allow login or register over an insecure connection
This commit is contained in:
@@ -74,21 +74,29 @@ namespace BTCPayServer.Controllers
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> Login(string returnUrl = null)
|
||||
{
|
||||
|
||||
if (User.Identity.IsAuthenticated && string.IsNullOrEmpty(returnUrl))
|
||||
return RedirectToLocal();
|
||||
// Clear the existing external cookie to ensure a clean login process
|
||||
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
|
||||
|
||||
CanLoginOrRegister();
|
||||
|
||||
ViewData["ReturnUrl"] = returnUrl;
|
||||
return View();
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[AllowAnonymous]
|
||||
[ValidateAntiForgeryToken]
|
||||
[RateLimitsFilter(ZoneLimits.Login, Scope = RateLimitsScope.RemoteAddress)]
|
||||
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
|
||||
{
|
||||
if (!CanLoginOrRegister())
|
||||
{
|
||||
return View(model);
|
||||
}
|
||||
ViewData["ReturnUrl"] = returnUrl;
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
@@ -199,6 +207,11 @@ namespace BTCPayServer.Controllers
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> LoginWithU2F(LoginWithU2FViewModel viewModel, string returnUrl = null)
|
||||
{
|
||||
if (!CanLoginOrRegister())
|
||||
{
|
||||
return RedirectToAction("Login");
|
||||
}
|
||||
|
||||
ViewData["ReturnUrl"] = returnUrl;
|
||||
var user = await _userManager.FindByIdAsync(viewModel.UserId);
|
||||
|
||||
@@ -242,6 +255,11 @@ namespace BTCPayServer.Controllers
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> LoginWith2fa(bool rememberMe, string returnUrl = null)
|
||||
{
|
||||
if (!CanLoginOrRegister())
|
||||
{
|
||||
return RedirectToAction("Login");
|
||||
}
|
||||
|
||||
// Ensure the user has gone through the username & password screen first
|
||||
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
|
||||
|
||||
@@ -264,6 +282,11 @@ namespace BTCPayServer.Controllers
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> LoginWith2fa(LoginWith2faViewModel model, bool rememberMe, string returnUrl = null)
|
||||
{
|
||||
if (!CanLoginOrRegister())
|
||||
{
|
||||
return RedirectToAction("Login");
|
||||
}
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(model);
|
||||
@@ -305,6 +328,11 @@ namespace BTCPayServer.Controllers
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> LoginWithRecoveryCode(string returnUrl = null)
|
||||
{
|
||||
if (!CanLoginOrRegister())
|
||||
{
|
||||
return RedirectToAction("Login");
|
||||
}
|
||||
|
||||
// Ensure the user has gone through the username & password screen first
|
||||
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
|
||||
if (user == null)
|
||||
@@ -322,6 +350,11 @@ namespace BTCPayServer.Controllers
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> LoginWithRecoveryCode(LoginWithRecoveryCodeViewModel model, string returnUrl = null)
|
||||
{
|
||||
if (!CanLoginOrRegister())
|
||||
{
|
||||
return RedirectToAction("Login");
|
||||
}
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(model);
|
||||
@@ -366,7 +399,8 @@ namespace BTCPayServer.Controllers
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> Register(string returnUrl = null, bool logon = true, bool useBasicLayout = false)
|
||||
{
|
||||
var policies = await _SettingsRepository.GetSettingAsync<PoliciesSettings>() ?? new PoliciesSettings();
|
||||
CanLoginOrRegister();
|
||||
var policies = await _SettingsRepository.GetSettingAsync<PoliciesSettings>() ?? new PoliciesSettings();
|
||||
if (policies.LockSubscription && !User.IsInRole(Roles.ServerAdmin))
|
||||
return RedirectToAction(nameof(HomeController.Index), "Home");
|
||||
ViewData["ReturnUrl"] = returnUrl;
|
||||
@@ -381,6 +415,11 @@ namespace BTCPayServer.Controllers
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null, bool logon = true)
|
||||
{
|
||||
if (!CanLoginOrRegister())
|
||||
{
|
||||
return RedirectToAction("Register");
|
||||
}
|
||||
|
||||
ViewData["ReturnUrl"] = returnUrl;
|
||||
ViewData["Logon"] = logon.ToString(CultureInfo.InvariantCulture).ToLowerInvariant();
|
||||
ViewData["AllowIsAdmin"] = _Options.AllowAdminRegistration;
|
||||
@@ -580,6 +619,21 @@ namespace BTCPayServer.Controllers
|
||||
return RedirectToAction(nameof(HomeController.Index), "Home");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool CanLoginOrRegister()
|
||||
{
|
||||
if (_btcPayServerEnvironment.IsDevelopping || _btcPayServerEnvironment.IsSecure) return true;
|
||||
TempData.SetStatusMessageModel(new StatusMessageModel()
|
||||
{
|
||||
Severity = StatusMessageModel.StatusSeverity.Error,
|
||||
Message = "You cannot login over an insecure connection. Please use HTTPS or Tor."
|
||||
});
|
||||
|
||||
ViewData["disabled"] = true;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -4,7 +4,14 @@
|
||||
ViewData["Title"] = "Log in";
|
||||
Layout = "_WelcomeLayout.cshtml";
|
||||
}
|
||||
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<partial name="_StatusMessage"/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="modal-dialog modal-login">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
@@ -12,30 +19,32 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form asp-route-returnurl="@ViewData["ReturnUrl"]" method="post">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Email" class="input-group-text"><span class="input-group-addon fa fa-user"></span></label>
|
||||
</div>
|
||||
<fieldset disabled="@(ViewData.ContainsKey("disabled") ? "disabled" : null)" >
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Email" class="input-group-text"><span class="input-group-addon fa fa-user"></span></label>
|
||||
</div>
|
||||
|
||||
<input asp-for="Email" class="form-control" placeholder="Email" required="required" />
|
||||
</div>
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Password" class="input-group-text"><span class="input-group-addon fa fa-lock"></span></label>
|
||||
<input asp-for="Email" class="form-control" placeholder="Email" required="required" />
|
||||
</div>
|
||||
<input asp-for="Password" class="form-control" placeholder="Password" required="required" />
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
</div>
|
||||
<span asp-validation-for="Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-lg" id="LoginButton">Sign in</button>
|
||||
</div>
|
||||
<p class="hint-text"><a asp-action="ForgotPassword">Forgot your password?</a></p>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Password" class="input-group-text"><span class="input-group-addon fa fa-lock"></span></label>
|
||||
</div>
|
||||
<input asp-for="Password" class="form-control" placeholder="Password" required="required" />
|
||||
</div>
|
||||
<span asp-validation-for="Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-lg" id="LoginButton">Sign in</button>
|
||||
</div>
|
||||
<p class="hint-text"><a asp-action="ForgotPassword">Forgot your password?</a></p>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
@if (themeManager.ShowRegister)
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
var useBasicLayout = ViewData["UseBasicLayout"] is true;
|
||||
Layout = useBasicLayout ? "../Shared/_Layout.cshtml" : "_WelcomeLayout.cshtml";
|
||||
}
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<partial name="_StatusMessage"/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- We want to center the dialog box in case we are not using the Welcome layout -->
|
||||
<div class="modal-dialog @(useBasicLayout ? "modal-dialog-centered" : "")">
|
||||
@@ -13,45 +21,53 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form asp-route-returnUrl="@ViewData["ReturnUrl"]" asp-route-logon="@ViewData["Logon"]" method="post">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Email" class="input-group-text"><span class="input-group-addon fa fa-user"></span></label>
|
||||
</div>
|
||||
<input asp-for="Email" class="form-control" placeholder="Email" required="required" />
|
||||
</div>
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Password" class="input-group-text"><span class="input-group-addon fa fa-lock"></span></label>
|
||||
</div>
|
||||
<input asp-for="Password" class="form-control" placeholder="Password" required="required" />
|
||||
</div>
|
||||
<span asp-validation-for="Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="ConfirmPassword" class="input-group-text"><span class="input-group-addon fa fa-lock"></span></label>
|
||||
</div>
|
||||
<input asp-for="ConfirmPassword" class="form-control" placeholder="Repeat password" required="required" />
|
||||
</div>
|
||||
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
|
||||
</div>
|
||||
@if (ViewData["AllowIsAdmin"] is true)
|
||||
{
|
||||
<fieldset disabled="@(ViewData.ContainsKey("disabled") ? "disabled" : null)" >
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="IsAdmin"></label>
|
||||
<input asp-for="IsAdmin" type="checkbox" class="form-check-inline" />
|
||||
<span asp-validation-for="IsAdmin" class="text-danger"></span>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Email" class="input-group-text">
|
||||
<span class="input-group-addon fa fa-user"></span>
|
||||
</label>
|
||||
</div>
|
||||
<input asp-for="Email" class="form-control" placeholder="Email" required="required"/>
|
||||
</div>
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
</div>
|
||||
}
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-lg" id="RegisterButton">Create account</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Password" class="input-group-text">
|
||||
<span class="input-group-addon fa fa-lock"></span>
|
||||
</label>
|
||||
</div>
|
||||
<input asp-for="Password" class="form-control" placeholder="Password" required="required"/>
|
||||
</div>
|
||||
<span asp-validation-for="Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="ConfirmPassword" class="input-group-text">
|
||||
<span class="input-group-addon fa fa-lock"></span>
|
||||
</label>
|
||||
</div>
|
||||
<input asp-for="ConfirmPassword" class="form-control" placeholder="Repeat password" required="required"/>
|
||||
</div>
|
||||
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
|
||||
</div>
|
||||
@if (ViewData["AllowIsAdmin"] is true)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="IsAdmin"></label>
|
||||
<input asp-for="IsAdmin" type="checkbox" class="form-check-inline"/>
|
||||
<span asp-validation-for="IsAdmin" class="text-danger"></span>
|
||||
</div>
|
||||
}
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-lg" id="RegisterButton">Create account</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user