diff --git a/SolarWatch/Controllers/AuthController.cs b/SolarWatch/Controllers/AuthController.cs index de68dda..de513df 100644 --- a/SolarWatch/Controllers/AuthController.cs +++ b/SolarWatch/Controllers/AuthController.cs @@ -24,6 +24,7 @@ public AuthController(IAuthService authenticationService) public async Task> RenewToken() { var token = Request.Headers["Authorization"].ToString().Replace("Bearer ", ""); + // do a validation for a valid / not blacklisted token var result = await _authenticationService.RenewTokenAsync(token); if (!result.Success) diff --git a/SolarWatch/Controllers/SolarWatchController.cs b/SolarWatch/Controllers/SolarWatchController.cs index c269ec9..a277dbe 100644 --- a/SolarWatch/Controllers/SolarWatchController.cs +++ b/SolarWatch/Controllers/SolarWatchController.cs @@ -19,7 +19,7 @@ public SolarWatchController(ILogger logger, ISolarDataServ _solarDataService = solarDataService; } - [HttpGet("GeocodingData"), /*Authorize(Roles = "User, Admin")*/] + [HttpGet("GeocodingData"), Authorize(Roles = "User, Admin")] public async Task> GetGeocodingData([Required] string location) { try @@ -35,7 +35,7 @@ public async Task> GetGeocodingData([Required] strin } - [HttpGet("SolarData"), /*Authorize(Roles = "User, Admin")*/] + [HttpGet("SolarData"), Authorize(Roles = "User, Admin")] public async Task> GetSolarData([Required] DateOnly date, [Required] string location) { try diff --git a/SolarWatch/Services/Authentication/AuthService.cs b/SolarWatch/Services/Authentication/AuthService.cs index 8511c70..dbd33a6 100644 --- a/SolarWatch/Services/Authentication/AuthService.cs +++ b/SolarWatch/Services/Authentication/AuthService.cs @@ -7,11 +7,13 @@ public class AuthService : IAuthService { private readonly UserManager _userManager; private readonly ITokenService _tokenService; + private readonly ITokenBlacklistService _tokenBlacklistService; - public AuthService(UserManager userManager, ITokenService tokenService) + public AuthService(UserManager userManager, ITokenService tokenService, ITokenBlacklistService tokenBlacklistService) { _userManager = userManager; _tokenService = tokenService; + _tokenBlacklistService = tokenBlacklistService; } public async Task RegisterAsync(string email, string username, string password, string role) @@ -92,6 +94,7 @@ private static AuthResult FailedRegistration(IdentityResult result, string email public async Task RenewTokenAsync(string token) { + var principal = _tokenService.GetPrincipalFromExpiredToken(token); if (principal == null) { @@ -111,6 +114,8 @@ public async Task RenewTokenAsync(string token) return NoRolesAssigned(user.Email, user.UserName); } + _tokenBlacklistService.AddTokenToBlacklist(token); + var newToken = _tokenService.CreateToken(user, roles[0]); // roles[0] might fail if there are more roles / user return new AuthResult(true, user.Email, user.UserName, newToken); } diff --git a/SolarWatch/SolarWatch.csproj.user b/SolarWatch/SolarWatch.csproj.user index c404400..983ecfc 100644 --- a/SolarWatch/SolarWatch.csproj.user +++ b/SolarWatch/SolarWatch.csproj.user @@ -1,7 +1,7 @@  - https + http ProjectDebugger diff --git a/SolarWatch/SolarWatch.sln.DotSettings.user b/SolarWatch/SolarWatch.sln.DotSettings.user index a310cbe..76bda7d 100644 --- a/SolarWatch/SolarWatch.sln.DotSettings.user +++ b/SolarWatch/SolarWatch.sln.DotSettings.user @@ -3,5 +3,6 @@ <TestAncestor> <TestId>NUnit3x::799DCF59-930B-4FF3-BF8D-EDF88B1AAEB7::net9.0::SolarWatchTests.SolarWatchControllerTests</TestId> <TestId>xUnit::799DCF59-930B-4FF3-BF8D-EDF88B1AAEB7::net9.0::SolarWatchTests.IntegrationTests</TestId> + <TestId>xUnit::799DCF59-930B-4FF3-BF8D-EDF88B1AAEB7::net9.0::SolarWatchTests.IntegrationTestForAuth</TestId> </TestAncestor> </SessionState> \ No newline at end of file diff --git a/SolarWatchTests/IntegrationTests.cs b/SolarWatchTests/IntegrationTests.cs index 77db92c..e15c533 100644 --- a/SolarWatchTests/IntegrationTests.cs +++ b/SolarWatchTests/IntegrationTests.cs @@ -1,6 +1,9 @@ using System; using System.Linq; +using System.Net; using System.Net.Http; +using System.Net.Http.Headers; +using System.Net.Http.Json; using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; @@ -10,17 +13,23 @@ using SolarWatch; using Microsoft.AspNetCore.Hosting; using SolarWatch.Context; +using SolarWatch.Contracts; +using SolarWatch.Controllers; +using Assert = Xunit.Assert; namespace SolarWatchTests { [Collection("IntegrationTests")] - public class IntegrationTests : IClassFixture> + public class IntegrationTestForAuth : IDisposable { private readonly string _dbName = Guid.NewGuid().ToString(); - private readonly HttpClient _client; + public HttpClient Client { get; } + public string Token { get; private set; } - public IntegrationTests(WebApplicationFactory factory) + public IntegrationTestForAuth() { + var factory = new WebApplicationFactory(); + var webAppFactory = factory.WithWebHostBuilder(builder => { builder.UseEnvironment("Test"); @@ -52,9 +61,45 @@ public IntegrationTests(WebApplicationFactory factory) }); }); - _client = webAppFactory.CreateClient(); + Client = webAppFactory.CreateClient(); + RegisterTestUser().GetAwaiter().GetResult(); // register a new user before tests for [Authorize] to work + } + + private async Task RegisterTestUser() + { + var newUser = new RegistrationRequest("testuser@test.com", "testuser", "testuser"); + var response = await Client.PostAsJsonAsync("/Auth/Register", newUser); + response.EnsureSuccessStatusCode(); + + var login = await Client.PostAsJsonAsync("/Auth/Login", new AuthController.AuthRequest("testuser@test.com", "testuser")); + var token = await login.Content.ReadFromJsonAsync(); + Token = token.Token; + + Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Token); + } + + public void Dispose() => Client.Dispose(); + } + + public class IntegrationTests : IClassFixture + { + + private readonly HttpClient _client; + + public IntegrationTests(IntegrationTestForAuth setupAuth) + { + _client = setupAuth.Client; + _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", setupAuth.Token); } + [Fact] + public async Task LoginTest() + { + + var testEndpoint = await _client.GetAsync("/Auth/testUser"); + + Assert.Equal(HttpStatusCode.OK, testEndpoint.StatusCode); + } [Fact] public async Task GetGeocodingData_ValidLocation_ReturnsOk() diff --git a/SolarWatch_Frontend/vite.config.js b/SolarWatch_Frontend/vite.config.js index b9261d1..699c028 100644 --- a/SolarWatch_Frontend/vite.config.js +++ b/SolarWatch_Frontend/vite.config.js @@ -8,7 +8,7 @@ export default defineConfig({ port: 3000, proxy: { '/api': { - target: process.env.VITE_API_BASE_URL,// || 'https://localhost:7119', // remove .env file and it will work + target: /* process.env.VITE_API_BASE_URL */ 'http://localhost:5158', // remove .env file and it will work changeOrigin: true, secure: false, // DO NOT USE IN PRODUCTION. GET A VALID SSL CERTIFICATE rewrite: (path) => path.replace(/^\/api/, '')