Skip to content

Commit 1c358bd

Browse files
committed
BE: RBAC: Add integration test for Active Directory auth
1 parent bacf1b4 commit 1c358bd

File tree

3 files changed

+208
-0
lines changed

3 files changed

+208
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package io.kafbat.ui;
2+
3+
import static io.kafbat.ui.AbstractIntegrationTest.LOCAL;
4+
import static io.kafbat.ui.container.ActiveDirectoryContainer.DOMAIN;
5+
import static io.kafbat.ui.container.ActiveDirectoryContainer.FIRST_USER_WITH_GROUP;
6+
import static io.kafbat.ui.container.ActiveDirectoryContainer.PASSWORD;
7+
import static io.kafbat.ui.container.ActiveDirectoryContainer.SECOND_USER_WITH_GROUP;
8+
import static io.kafbat.ui.container.ActiveDirectoryContainer.USER_WITHOUT_GROUP;
9+
import static org.junit.jupiter.api.Assertions.assertEquals;
10+
import static org.junit.jupiter.api.Assertions.assertFalse;
11+
import static org.junit.jupiter.api.Assertions.assertNotNull;
12+
import static org.junit.jupiter.api.Assertions.assertTrue;
13+
14+
import io.kafbat.ui.container.ActiveDirectoryContainer;
15+
import io.kafbat.ui.model.AuthenticationInfoDTO;
16+
import io.kafbat.ui.model.ResourceTypeDTO;
17+
import io.kafbat.ui.model.UserPermissionDTO;
18+
import java.util.List;
19+
import java.util.Objects;
20+
import org.jetbrains.annotations.NotNull;
21+
import org.junit.jupiter.api.AfterAll;
22+
import org.junit.jupiter.api.BeforeAll;
23+
import org.junit.jupiter.api.Test;
24+
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
26+
import org.springframework.boot.test.context.SpringBootTest;
27+
import org.springframework.context.ApplicationContextInitializer;
28+
import org.springframework.context.ConfigurableApplicationContext;
29+
import org.springframework.http.MediaType;
30+
import org.springframework.test.context.ActiveProfiles;
31+
import org.springframework.test.context.ContextConfiguration;
32+
import org.springframework.test.web.reactive.server.WebTestClient;
33+
import org.springframework.web.reactive.function.BodyInserters;
34+
35+
@SpringBootTest
36+
@ActiveProfiles("rbac-ad")
37+
@AutoConfigureWebTestClient(timeout = "60000")
38+
@ContextConfiguration(initializers = {ActiveDirectoryIntegrationTest.Initializer.class})
39+
public class ActiveDirectoryIntegrationTest {
40+
private static final String SESSION = "SESSION";
41+
42+
private static final ActiveDirectoryContainer ACTIVE_DIRECTORY = new ActiveDirectoryContainer();
43+
44+
@Autowired
45+
private WebTestClient webTestClient;
46+
47+
@BeforeAll
48+
public static void setup() {
49+
ACTIVE_DIRECTORY.start();
50+
}
51+
52+
@AfterAll
53+
public static void shutdown() {
54+
ACTIVE_DIRECTORY.stop();
55+
}
56+
57+
@Test
58+
public void testUserPermissions() {
59+
AuthenticationInfoDTO info = authenticationInfo(FIRST_USER_WITH_GROUP);
60+
61+
assertNotNull(info);
62+
assertTrue(info.getRbacEnabled());
63+
64+
List<UserPermissionDTO> permissions = info.getUserInfo().getPermissions();
65+
66+
assertFalse(permissions.isEmpty());
67+
assertTrue(permissions.stream().anyMatch(permission ->
68+
permission.getClusters().contains(LOCAL) && permission.getResource() == ResourceTypeDTO.TOPIC));
69+
assertEquals(permissions, authenticationInfo(SECOND_USER_WITH_GROUP).getUserInfo().getPermissions());
70+
}
71+
72+
@Test
73+
public void testEmptyPermissions() {
74+
assertTrue(Objects.requireNonNull(authenticationInfo(USER_WITHOUT_GROUP))
75+
.getUserInfo()
76+
.getPermissions()
77+
.isEmpty()
78+
);
79+
}
80+
81+
private String session(String name) {
82+
return Objects.requireNonNull(
83+
webTestClient
84+
.post()
85+
.uri("/login")
86+
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
87+
.body(BodyInserters.fromFormData("username", name).with("password", PASSWORD))
88+
.exchange()
89+
.expectStatus()
90+
.isFound()
91+
.returnResult(String.class)
92+
.getResponseCookies()
93+
.getFirst(SESSION))
94+
.getValue();
95+
}
96+
97+
private AuthenticationInfoDTO authenticationInfo(String name) {
98+
return webTestClient
99+
.get()
100+
.uri("/api/authorization")
101+
.cookie(SESSION, session(name))
102+
.exchange()
103+
.expectStatus()
104+
.isOk()
105+
.returnResult(AuthenticationInfoDTO.class)
106+
.getResponseBody()
107+
.blockFirst();
108+
}
109+
110+
public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
111+
@Override
112+
public void initialize(@NotNull ConfigurableApplicationContext context) {
113+
System.setProperty("spring.ldap.urls", ACTIVE_DIRECTORY.getLdapUrl());
114+
System.setProperty("oauth2.ldap.activeDirectory", "true");
115+
System.setProperty("oauth2.ldap.activeDirectory.domain", DOMAIN);
116+
}
117+
}
118+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package io.kafbat.ui.container;
2+
3+
import com.github.dockerjava.api.command.InspectContainerResponse;
4+
import java.io.IOException;
5+
import lombok.extern.slf4j.Slf4j;
6+
import org.testcontainers.containers.GenericContainer;
7+
import org.testcontainers.utility.DockerImageName;
8+
9+
@Slf4j
10+
public class ActiveDirectoryContainer extends GenericContainer<ActiveDirectoryContainer> {
11+
public static final String DOMAIN = "corp.kafbat.io";
12+
public static final String PASSWORD = "StrongPassword123";
13+
public static final String FIRST_USER_WITH_GROUP = "JohnDoe";
14+
public static final String SECOND_USER_WITH_GROUP = "JohnWick";
15+
public static final String USER_WITHOUT_GROUP = "JackSmith";
16+
17+
private static final String DOMAIN_DC = "dc=corp,dc=kafbat,dc=io";
18+
private static final String GROUP = "group";
19+
private static final String TEST_GROUP = "test-AD-Group";
20+
private static final String DOMAIN_EMAIL = "kafbat.io";
21+
private static final String SAMBA_TOOL = "samba-tool";
22+
private static final int LDAP_PORT = 389;
23+
private static final DockerImageName IMAGE_NAME = DockerImageName.parse("nowsci/samba-domain:latest");
24+
25+
public ActiveDirectoryContainer() {
26+
super(IMAGE_NAME);
27+
28+
withExposedPorts(LDAP_PORT);
29+
30+
withEnv("DOMAIN", DOMAIN);
31+
withEnv("DOMAIN_DC", DOMAIN_DC);
32+
withEnv("DOMAIN_EMAIL", DOMAIN_EMAIL);
33+
withEnv("DOMAINPASS", PASSWORD);
34+
withEnv("NOCOMPLEXITY", "true");
35+
withEnv("INSECURELDAP", "true");
36+
37+
withPrivilegedMode(true);
38+
}
39+
40+
protected void containerIsStarted(InspectContainerResponse containerInfo) {
41+
createUser(USER_WITHOUT_GROUP);
42+
createUser(FIRST_USER_WITH_GROUP);
43+
createUser(SECOND_USER_WITH_GROUP);
44+
45+
exec(SAMBA_TOOL, GROUP, "add", TEST_GROUP);
46+
exec(SAMBA_TOOL, GROUP, "addmembers", TEST_GROUP, FIRST_USER_WITH_GROUP);
47+
exec(SAMBA_TOOL, GROUP, "addmembers", TEST_GROUP, SECOND_USER_WITH_GROUP);
48+
}
49+
50+
public String getLdapUrl() {
51+
return String.format("ldap://%s:%s", getHost(), getMappedPort(LDAP_PORT));
52+
}
53+
54+
private void createUser(String name) {
55+
exec(SAMBA_TOOL, "user", "create", name, PASSWORD, "--mail-address", name + '@' + DOMAIN_EMAIL);
56+
exec(SAMBA_TOOL, "user", "setexpiry", name, "--noexpiry");
57+
}
58+
59+
private void exec(String... cmd) {
60+
ExecResult result;
61+
try {
62+
result = execInContainer(cmd);
63+
} catch (IOException | InterruptedException e) {
64+
throw new RuntimeException(e);
65+
}
66+
67+
if (result.getStdout() != null && !result.getStdout().isEmpty()) {
68+
log.info("Output: {}", result.getStdout());
69+
}
70+
71+
if (result.getExitCode() != 0) {
72+
throw new IllegalStateException(result.toString());
73+
}
74+
}
75+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
auth:
2+
type: LDAP
3+
rbac:
4+
roles:
5+
- name: "test-AD-Group"
6+
clusters:
7+
- local
8+
subjects:
9+
- provider: ldap_ad
10+
permissions:
11+
- resource: applicationconfig
12+
actions: all
13+
- resource: topic
14+
value: ".*"
15+
actions: all

0 commit comments

Comments
 (0)