mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-22 06:21:44 +01:00
A api key can always revoke itself, add a route to delete any api key
This commit is contained in:
parent
39a8c3fe47
commit
6d7b57ea3b
5 changed files with 69 additions and 43 deletions
|
@ -27,5 +27,13 @@ namespace BTCPayServer.Client
|
|||
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/api-keys/current", null, HttpMethod.Delete), token);
|
||||
HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task RevokeAPIKey(string apikey, CancellationToken token = default)
|
||||
{
|
||||
if (apikey == null)
|
||||
throw new ArgumentNullException(nameof(apikey));
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/api-keys/{apikey}", null, HttpMethod.Delete), token);
|
||||
HandleResponse(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace BTCPayServer.Tests
|
|||
var user = tester.NewAccount();
|
||||
user.GrantAccess();
|
||||
await user.MakeAdmin();
|
||||
var client = await user.CreateClient(Policies.Unrestricted);
|
||||
var client = await user.CreateClient(Policies.CanViewProfile);
|
||||
var clientBasic = await user.CreateClient();
|
||||
//Get current api key
|
||||
var apiKeyData = await client.GetCurrentAPIKeyInfo();
|
||||
|
@ -57,7 +57,7 @@ namespace BTCPayServer.Tests
|
|||
}
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
[Trait("Integration", "Integration")]
|
||||
public async Task CanCreateAPIKeyViaAPI()
|
||||
public async Task CanCreateAndDeleteAPIKeyViaAPI()
|
||||
{
|
||||
using (var tester = ServerTester.Create())
|
||||
{
|
||||
|
@ -80,6 +80,9 @@ namespace BTCPayServer.Tests
|
|||
Label = "Hello world2",
|
||||
Permissions = new Permission[] { Permission.Create(Policies.CanViewProfile) }
|
||||
}));
|
||||
|
||||
await unrestricted.RevokeAPIKey(apiKey.ApiKey);
|
||||
await AssertHttpError(404, async () => await unrestricted.RevokeAPIKey(apiKey.ApiKey));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,17 +56,28 @@ namespace BTCPayServer.Controllers.GreenField
|
|||
}
|
||||
|
||||
[HttpDelete("~/api/v1/api-keys/current")]
|
||||
[Authorize(Policy = Policies.Unrestricted, AuthenticationSchemes = AuthenticationSchemes.GreenfieldAPIKeys)]
|
||||
public async Task<IActionResult> RevokeKey()
|
||||
[Authorize(AuthenticationSchemes = AuthenticationSchemes.GreenfieldAPIKeys)]
|
||||
public Task<IActionResult> RevokeCurrentKey()
|
||||
{
|
||||
if (!ControllerContext.HttpContext.GetAPIKey(out var apiKey))
|
||||
{
|
||||
return NotFound();
|
||||
// Should be impossible (we force apikey auth)
|
||||
return Task.FromResult<IActionResult>(BadRequest());
|
||||
}
|
||||
await _apiKeyRepository.Remove(apiKey, _userManager.GetUserId(User));
|
||||
return Ok();
|
||||
return RevokeKey(apiKey);
|
||||
}
|
||||
|
||||
[HttpDelete("~/api/v1/api-keys/{apikey}", Order = 1)]
|
||||
[Authorize(Policy = Policies.Unrestricted, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||
public async Task<IActionResult> RevokeKey(string apikey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(apikey))
|
||||
return BadRequest();
|
||||
if (await _apiKeyRepository.Remove(apikey, _userManager.GetUserId(User)))
|
||||
return Ok();
|
||||
else
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
private static ApiKeyData FromModel(APIKeyData data)
|
||||
{
|
||||
return new ApiKeyData()
|
||||
|
|
|
@ -53,15 +53,18 @@ namespace BTCPayServer.Security.GreenField
|
|||
}
|
||||
}
|
||||
|
||||
public async Task Remove(string id, string getUserId)
|
||||
public async Task<bool> Remove(string id, string getUserId)
|
||||
{
|
||||
using (var context = _applicationDbContextFactory.CreateContext())
|
||||
{
|
||||
var key = await EntityFrameworkQueryableExtensions.SingleOrDefaultAsync(context.ApiKeys,
|
||||
data => data.Id == id && data.UserId == getUserId);
|
||||
if (key == null)
|
||||
return false;
|
||||
context.ApiKeys.Remove(key);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public class APIKeyQuery
|
||||
|
|
|
@ -188,23 +188,48 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"/api/v1/api-keys/{apikey}": {
|
||||
"delete": {
|
||||
"tags": [
|
||||
"API Keys"
|
||||
],
|
||||
"summary": "Revoke an API Key",
|
||||
"description": "Revoke the current API key so that it cannot be used anymore",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "apikey",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The API Key to revoke",
|
||||
"schema": { "type": "string" }
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The key has been deleted"
|
||||
},
|
||||
"404": {
|
||||
"description": "The key is not found for this user"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"API Key": [ "unrestricted" ],
|
||||
"Basic": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/v1/api-keys/current": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"API Keys"
|
||||
],
|
||||
"summary": "Get current API Key information",
|
||||
"summary": "Get the current API Key information",
|
||||
"description": "View information about the current API key",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Information about the current api key",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiKeyData"
|
||||
}
|
||||
}
|
||||
}
|
||||
"description": "The key has been deleted"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
|
@ -233,7 +258,7 @@
|
|||
},
|
||||
"security": [
|
||||
{
|
||||
"API Key": [ "unrestricted" ]
|
||||
"API Key": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -289,30 +314,6 @@
|
|||
"Basic": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"API Keys"
|
||||
],
|
||||
"summary": "Revoke the current API Key",
|
||||
"description": "Revoke the current API key so that it cannot be used anymore",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The key was revoked and is no longer usable",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiKeyData"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"API Key": [ "unrestricted" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Add table
Reference in a new issue