From 8718d81f7aebd0e855eb06e2423521c674805b85 Mon Sep 17 00:00:00 2001 From: Robert Marshall Date: Sat, 8 May 2021 09:27:54 +0100 Subject: [PATCH] Load api keys from database. Create api keys. --- .../Controllers/ApiControllerTests.cs | 26 +++++++++++++-- .../Controllers/ApiController.cs | 11 +++++-- src/Robware.Auth/API/IApiKeys.cs | 3 +- src/Robware.Data/ApiKeyRepository.cs | 33 +++++++++++++++---- 4 files changed, 61 insertions(+), 12 deletions(-) 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