Skip to content
Snippets Groups Projects
Commit 77fe315e authored by Tobias Bruns's avatar Tobias Bruns
Browse files

Merge remote-tracking branch 'origin/main' into OZG-6988_add_reporting

parents a9d8f751 ddd28973
No related branches found
No related tags found
1 merge request!3Ozg 6988 add reporting
...@@ -32,9 +32,11 @@ import lombok.Setter; ...@@ -32,9 +32,11 @@ import lombok.Setter;
@Setter @Setter
@Getter @Getter
@Configuration @Configuration
@ConfigurationProperties(prefix = "ozgcloud.feature") @ConfigurationProperties(prefix = FeatureToggleProperties.FEATURE_TOGGLE_PREFIX)
public class FeatureToggleProperties { public class FeatureToggleProperties {
public static final String FEATURE_TOGGLE_PREFIX = "ozgcloud.feature";
private boolean postfach; private boolean postfach;
private boolean benutzerRollen; private boolean benutzerRollen;
private boolean organisationsEinheiten; private boolean organisationsEinheiten;
......
/*
* Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* 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.keycloak;
import java.util.Map;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.RepresentationModelProcessor;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
import de.ozgcloud.admin.Root;
import de.ozgcloud.admin.common.FeatureToggleProperties;
import de.ozgcloud.admin.common.user.CurrentUserService;
import de.ozgcloud.admin.common.user.UserRole;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = FeatureToggleProperties.FEATURE_TOGGLE_PREFIX, name = "benutzer-rollen", havingValue = "true")
class KeyCloakRootProcessor implements RepresentationModelProcessor<EntityModel<Root>> {
private static final String KEYCLOAK_API_TEMPLATE = "{baseUrl}/admin/realms/{realm}/users";
private static final String BASE_URL_KEY = "baseUrl";
private static final String REALM_KEY = "realm";
public static final String REL_USERS = "users";
private final KeycloakApiProperties keycloakApiProperties;
private final CurrentUserService currentUserService;
@Override
public EntityModel<Root> process(EntityModel<Root> model) {
return model.addIf(currentUserService.hasRole(UserRole.ADMIN_ADMIN), () -> Link.of(buildUsersHref(), REL_USERS));
}
String buildUsersHref() {
Map<String, Object> pathVariableMap = Map.of(BASE_URL_KEY, keycloakApiProperties.getUrl(), REALM_KEY, keycloakApiProperties.getRealm());
return UriComponentsBuilder.fromUriString(KEYCLOAK_API_TEMPLATE).uriVariables(pathVariableMap)
.build().toUriString();
}
}
/*
* Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* 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.keycloak;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import de.ozgcloud.common.test.ITCase;
class KeyCloakRootProcessorITCase {
@Nested
@SpringBootTest(properties = {
"ozgcloud.feature.benutzer-rollen=true"
})
@ITCase
class TestFeatureEnabled {
@Autowired
private ApplicationContext applicationContext;
@Test
void shouldHaveKeyCloakRootProcessorBean() {
assertDoesNotThrow(() -> applicationContext.getBean(KeyCloakRootProcessor.class));
}
}
@Nested
@SpringBootTest(properties = {
"ozgcloud.feature.benutzer-rollen=false"
})
@ITCase
class TestFeatureDisabled {
@Autowired
private ApplicationContext applicationContext;
@Test
void shouldHaveKeyCloakRootProcessorBean() {
assertThrows(NoSuchBeanDefinitionException.class, () -> applicationContext.getBean(KeyCloakRootProcessor.class));
}
}
}
\ No newline at end of file
/*
* Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* 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.keycloak;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import com.thedeanda.lorem.LoremIpsum;
import de.ozgcloud.admin.Root;
import de.ozgcloud.admin.RootTestFactory;
import de.ozgcloud.admin.common.user.CurrentUserService;
import de.ozgcloud.admin.common.user.UserRole;
class KeyCloakRootProcessorTest {
@InjectMocks
@Spy
private KeyCloakRootProcessor processor;
@Mock
private CurrentUserService currentUserService;
@Mock
private KeycloakApiProperties keycloakApiProperties;
@Nested
class TestProcess {
private final String href = LoremIpsum.getInstance().getUrl();
@Test
void shouldCheckUserRole() {
processModel();
verify(currentUserService).hasRole(UserRole.ADMIN_ADMIN);
}
@Nested
class TestOnAdminRole {
@BeforeEach
void givenHasAdminRole() {
when(currentUserService.hasRole(anyString())).thenReturn(true);
doReturn(href).when(processor).buildUsersHref();
}
@Test
void shouldCallBuildUsersHref() {
processModel();
verify(processor).buildUsersHref();
}
@Test
void shouldAddUsersLink() {
var model = processModel();
assertThat(model.getLink(KeyCloakRootProcessor.REL_USERS)).isNotEmpty();
}
@Test
void shouldSetHref() {
var model = processModel();
assertThat(model.getLink(KeyCloakRootProcessor.REL_USERS))
.get()
.extracting(Link::getHref)
.isEqualTo(href);
}
}
@Nested
class TestOnWrongUserRole {
@BeforeEach
void givenHasWrongRole() {
when(currentUserService.hasRole(anyString())).thenReturn(false);
}
@Test
void shouldNotAddAnyLinks() {
var model = processModel();
assertThat(model.getLinks()).isEmpty();
}
}
private EntityModel<Root> processModel() {
return processor.process(EntityModel.of(RootTestFactory.create()));
}
}
@Nested
class TestBuildUsersHref {
private final String baseUrl = "https://keycloak.domain.de";
private final String realm = LoremIpsum.getInstance().getWords(1);
@BeforeEach
void mockProperties() {
when(keycloakApiProperties.getUrl()).thenReturn(baseUrl);
when(keycloakApiProperties.getRealm()).thenReturn(realm);
}
@Test
void shouldGetKeyCloakUrl() {
processor.buildUsersHref();
verify(keycloakApiProperties).getUrl();
}
@Test
void shouldGetKeyCloakRealm() {
processor.buildUsersHref();
verify(keycloakApiProperties).getRealm();
}
@Test
void shouldReturnApiEndpoint() {
var uriString = processor.buildUsersHref();
assertThat(uriString).isEqualTo(baseUrl + "/admin/realms/" + realm + "/users");
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment