Add methods for managing API keys
This commit is contained in:
parent
84ae81d411
commit
3adef125a2
4 changed files with 174 additions and 2 deletions
|
@ -48,5 +48,129 @@ namespace Robware.Api.Auth.Tests.Controllers {
|
||||||
var controller = new ApiController(logger, apiKeyValidator, apiKeyRepository);
|
var controller = new ApiController(logger, apiKeyValidator, apiKeyRepository);
|
||||||
(await controller.Create("test")).Value.Should().BeEquivalentTo(expectedKey);
|
(await controller.Create("test")).Value.Should().BeEquivalentTo(expectedKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task List_ReturnsAllApiKeys() {
|
||||||
|
var logger = Substitute.For<ILogger<ApiController>>();
|
||||||
|
var apiKeyValidator = Substitute.For<IApiKeyValidator>();
|
||||||
|
var apiKeyRepository = Substitute.For<IApiKeys>();
|
||||||
|
|
||||||
|
var apiKeys = new[] {
|
||||||
|
new ApiKey {Name = "test1", Key = "test1", IssueTimestamp = DateTime.Now, Enabled = true},
|
||||||
|
new ApiKey {Name = "test2", Key = "test2", IssueTimestamp = DateTime.Now, Enabled = false},
|
||||||
|
new ApiKey {Name = "test3", Key = "test3", IssueTimestamp = DateTime.Now, Enabled = true}
|
||||||
|
};
|
||||||
|
|
||||||
|
apiKeyRepository.GetAll().Returns(apiKeys);
|
||||||
|
|
||||||
|
var controller = new ApiController(logger, apiKeyValidator, apiKeyRepository);
|
||||||
|
(await controller.List()).Value.Should().BeEquivalentTo(apiKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Delete_WithSuccessfulDeletion_ReturnsNoContent() {
|
||||||
|
var logger = Substitute.For<ILogger<ApiController>>();
|
||||||
|
var apiKeyValidator = Substitute.For<IApiKeyValidator>();
|
||||||
|
var apiKeyRepository = Substitute.For<IApiKeys>();
|
||||||
|
|
||||||
|
apiKeyRepository.Delete("test").Returns(true);
|
||||||
|
|
||||||
|
var controller = new ApiController(logger, apiKeyValidator, apiKeyRepository);
|
||||||
|
(await controller.Delete("test")).Should().BeOfType<NoContentResult>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Delete_WithUnsuccessfulDeletion_ReturnsBadRequest() {
|
||||||
|
var logger = Substitute.For<ILogger<ApiController>>();
|
||||||
|
var apiKeyValidator = Substitute.For<IApiKeyValidator>();
|
||||||
|
var apiKeyRepository = Substitute.For<IApiKeys>();
|
||||||
|
|
||||||
|
apiKeyRepository.Delete("test").Returns(false);
|
||||||
|
|
||||||
|
var controller = new ApiController(logger, apiKeyValidator, apiKeyRepository);
|
||||||
|
(await controller.Delete("test")).Should().BeOfType<BadRequestResult>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Disable_WithSuccessfulDisablement_ReturnsNoContent() {
|
||||||
|
var logger = Substitute.For<ILogger<ApiController>>();
|
||||||
|
var apiKeyValidator = Substitute.For<IApiKeyValidator>();
|
||||||
|
var apiKeyRepository = Substitute.For<IApiKeys>();
|
||||||
|
|
||||||
|
var apiKey = new ApiKey {
|
||||||
|
Name = "test",
|
||||||
|
Key = "test",
|
||||||
|
IssueTimestamp = DateTime.Now,
|
||||||
|
Enabled = true
|
||||||
|
};
|
||||||
|
|
||||||
|
apiKeyRepository.Get("test").Returns(apiKey);
|
||||||
|
apiKeyRepository.Update(apiKey).Returns(true);
|
||||||
|
|
||||||
|
var controller = new ApiController(logger, apiKeyValidator, apiKeyRepository);
|
||||||
|
(await controller.Disable("test")).Should().BeOfType<NoContentResult>();
|
||||||
|
apiKey.Enabled.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Disable_WithUnsuccessfulDisablement_ReturnsBadRequest() {
|
||||||
|
var logger = Substitute.For<ILogger<ApiController>>();
|
||||||
|
var apiKeyValidator = Substitute.For<IApiKeyValidator>();
|
||||||
|
var apiKeyRepository = Substitute.For<IApiKeys>();
|
||||||
|
|
||||||
|
var apiKey = new ApiKey {
|
||||||
|
Name = "test",
|
||||||
|
Key = "test",
|
||||||
|
IssueTimestamp = DateTime.Now,
|
||||||
|
Enabled = true
|
||||||
|
};
|
||||||
|
|
||||||
|
apiKeyRepository.Get("test").Returns(apiKey);
|
||||||
|
apiKeyRepository.Update(apiKey).Returns(false);
|
||||||
|
|
||||||
|
var controller = new ApiController(logger, apiKeyValidator, apiKeyRepository);
|
||||||
|
(await controller.Disable("test")).Should().BeOfType<BadRequestResult>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Enable_WithSuccessfulEnablement_ReturnsNoContent() {
|
||||||
|
var logger = Substitute.For<ILogger<ApiController>>();
|
||||||
|
var apiKeyValidator = Substitute.For<IApiKeyValidator>();
|
||||||
|
var apiKeyRepository = Substitute.For<IApiKeys>();
|
||||||
|
|
||||||
|
var apiKey = new ApiKey {
|
||||||
|
Name = "test",
|
||||||
|
Key = "test",
|
||||||
|
IssueTimestamp = DateTime.Now,
|
||||||
|
Enabled = false
|
||||||
|
};
|
||||||
|
|
||||||
|
apiKeyRepository.Get("test").Returns(apiKey);
|
||||||
|
apiKeyRepository.Update(apiKey).Returns(true);
|
||||||
|
|
||||||
|
var controller = new ApiController(logger, apiKeyValidator, apiKeyRepository);
|
||||||
|
(await controller.Enable("test")).Should().BeOfType<NoContentResult>();
|
||||||
|
apiKey.Enabled.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Enable_WithUnsuccessfulEnablement_ReturnsBadRequest() {
|
||||||
|
var logger = Substitute.For<ILogger<ApiController>>();
|
||||||
|
var apiKeyValidator = Substitute.For<IApiKeyValidator>();
|
||||||
|
var apiKeyRepository = Substitute.For<IApiKeys>();
|
||||||
|
|
||||||
|
var apiKey = new ApiKey {
|
||||||
|
Name = "test",
|
||||||
|
Key = "test",
|
||||||
|
IssueTimestamp = DateTime.Now,
|
||||||
|
Enabled = false
|
||||||
|
};
|
||||||
|
|
||||||
|
apiKeyRepository.Get("test").Returns(apiKey);
|
||||||
|
apiKeyRepository.Update(apiKey).Returns(false);
|
||||||
|
|
||||||
|
var controller = new ApiController(logger, apiKeyValidator, apiKeyRepository);
|
||||||
|
(await controller.Enable("test")).Should().BeOfType<BadRequestResult>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Robware.Auth.API;
|
using Robware.Auth.API;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Robware.Api.Auth.Controllers {
|
namespace Robware.Api.Auth.Controllers {
|
||||||
[ApiController]
|
[ApiController]
|
||||||
|
@ -24,5 +25,34 @@ namespace Robware.Api.Auth.Controllers {
|
||||||
[HttpPost(nameof(Create))]
|
[HttpPost(nameof(Create))]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public async Task<ActionResult<ApiKey>> Create(string name) => await _apiKeyRepository.Create(name);
|
public async Task<ActionResult<ApiKey>> Create(string name) => await _apiKeyRepository.Create(name);
|
||||||
|
|
||||||
|
[HttpGet(nameof(List))]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<ActionResult<ApiKey[]>> List() => (await _apiKeyRepository.GetAll()).ToArray();
|
||||||
|
|
||||||
|
[HttpDelete(nameof(Delete))]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<ActionResult> Delete(string key) => await _apiKeyRepository.Delete(key) ? (ActionResult) NoContent() : BadRequest();
|
||||||
|
|
||||||
|
private async Task<ActionResult> SetEnabled(string key, bool enabled) {
|
||||||
|
try {
|
||||||
|
var apiKey = await _apiKeyRepository.Get(key);
|
||||||
|
|
||||||
|
apiKey.Enabled = enabled;
|
||||||
|
|
||||||
|
return await _apiKeyRepository.Update(apiKey) ? (ActionResult)NoContent() : BadRequest();
|
||||||
|
}
|
||||||
|
catch (ApiKeyNotFoundException) {
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPatch(nameof(Disable))]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<ActionResult> Disable(string key) => await SetEnabled(key, false);
|
||||||
|
|
||||||
|
[HttpPatch(nameof(Enable))]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<ActionResult> Enable(string key) => await SetEnabled(key, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
using System.Threading.Tasks;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Robware.Auth.API {
|
namespace Robware.Auth.API {
|
||||||
public interface IApiKeys {
|
public interface IApiKeys {
|
||||||
Task<ApiKey> Get(string apiKey);
|
Task<ApiKey> Get(string apiKey);
|
||||||
Task<ApiKey> Create(string name);
|
Task<ApiKey> Create(string name);
|
||||||
|
Task<IEnumerable<ApiKey>> GetAll();
|
||||||
|
Task<bool> Delete(string key);
|
||||||
|
Task<bool> Update(ApiKey apiKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,6 +3,8 @@ using Robware.Auth.API;
|
||||||
using Robware.Data.ApiKeys;
|
using Robware.Data.ApiKeys;
|
||||||
using Robware.Data.ApiKeys.State;
|
using Robware.Data.ApiKeys.State;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Robware.Data {
|
namespace Robware.Data {
|
||||||
|
@ -34,5 +36,17 @@ namespace Robware.Data {
|
||||||
|
|
||||||
return apiKey;
|
return apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<ApiKey>> GetAll() => (await _collection.FindAsync(_ => true)).ToEnumerable().Select(state => new DatabaseApiKey(state));
|
||||||
|
|
||||||
|
public async Task<bool> Delete(string key) {
|
||||||
|
var deleteResult = await _collection.DeleteOneAsync(state => state.Key == key);
|
||||||
|
return deleteResult.IsAcknowledged && deleteResult.DeletedCount == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> Update(ApiKey apiKey) {
|
||||||
|
var result = await _collection.ReplaceOneAsync(state => state.Key == apiKey.Key, new ApiKeyState(apiKey));
|
||||||
|
return result.IsAcknowledged && result.ModifiedCount == 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue