diff --git a/src/Robware.Api.Auth.Tests/Controllers/ApiControllerTests.cs b/src/Robware.Api.Auth.Tests/Controllers/ApiControllerTests.cs index 3a497e7..390f745 100644 --- a/src/Robware.Api.Auth.Tests/Controllers/ApiControllerTests.cs +++ b/src/Robware.Api.Auth.Tests/Controllers/ApiControllerTests.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging; using NSubstitute; using Robware.Api.Auth.Controllers; using Robware.Auth.API; +using System; using Xunit; namespace Robware.Api.Auth.Tests.Controllers { @@ -14,7 +15,8 @@ namespace Robware.Api.Auth.Tests.Controllers { var logger = Substitute.For>(); var apiKeyValidator = Substitute.For(); apiKeyValidator.Validate("key").Returns(true); - var controller = new ApiController(logger, apiKeyValidator); + var apiKeyRepository = Substitute.For(); + var controller = new ApiController(logger, apiKeyValidator, apiKeyRepository); (await controller.Validate("key")).Should().BeOfType(); } @@ -23,8 +25,28 @@ namespace Robware.Api.Auth.Tests.Controllers { var logger = Substitute.For>(); var apiKeyValidator = Substitute.For(); apiKeyValidator.Validate("key").Returns(false); - var controller = new ApiController(logger, apiKeyValidator); + var apiKeyRepository = Substitute.For(); + var controller = new ApiController(logger, apiKeyValidator, apiKeyRepository); (await controller.Validate("key")).Should().BeOfType(); } + + [Fact] + public async Task Create_WithName_ReturnsApiKeyJson() { + var logger = Substitute.For>(); + var apiKeyValidator = Substitute.For(); + var apiKeyRepository = Substitute.For(); + + var expectedKey = new ApiKey { + Name = "test", + Key = "test", + IssueTimestamp = DateTime.Now, + Enabled = true + }; + + apiKeyRepository.Create("test").Returns(expectedKey); + + var controller = new ApiController(logger, apiKeyValidator, apiKeyRepository); + controller.Create("test").Result.Value.Should().BeEquivalentTo(expectedKey); + } } } \ No newline at end of file diff --git a/src/Robware.Api.Auth/Controllers/ApiController.cs b/src/Robware.Api.Auth/Controllers/ApiController.cs index db528d2..3258ee5 100644 --- a/src/Robware.Api.Auth/Controllers/ApiController.cs +++ b/src/Robware.Api.Auth/Controllers/ApiController.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Robware.Auth.API; @@ -9,13 +10,19 @@ namespace Robware.Api.Auth.Controllers { public class ApiController : ControllerBase { private readonly ILogger _logger; private readonly IApiKeyValidator _apiKeyValidator; + private readonly IApiKeys _apiKeyRepository; - public ApiController(ILogger logger, IApiKeyValidator apiKeyValidator) { + public ApiController(ILogger logger, IApiKeyValidator apiKeyValidator, IApiKeys apiKeyRepository) { _logger = logger; _apiKeyValidator = apiKeyValidator; + _apiKeyRepository = apiKeyRepository; } [HttpGet(nameof(Validate))] public async Task Validate(string key) => await _apiKeyValidator.Validate(key) ? (ActionResult) Ok() : Unauthorized(); + + [HttpPost(nameof(Create))] + [Authorize] + public async Task> Create(string name) => await _apiKeyRepository.Create(name); } } diff --git a/src/Robware.Auth/API/IApiKeys.cs b/src/Robware.Auth/API/IApiKeys.cs index a4a962d..45ab091 100644 --- a/src/Robware.Auth/API/IApiKeys.cs +++ b/src/Robware.Auth/API/IApiKeys.cs @@ -2,6 +2,7 @@ namespace Robware.Auth.API { public interface IApiKeys { - Task Get(string key); + Task Get(string apiKey); + Task Create(string name); } } \ No newline at end of file diff --git a/src/Robware.Data/ApiKeyRepository.cs b/src/Robware.Data/ApiKeyRepository.cs index 8174ecd..eba493b 100644 --- a/src/Robware.Data/ApiKeyRepository.cs +++ b/src/Robware.Data/ApiKeyRepository.cs @@ -1,19 +1,38 @@ +using MongoDB.Driver; using Robware.Auth.API; +using Robware.Data.ApiKeys; +using Robware.Data.ApiKeys.State; using System; using System.Threading.Tasks; namespace Robware.Data { public class ApiKeyRepository : IApiKeys { - public async Task Get(string key) { - if (key=="denied") - throw new ApiKeyNotFoundException(key); - - return new ApiKey { - Name = "Hardcoded key", - Key = key, + private readonly IMongoCollection _collection; + + public ApiKeyRepository(IMongoDatabase database) { + _collection = database.GetCollection("api-keys"); + } + + public async Task Get(string apiKey) { + var result = (await _collection.FindAsync(key => key.Key == apiKey)).FirstOrDefault(); + + if (result == null) + throw new ApiKeyNotFoundException(apiKey); + + return new DatabaseApiKey(result); + } + + public async Task Create(string name) { + var apiKey = new ApiKey { + Name = name, + Key = Guid.NewGuid().ToString(), Enabled = true, IssueTimestamp = DateTime.Now }; + + await _collection.InsertOneAsync(new ApiKeyState(apiKey)); + + return apiKey; } } } \ No newline at end of file