Greenfield: Admins can create/delete API keys of any user (#4680)

* Greenfield: Admins can create/delete API keys of any user

* Greenfield: Improve doc for scoped apikey (Close #4673)

* Fix permissions hierarchy

* Update BTCPayServer.Client/Permissions.cs

* Fix tests

---------

Co-authored-by: Andrew Camilleri <evilkukka@gmail.com>
This commit is contained in:
Nicolas Dorier
2023-02-24 16:19:03 +09:00
committed by GitHub
parent d14dafc871
commit 4ae05272c3
13 changed files with 401 additions and 169 deletions

View File

@@ -44,7 +44,14 @@ namespace BTCPayServer.Controllers.Greenfield
[HttpPost("~/api/v1/api-keys")]
[Authorize(Policy = Policies.Unrestricted, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
public async Task<IActionResult> CreateKey(CreateApiKeyRequest request)
public Task<IActionResult> CreateAPIKey(CreateApiKeyRequest request)
{
return CreateUserAPIKey(_userManager.GetUserId(User), request);
}
[HttpPost("~/api/v1/users/{userId}/api-keys")]
[Authorize(Policy = Policies.CanManageUsers, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
public async Task<IActionResult> CreateUserAPIKey(string userId, CreateApiKeyRequest request)
{
request ??= new CreateApiKeyRequest();
request.Permissions ??= System.Array.Empty<Permission>();
@@ -52,7 +59,7 @@ namespace BTCPayServer.Controllers.Greenfield
{
Id = Encoders.Hex.EncodeData(RandomUtils.GetBytes(20)),
Type = APIKeyType.Permanent,
UserId = _userManager.GetUserId(User),
UserId = userId,
Label = request.Label
};
key.SetBlob(new APIKeyBlob()
@@ -72,19 +79,27 @@ namespace BTCPayServer.Controllers.Greenfield
// Should be impossible (we force apikey auth)
return Task.FromResult<IActionResult>(BadRequest());
}
return RevokeKey(apiKey);
return RevokeAPIKey(apiKey);
}
[HttpDelete("~/api/v1/api-keys/{apikey}", Order = 1)]
[Authorize(Policy = Policies.Unrestricted, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
public async Task<IActionResult> RevokeKey(string apikey)
public Task<IActionResult> RevokeAPIKey(string apikey)
{
return RevokeAPIKey(_userManager.GetUserId(User), apikey);
}
[HttpDelete("~/api/v1/users/{userId}/api-keys/{apikey}", Order = 1)]
[Authorize(Policy = Policies.CanManageUsers, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
public async Task<IActionResult> RevokeAPIKey(string userId, string apikey)
{
if (!string.IsNullOrEmpty(apikey) &&
await _apiKeyRepository.Remove(apikey, _userManager.GetUserId(User)))
await _apiKeyRepository.Remove(apikey, userId))
return Ok();
else
return this.CreateAPIError("apikey-not-found", "This apikey does not exists");
}
private static ApiKeyData FromModel(APIKeyData data)
{
return new ApiKeyData()