Skip to content
Snippets Groups Projects
Select Git revision
  • d2666fc1eb5a87e0c0ae693bdb09675cef8b31c0
  • main default protected
  • release
  • OZG-8252-gitlab-pipeline
  • OZG-7774-E2E
  • OZG-5120-PoC-Native-Image
  • 1.11.0
  • 1.10.0
  • 1.9.0
  • 1.8.0
  • 1.7.0
  • 1.6.0
  • 1.5.0
  • 1.4.0
  • 1.3.0
  • 1.2.1
  • 1.2.0
  • 1.1.1
  • 1.1.0
  • 1.0.0
  • 0.8.0
  • 0.7.0
  • 0.6.0
  • 0.5.0
  • 0.4.0
  • 0.3.0
26 results

SecurityConfigurationITCase.java

Blame
  • user avatar
    OZGCloud authored
    d2666fc1
    History
    SecurityConfigurationITCase.java 4.35 KiB
    /*
     * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur
     * Zentrales IT-Management
     *
     * Lizenziert unter der EUPL, Version 1.2 oder - sobald
     * diese von der Europäischen Kommission genehmigt wurden -
     * Folgeversionen der EUPL ("Lizenz");
     * Sie dürfen dieses Werk ausschließlich gemäß
     * dieser Lizenz nutzen.
     * Eine Kopie der Lizenz finden Sie hier:
     *
     * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
     *
     * Sofern nicht durch anwendbare Rechtsvorschriften
     * gefordert oder in schriftlicher Form vereinbart, wird
     * die unter der Lizenz verbreitete Software "so wie sie
     * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
     * ausdrücklich oder stillschweigend - verbreitet.
     * Die sprachspezifischen Genehmigungen und Beschränkungen
     * unter der Lizenz sind dem Lizenztext zu entnehmen.
     */
    package de.ozgcloud.admin.security;
    
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
    
    import org.apache.http.HttpHeaders;
    import org.junit.jupiter.api.DisplayName;
    import org.junit.jupiter.api.Nested;
    import org.junit.jupiter.api.Test;
    import org.junit.jupiter.params.ParameterizedTest;
    import org.junit.jupiter.params.provider.ValueSource;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
    import org.springframework.http.HttpStatus;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.ResultActions;
    
    import de.ozgcloud.common.test.DataITCase;
    import lombok.SneakyThrows;
    
    @DataITCase
    @AutoConfigureMockMvc
    class SecurityConfigurationITCase {
    
    	@Autowired
    	private MockMvc mockMvc;
    
    	@DisplayName("without authorization")
    	@Nested
    	class TestWithoutAuthorization {
    
    		@DisplayName("allow for not found")
    		@SneakyThrows
    		@ParameterizedTest
    		@ValueSource(strings = {
    				"/actuator", "/actuator/x", "/actuator/x/y",
    				"/configserver", "/configserver/x",
    		})
    		void shouldAllowForNotFound(String path) {
    			var result = doPerform(path);
    
    			result.andExpect(status().isNotFound());
    		}
    
    		@DisplayName("allow")
    		@SneakyThrows
    		@ParameterizedTest
    		@ValueSource(strings = {
    				"/api/environment",
    				"/configserver/name/profile"
    		})
    		void shouldAllow(String path) {
    			var result = doPerform(path);
    
    			result.andExpect(status().isOk());
    		}
    
    		@SneakyThrows
    		@ParameterizedTest
    		@ValueSource(strings = {
    				"/api", "/api/configuration", "/api/configuration/param",
    				"/unknown",
    		})
    		void shouldDeny(String path) {
    			var result = doPerform(path);
    
    			result.andExpect(status().isUnauthorized());
    		}
    
    		@DisplayName("deny with problem details")
    		@Nested
    		class TestDenyWithProblemDetails {
    
    			@SneakyThrows
    			@Test
    			void shouldHaveStatus() {
    				var result = doPerform("/api");
    
    				result.andExpect(jsonPath("$.status").value(HttpStatus.UNAUTHORIZED.value()));
    			}
    
    			@SneakyThrows
    			@Test
    			void shouldHaveInstanceURI() {
    				var result = doPerform("/api");
    
    				result.andExpect(jsonPath("$.instance").value("/api"));
    			}
    
    			@Test
    			@SneakyThrows
    			void shouldHaveErrorDetailInBody() {
    				var result = doPerform("/api");
    
    				result.andExpect(jsonPath("$.detail").value("Full authentication is required to access this resource"));
    
    			}
    
    			@Test
    			@SneakyThrows
    			void shouldHaveHeader() {
    				var result = doPerform("/api");
    
    				result.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Bearer realm=\"Restricted Content\""));
    			}
    		}
    
    		@SneakyThrows
    		private ResultActions doPerform(String path) {
    			return mockMvc.perform(get(path).header("Authorization", "invalid"));
    		}
    	}
    
    	@DisplayName("with authorization")
    	@Nested
    	class TestWithAuthorization {
    
    		static final String CLAIMS = """
    				{
    				  "preferredUsername": "testUser",
    				  "scope": "openid testscope"
    				}""";
    
    		@SneakyThrows
    		@ParameterizedTest
    		@ValueSource(strings = {
    				"/api/environment",
    				"/configserver/name/profile",
    				"/api", "/api/configuration", "/api/configuration/param",
    		})
    		@WithJwt(CLAIMS)
    		void shouldAllow(String path) {
    			var result = doPerformAuthenticated(path);
    
    			result.andExpect(status().isOk());
    		}
    
    		@SneakyThrows
    		private ResultActions doPerformAuthenticated(String path) {
    			return mockMvc.perform(get(path));
    		}
    	}
    }