From 9dbfe2217193331d0bfcfb9d941aa8ab7fe965ea Mon Sep 17 00:00:00 2001 From: Andrew Camilleri Date: Wed, 23 Dec 2020 05:19:38 +0100 Subject: [PATCH] add greenfield authorize UI docs and fix small issues (#2156) * add greenfield authorize UI docs and fix small issues * Update ManageController.APIKeys.cs * Apply suggestions from code review Co-authored-by: Dennis Reimann Co-authored-by: Dennis Reimann --- .../Controllers/ManageController.APIKeys.cs | 13 ++++++---- docs/greenfield-authorization.md | 24 +++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 docs/greenfield-authorization.md diff --git a/BTCPayServer/Controllers/ManageController.APIKeys.cs b/BTCPayServer/Controllers/ManageController.APIKeys.cs index be3b5baf7..0fa5a440e 100644 --- a/BTCPayServer/Controllers/ManageController.APIKeys.cs +++ b/BTCPayServer/Controllers/ManageController.APIKeys.cs @@ -98,8 +98,13 @@ namespace BTCPayServer.Controllers permissions ??= Array.Empty(); var requestPermissions = Permission.ToPermissions(permissions); + if (redirect?.IsAbsoluteUri is false) + { + redirect = null; + } if (!string.IsNullOrEmpty(applicationIdentifier) && redirect != null) { + //check if there is an app identifier that matches and belongs to the current user var keys = await _apiKeyRepository.GetKeys(new APIKeyRepository.APIKeyQuery() { @@ -110,7 +115,7 @@ namespace BTCPayServer.Controllers var blob = key.GetBlob(); if (blob.ApplicationIdentifier != applicationIdentifier || - blob.ApplicationAuthority != redirect.Authority) + blob.ApplicationAuthority != redirect.AbsoluteUri) { continue; } @@ -190,7 +195,7 @@ namespace BTCPayServer.Controllers private void AdjustVMForAuthorization(AuthorizeApiKeysViewModel vm) { - var parsedPermissions = Permission.ToPermissions(vm.Permissions.Split(';')).GroupBy(permission => permission.Policy); + var parsedPermissions = Permission.ToPermissions(vm.Permissions?.Split(';')??Array.Empty()).GroupBy(permission => permission.Policy); for (var index = vm.PermissionValues.Count - 1; index >= 0; index--) { @@ -266,7 +271,7 @@ namespace BTCPayServer.Controllers case "authorize": case "confirm": var key = command == "authorize" - ? await CreateKey(viewModel, (viewModel.ApplicationIdentifier, viewModel.RedirectUrl?.Authority)) + ? await CreateKey(viewModel, (viewModel.ApplicationIdentifier, viewModel.RedirectUrl.AbsoluteUri)) : await _apiKeyRepository.GetKey(viewModel.ApiKey); if (viewModel.RedirectUrl != null) @@ -274,7 +279,7 @@ namespace BTCPayServer.Controllers var permissions = key.GetBlob().Permissions; var redirectVm = new PostRedirectViewModel() { - FormUrl = viewModel.RedirectUrl.ToString(), + FormUrl = viewModel.RedirectUrl.AbsoluteUri, Parameters = { new KeyValuePair("apiKey", key.Id), diff --git a/docs/greenfield-authorization.md b/docs/greenfield-authorization.md new file mode 100644 index 000000000..1f44a6092 --- /dev/null +++ b/docs/greenfield-authorization.md @@ -0,0 +1,24 @@ + +# GreenField API Authorization Flow + +The GreenField API allows two modes of authentication to its endpoints: Basic auth and API Keys. + +## Basic auth +Basic auth allows you to seamlessly integrate with BTCPay Server's user system using only a traditional user/password login form. This is however a security risk if the application is a third party as they will receive your credentials in plain text and will be able to access your full account. + +## API Keys +BTCPay Server's GreenField API also allows users to generate API keys with [specific permissions](https://docs.btcpayserver.org/API/Greenfield/v1/#section/Authentication/API%20Key). **If you are integrating BTCPay Server into your third-party application, this is the recommended way.** + +Asking a user to generate a dedicated API key, with a specific set of permissions can be a bad UX experience. For this scenario, we have the [Authorize User UI](https://docs.btcpayserver.org/API/Greenfield/v1/#tag/Authorization). This allows external applications to request the user to generate an API key with a specific set of permissions by simply generating a URL to BTCPay Server and redirecting the user to it. +Additionally, there are 2 optional parameters to the endpoint which allow a more seamless integration: +* if `redirect` is specified, once the API key is created, BTCPay Server redirects the user via a POST submission to the specified `redirect` URL, with a json body containing the API key, user id, and permissions granted. +* if `applicationIdentifier` is specified (along with `redirect`), BTCPay Server will check if there is an existing API key associated with the user that also has this application identifier, redirect host AND the permissions required match. `applicationIdentifier` is ignored if `redirect` is not specified. + +Some examples of a generated Authorize URL: +* `https://mainnet.demo.btcpayserver.org/api-keys/authorize` - A simplistic request, where no permission is requested. Useful to prove that a user exists on a specific BTCPay Server instance. +* `https://mainnet.demo.btcpayserver.org/api-keys/authorize?applicationName=Your%20Application` - Indicates that the API key is being generated for `Your Application` +* `https://mainnet.demo.btcpayserver.org/api-keys/authorize?applicationName=Your%20Application&redirect=http://gozo.com` - Redirects the user via a POST to `http://gozo.com` with a JSON body containing the API key and its info. +* `https://mainnet.demo.btcpayserver.org/api-keys/authorize?applicationName=Your%20Application&redirect=http://gozo.com&applicationIdentifier=gozo` - Attempts to match a previously created API key based on the app identifier, domain and permissions and is prompted. +* `https://mainnet.demo.btcpayserver.org/api-keys/authorize?permissions=btcpay.store.cancreateinvoice&permissions=btcpay.store.canviewinvoices` - A request asking for permissions to create and view invoices on all stores available to the user +* `https://mainnet.demo.btcpayserver.org/api-keys/authorize?permissions=btcpay.store.cancreateinvoice&permissions=btcpay.store.canviewinvoices&selectiveStores=true` - A request asking for permissions to create and view invoices on stores but also allows the user to choose which stores the application will have the permission to. +* `https://mainnet.demo.btcpayserver.org/api-keys/authorize?permissions=btcpay.store.cancreateinvoice&permissions=btcpay.store.canviewinvoices&strict=false` - A request asking for permissions but allows the user to remove or add to the requested permission list.