diff --git a/backend/src/Designer/Controllers/AnsattPortenController.cs b/backend/src/Designer/Controllers/AnsattPortenController.cs index 8feff836cf4..868fbb28240 100644 --- a/backend/src/Designer/Controllers/AnsattPortenController.cs +++ b/backend/src/Designer/Controllers/AnsattPortenController.cs @@ -30,7 +30,6 @@ public async Task Login([FromQuery(Name = "redirect_to")] string [HttpGet("auth-status")] public async Task AuthStatus() { - await Task.CompletedTask; var authenticateResult = await authService.AuthenticateAsync(HttpContext, AnsattPortenConstants.AnsattportenAuthenticationScheme); diff --git a/backend/src/Designer/Controllers/AppScopesController.cs b/backend/src/Designer/Controllers/AppScopesController.cs index 4e8d88e0f87..474157c14da 100644 --- a/backend/src/Designer/Controllers/AppScopesController.cs +++ b/backend/src/Designer/Controllers/AppScopesController.cs @@ -17,7 +17,6 @@ namespace Altinn.Studio.Designer.Controllers; [FeatureGate(StudioFeatureFlags.AnsattPorten)] [Route("designer/api/{org}/{app:regex(^(?!datamodels$)[[a-z]][[a-z0-9-]]{{1,28}}[[a-z0-9]]$)}/app-scopes")] - public class AppScopesController(IMaskinPortenHttpClient maskinPortenHttpClient, IAppScopesService appScopesService) : ControllerBase { diff --git a/backend/tests/Designer.Tests/Controllers/AnsattPortenController/AuthStatusTests.cs b/backend/tests/Designer.Tests/Controllers/AnsattPortenController/AuthStatusTests.cs new file mode 100644 index 00000000000..7097a351233 --- /dev/null +++ b/backend/tests/Designer.Tests/Controllers/AnsattPortenController/AuthStatusTests.cs @@ -0,0 +1,81 @@ +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Altinn.Studio.Designer.Models.Dto; +using Designer.Tests.Controllers.ApiTests; +using FluentAssertions; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.Mvc.Testing.Handlers; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace Designer.Tests.Controllers.AnsattPortenController; + +public class AuthStatusTest : DesignerEndpointsTestsBase, IClassFixture> +{ + private static string VersionPrefix => "/designer/api/ansattporten/auth-status"; + + // Setup unauthenticated http client + protected override HttpClient GetTestClient() + { + string configPath = GetConfigPath(); + IConfiguration configuration = new ConfigurationBuilder() + .AddJsonFile(configPath, false, false) + .AddJsonStream(GenerateJsonOverrideConfig()) + .AddEnvironmentVariables() + .Build(); + + return Factory.WithWebHostBuilder(builder => + { + builder.UseConfiguration(configuration); + builder.ConfigureAppConfiguration((_, conf) => + { + conf.AddJsonFile(configPath); + conf.AddJsonStream(GenerateJsonOverrideConfig()); + }); + builder.ConfigureTestServices(ConfigureTestServices); + builder.ConfigureServices(ConfigureTestServicesForSpecificTest); + }).CreateDefaultClient(new ApiTestsAuthAndCookieDelegatingHandler(), new CookieContainerHandler()); + } + + public AuthStatusTest(WebApplicationFactory factory) : base(factory) + { + } + + [Fact] + public async Task AuthStatus_Should_ReturnFalse_IfNotAuthenticated() + { + using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, VersionPrefix); + + using var response = await HttpClient.SendAsync(httpRequestMessage); + response.StatusCode.Should().Be(HttpStatusCode.OK); + + AuthStatus authStatus = await response.Content.ReadAsAsync(); + authStatus.IsLoggedIn.Should().BeFalse(); + } + + [Fact] + public async Task AuthStatus_Should_ReturnTrue_IfAuthenticated() + { + // Setup test authentication + ConfigureTestServicesForSpecificTest = services => + { + services.AddAuthentication(defaultScheme: TestAuthConstants.TestAuthenticationScheme) + .AddScheme( + TestAuthConstants.TestAuthenticationScheme, options => { }); + services.AddTransient(); + }; + + using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, VersionPrefix); + + using var response = await HttpClient.SendAsync(httpRequestMessage); + response.StatusCode.Should().Be(HttpStatusCode.OK); + + AuthStatus authStatus = await response.Content.ReadAsAsync(); + authStatus.IsLoggedIn.Should().BeTrue(); + } +} diff --git a/backend/tests/Designer.Tests/Controllers/AnsattPortenController/LoginTests.cs b/backend/tests/Designer.Tests/Controllers/AnsattPortenController/LoginTests.cs new file mode 100644 index 00000000000..1d928cf2b29 --- /dev/null +++ b/backend/tests/Designer.Tests/Controllers/AnsattPortenController/LoginTests.cs @@ -0,0 +1,48 @@ +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Altinn.Studio.Designer.Constants; +using Designer.Tests.Controllers.ApiTests; +using Microsoft.AspNetCore.Mvc.Testing; +using Xunit; + +namespace Designer.Tests.Controllers.AnsattPortenController; + +public class LoginTests : DesignerEndpointsTestsBase, IClassFixture> +{ + private static string VersionPrefix => "/designer/api/ansattporten/login"; + + public LoginTests(WebApplicationFactory factory) : base(factory) + { + JsonConfigOverrides.Add( + $$""" + { + "FeatureManagement": { + "{{StudioFeatureFlags.AnsattPorten}}": true + }, + "AnsattPortenLoginSettings": { + "ClientId": "non-empty-for-testing", + "ClientSecret": "non-empty-for-testing" + } + } + """); + } + + [Theory] + [InlineData("/test", HttpStatusCode.Redirect)] + [InlineData("/", HttpStatusCode.Redirect)] + [InlineData("https://docs.altinn.studio/", HttpStatusCode.Forbidden)] + public async Task LoginShouldReturn_ExpectedCode(string redirectTo, HttpStatusCode expectedStatusCode) + { + using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get + , $"{VersionPrefix}?redirect_to={redirectTo}"); + + using var response = await HttpClient.SendAsync(httpRequestMessage); + Assert.Equal(expectedStatusCode, response.StatusCode); + + if (expectedStatusCode == HttpStatusCode.Redirect) + { + Assert.Equal(redirectTo, response.Headers.Location?.ToString()); + } + } +} diff --git a/backend/tests/Designer.Tests/Controllers/ApiTests/ApiTestsBase.cs b/backend/tests/Designer.Tests/Controllers/ApiTests/ApiTestsBase.cs index 109345e8f49..7b03c34ac9e 100644 --- a/backend/tests/Designer.Tests/Controllers/ApiTests/ApiTestsBase.cs +++ b/backend/tests/Designer.Tests/Controllers/ApiTests/ApiTestsBase.cs @@ -44,7 +44,7 @@ protected HttpClient HttpClient /// protected abstract void ConfigureTestServices(IServiceCollection services); - protected Action ConfigureTestForSpecificTest { get; set; } = delegate { }; + protected Action ConfigureTestServicesForSpecificTest { get; set; } = delegate { }; /// /// Location of the assembly of the executing unit test. @@ -97,7 +97,7 @@ protected virtual HttpClient GetTestClient() TestAuthConstants.TestAuthenticationScheme, options => { }); services.AddTransient(); }); - builder.ConfigureServices(ConfigureTestForSpecificTest); + builder.ConfigureServices(ConfigureTestServicesForSpecificTest); }).CreateDefaultClient(new ApiTestsAuthAndCookieDelegatingHandler(), new CookieContainerHandler()); } @@ -152,7 +152,7 @@ private void InitializeJsonConfigOverrides() } - private Stream GenerateJsonOverrideConfig() + protected Stream GenerateJsonOverrideConfig() { var overrideJson = Newtonsoft.Json.Linq.JObject.Parse(JsonConfigOverrides.First()); if (JsonConfigOverrides.Count > 1) diff --git a/backend/tests/Designer.Tests/Controllers/AppScopesController/Base/AppScopesControllerTestsBase.cs b/backend/tests/Designer.Tests/Controllers/AppScopesController/Base/AppScopesControllerTestsBase.cs index 4e6e468ae06..0398fe48dea 100644 --- a/backend/tests/Designer.Tests/Controllers/AppScopesController/Base/AppScopesControllerTestsBase.cs +++ b/backend/tests/Designer.Tests/Controllers/AppScopesController/Base/AppScopesControllerTestsBase.cs @@ -1,3 +1,4 @@ +using Altinn.Studio.Designer.Constants; using Designer.Tests.Controllers.ApiTests; using Designer.Tests.Fixtures; using Microsoft.AspNetCore.Mvc.Testing; @@ -9,16 +10,17 @@ public class AppScopesControllerTestsBase : DbDesignerEndpoints { public AppScopesControllerTestsBase(WebApplicationFactory factory, DesignerDbFixture designerDbFixture) : base(factory, designerDbFixture) { - JsonConfigOverrides.Add($@" - {{ - ""FeatureManagement"": {{ - ""AnsattPorten"": true - }}, - ""AnsattPortenLoginSettings"": {{ - ""ClientId"": ""non-empty-for-testing"", - ""ClientSecret"": ""non-empty-for-testing"" - }} - }} - "); + JsonConfigOverrides.Add( + $$""" + { + "FeatureManagement": { + "{{StudioFeatureFlags.AnsattPorten}}": true + }, + "AnsattPortenLoginSettings": { + "ClientId": "non-empty-for-testing", + "ClientSecret": "non-empty-for-testing" + } + } + """); } } diff --git a/backend/tests/Designer.Tests/Controllers/PreviewController/GetImageTests.cs b/backend/tests/Designer.Tests/Controllers/PreviewController/GetImageTests.cs index afcc096ffcc..e314dfb04bb 100644 --- a/backend/tests/Designer.Tests/Controllers/PreviewController/GetImageTests.cs +++ b/backend/tests/Designer.Tests/Controllers/PreviewController/GetImageTests.cs @@ -84,7 +84,7 @@ public async Task Get_Image_Non_Existing_Image_Return_NotFound() public async Task Call_To_Get_Designer_Iframe_Does_Not_Hit_Image_EndPoint() { Mock factMock = new(); - ConfigureTestForSpecificTest = s => + ConfigureTestServicesForSpecificTest = s => { s.AddTransient(_ => factMock.Object); };