mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 14:04:26 +01:00
Greenfield: Rename API key redirect params; switch to POST body (#1898)
* Rename user param to userId in API key redirect This way it is clearer what to expect and it also make the parameteer easier to consume. * Post redirect: Allow form url and prettify page - Form URL as alternative to controller/action for external URLs - Making it look nice and add explanation for non-JS case * APIKeys: Minor view updates fix * APIKeys: Use POST redirect for confirmation fix * UI: Minor update to confirm view Tidies it up and adapts to the newly added ConfirmAPIKeys view. * APIKeys: Update delete view Structures the information in title and description better. * APIKeys: Distinguish authorize and confirm (reuse) * Upgrade ChromeDriver * Test fixes * Clean up PostRedirect view By adding missing forgery token * Re-add tests for callback post values * Rename key param to apiKey in API key redirect * Update BTCPayServer/wwwroot/swagger/v1/swagger.template.authorization.json Co-authored-by: Andrew Camilleri <evilkukka@gmail.com> * Use DEBUG conditional for postredirect-callback-test route * Remove unnecessary ChromeDriver references * Add debug flag * Remove debug flags Co-authored-by: Andrew Camilleri <evilkukka@gmail.com>
This commit is contained in:
@@ -7,9 +7,7 @@ using BTCPayServer.Client;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Security.GreenField;
|
||||
using ExchangeSharp;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NBitcoin;
|
||||
using NBitcoin.DataEncoders;
|
||||
@@ -40,10 +38,11 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
return View("Confirm", new ConfirmModel()
|
||||
{
|
||||
Title = "Delete API Key " + (string.IsNullOrEmpty(key.Label) ? string.Empty : key.Label) + "(" + key.Id + ")",
|
||||
Description = "Any application using this api key will immediately lose access",
|
||||
Title = $"Delete API Key {(string.IsNullOrEmpty(key.Label) ? string.Empty : key.Label)}",
|
||||
DescriptionHtml = true,
|
||||
Description = $"Any application using this API key will immediately lose access: <code>{key.Id}</code>",
|
||||
Action = "Delete",
|
||||
ActionUrl = this.Url.ActionLink(nameof(RemoveAPIKeyPost), values: new { id = id })
|
||||
ActionUrl = Url.ActionLink(nameof(RemoveAPIKeyPost), values: new { id })
|
||||
});
|
||||
}
|
||||
|
||||
@@ -81,7 +80,7 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("~/api-keys/authorize")]
|
||||
public async Task<IActionResult> AuthorizeAPIKey( string[] permissions, string applicationName = null, Uri redirect = null,
|
||||
public async Task<IActionResult> AuthorizeAPIKey(string[] permissions, string applicationName = null, Uri redirect = null,
|
||||
bool strict = true, bool selectiveStores = false, string applicationIdentifier = null)
|
||||
{
|
||||
if (!_btcPayServerEnvironment.IsSecure)
|
||||
@@ -157,16 +156,17 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
|
||||
//we have a key that is sufficient, redirect to a page to confirm that it's ok to provide this key to the app.
|
||||
return View("Confirm",
|
||||
new ConfirmModel()
|
||||
return View("ConfirmAPIKey",
|
||||
new AuthorizeApiKeysViewModel()
|
||||
{
|
||||
Title =
|
||||
$"Are you sure about exposing your API Key to {applicationName ?? applicationIdentifier}?",
|
||||
Description =
|
||||
$"You've previously generated this API Key ({key.Id}) specifically for {applicationName ?? applicationIdentifier} with the url {redirect}. ",
|
||||
ActionUrl = GetRedirectToApplicationUrl(redirect, key),
|
||||
ButtonClass = "btn-secondary",
|
||||
Action = "Confirm"
|
||||
ApiKey = key.Id,
|
||||
RedirectUrl = redirect,
|
||||
Label = applicationName,
|
||||
ApplicationName = applicationName,
|
||||
SelectiveStores = selectiveStores,
|
||||
Strict = strict,
|
||||
Permissions = string.Join(';', permissions),
|
||||
ApplicationIdentifier = applicationIdentifier
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -255,16 +255,37 @@ namespace BTCPayServer.Controllers
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
switch (viewModel.Command.ToLowerInvariant())
|
||||
var command = viewModel.Command.ToLowerInvariant();
|
||||
switch (command)
|
||||
{
|
||||
case "no":
|
||||
case "cancel":
|
||||
return RedirectToAction("APIKeys");
|
||||
case "yes":
|
||||
var key = await CreateKey(viewModel, (viewModel.ApplicationIdentifier, viewModel.RedirectUrl?.Authority));
|
||||
|
||||
case "authorize":
|
||||
case "confirm":
|
||||
var key = command == "authorize"
|
||||
? await CreateKey(viewModel, (viewModel.ApplicationIdentifier, viewModel.RedirectUrl?.Authority))
|
||||
: await _apiKeyRepository.GetKey(viewModel.ApiKey);
|
||||
|
||||
if (viewModel.RedirectUrl != null)
|
||||
{
|
||||
return Redirect(GetRedirectToApplicationUrl(viewModel.RedirectUrl, key));
|
||||
var permissions = key.GetBlob().Permissions;
|
||||
var redirectVm = new PostRedirectViewModel()
|
||||
{
|
||||
FormUrl = viewModel.RedirectUrl.ToString(),
|
||||
Parameters =
|
||||
{
|
||||
new KeyValuePair<string, string>("apiKey", key.Id),
|
||||
new KeyValuePair<string, string>("userId", key.UserId)
|
||||
}
|
||||
};
|
||||
foreach (var permission in permissions)
|
||||
{
|
||||
redirectVm.Parameters.Add(
|
||||
new KeyValuePair<string, string>("permissions[]", permission));
|
||||
}
|
||||
|
||||
return View("PostRedirect", redirectVm);
|
||||
}
|
||||
|
||||
TempData.SetStatusMessageModel(new StatusMessageModel()
|
||||
@@ -272,21 +293,14 @@ namespace BTCPayServer.Controllers
|
||||
Severity = StatusMessageModel.StatusSeverity.Success,
|
||||
Html = $"API key generated! <code class='alert-link'>{key.Id}</code>"
|
||||
});
|
||||
|
||||
return RedirectToAction("APIKeys", new { key = key.Id });
|
||||
|
||||
default:
|
||||
return View(viewModel);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetRedirectToApplicationUrl(Uri redirect, APIKeyData key)
|
||||
{
|
||||
var uri = new UriBuilder(redirect);
|
||||
var permissions = key.GetBlob().Permissions;
|
||||
BTCPayServerClient.AppendPayloadToQuery(uri,
|
||||
new Dictionary<string, object>() {{"key", key.Id}, {"permissions", permissions}, {"user", key.UserId}});
|
||||
return uri.Uri.AbsoluteUri;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> AddApiKey(AddApiKeyViewModel viewModel)
|
||||
{
|
||||
@@ -313,6 +327,7 @@ namespace BTCPayServer.Controllers
|
||||
});
|
||||
return RedirectToAction("APIKeys");
|
||||
}
|
||||
|
||||
private IActionResult HandleCommands(AddApiKeyViewModel viewModel)
|
||||
{
|
||||
if (string.IsNullOrEmpty(viewModel.Command))
|
||||
@@ -333,7 +348,6 @@ namespace BTCPayServer.Controllers
|
||||
switch (command)
|
||||
{
|
||||
case "change-store-mode":
|
||||
|
||||
permissionValueItem.StoreMode = permissionValueItem.StoreMode == AddApiKeyViewModel.ApiKeyStoreMode.Specific
|
||||
? AddApiKeyViewModel.ApiKeyStoreMode.AllStores
|
||||
: AddApiKeyViewModel.ApiKeyStoreMode.Specific;
|
||||
@@ -344,6 +358,7 @@ namespace BTCPayServer.Controllers
|
||||
permissionValueItem.SpecificStores.Add(null);
|
||||
}
|
||||
return View(viewModel);
|
||||
|
||||
case "add-store":
|
||||
permissionValueItem.SpecificStores.Add(null);
|
||||
return View(viewModel);
|
||||
@@ -501,9 +516,9 @@ namespace BTCPayServer.Controllers
|
||||
public bool Strict { get; set; }
|
||||
public bool SelectiveStores { get; set; }
|
||||
public string Permissions { get; set; }
|
||||
public string ApiKey { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class ApiKeysViewModel
|
||||
{
|
||||
public List<APIKeyData> ApiKeyDatas { get; set; }
|
||||
|
||||
Reference in New Issue
Block a user