Skip to content

Commit fa99b39

Browse files
committed
added test cases for issues
1 parent 1d5ca3b commit fa99b39

File tree

5 files changed

+598
-59
lines changed

5 files changed

+598
-59
lines changed

api/src/test/java/io/kafbat/ui/service/rbac/AccessControlServiceInitPropertiesTest.java

Lines changed: 0 additions & 59 deletions
This file was deleted.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package io.kafbat.ui.service.rbac;
2+
3+
import static org.mockito.Mockito.mock;
4+
import static org.mockito.Mockito.when;
5+
6+
import io.kafbat.ui.AbstractIntegrationTest;
7+
import io.kafbat.ui.config.auth.RbacUser;
8+
import io.kafbat.ui.config.auth.RoleBasedAccessControlProperties;
9+
import io.kafbat.ui.model.rbac.AccessContext;
10+
import io.kafbat.ui.model.rbac.Permission;
11+
import io.kafbat.ui.model.rbac.Resource;
12+
import io.kafbat.ui.model.rbac.Role;
13+
import io.kafbat.ui.model.rbac.permission.ClusterConfigAction;
14+
import java.util.List;
15+
import org.junit.jupiter.api.BeforeEach;
16+
import org.junit.jupiter.api.Disabled;
17+
import org.junit.jupiter.api.Test;
18+
import org.mockito.Mock;
19+
import org.mockito.MockedStatic;
20+
import org.mockito.Mockito;
21+
import org.springframework.beans.factory.annotation.Autowired;
22+
import org.springframework.security.core.Authentication;
23+
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
24+
import org.springframework.security.core.context.SecurityContext;
25+
import org.springframework.test.annotation.DirtiesContext;
26+
import org.springframework.test.util.ReflectionTestUtils;
27+
import reactor.core.publisher.Mono;
28+
import reactor.test.StepVerifier;
29+
30+
/**
31+
* Test cases for issue #461.
32+
* Sets the role to any cluster ".*"
33+
*/
34+
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
35+
class RbacClusterConfigTest extends AbstractIntegrationTest {
36+
37+
public static final String ROLE_NAME = "cluster_config_role";
38+
39+
@Autowired
40+
AccessControlService accessControlService;
41+
42+
@Mock
43+
SecurityContext securityContext;
44+
45+
@Mock
46+
Authentication authentication;
47+
48+
@Mock
49+
RbacUser user;
50+
51+
@BeforeEach
52+
void setUp() {
53+
// Mock roles
54+
List<Role> roles = List.of(
55+
getClusterConfigRole()
56+
);
57+
RoleBasedAccessControlProperties properties = mock();
58+
when(properties.getRoles()).thenReturn(roles);
59+
60+
ReflectionTestUtils.setField(accessControlService, "properties", properties);
61+
ReflectionTestUtils.setField(accessControlService, "rbacEnabled", true);
62+
63+
// Mock security context
64+
when(securityContext.getAuthentication()).thenReturn(authentication);
65+
when(authentication.getPrincipal()).thenReturn(user);
66+
}
67+
68+
public void withSecurityContext(Runnable runnable) {
69+
try (MockedStatic<ReactiveSecurityContextHolder> ctxHolder = Mockito.mockStatic(
70+
ReactiveSecurityContextHolder.class)) {
71+
// Mock static method to get security context
72+
ctxHolder.when(ReactiveSecurityContextHolder::getContext).thenReturn(Mono.just(securityContext));
73+
runnable.run();
74+
}
75+
}
76+
77+
@Test
78+
@Disabled("expected to work after issue #461 is resolved")
79+
void validateAccess_clusterConfigAll_propertiesAllCluster() {
80+
withSecurityContext(() -> {
81+
when(user.groups()).thenReturn(List.of(ROLE_NAME));
82+
AccessContext context = AccessContext.builder()
83+
.cluster("prod")
84+
.clusterConfigActions(ClusterConfigAction.EDIT)
85+
.build();
86+
Mono<Void> validateAccessMono = accessControlService.validateAccess(context);
87+
StepVerifier.create(validateAccessMono)
88+
.expectComplete()
89+
.verify();
90+
});
91+
}
92+
93+
public static Role getClusterConfigRole() {
94+
Role role = new Role();
95+
role.setName(ROLE_NAME);
96+
role.setClusters(List.of(".*")); // setting role for any cluster
97+
98+
Permission permission = new Permission();
99+
permission.setResource(Resource.CLUSTERCONFIG.name());
100+
permission.setActions(List.of("all"));
101+
102+
List<Permission> permissions = List.of(
103+
permission
104+
);
105+
role.setPermissions(permissions);
106+
role.validate();
107+
return role;
108+
}
109+
110+
}
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
package io.kafbat.ui.service.rbac;
2+
3+
import static org.mockito.Mockito.mock;
4+
import static org.mockito.Mockito.when;
5+
6+
import io.kafbat.ui.AbstractIntegrationTest;
7+
import io.kafbat.ui.config.auth.RbacUser;
8+
import io.kafbat.ui.config.auth.RoleBasedAccessControlProperties;
9+
import io.kafbat.ui.model.rbac.AccessContext;
10+
import io.kafbat.ui.model.rbac.Permission;
11+
import io.kafbat.ui.model.rbac.Resource;
12+
import io.kafbat.ui.model.rbac.Role;
13+
import io.kafbat.ui.model.rbac.permission.AclAction;
14+
import java.util.List;
15+
import org.junit.jupiter.api.BeforeEach;
16+
import org.junit.jupiter.api.Test;
17+
import org.mockito.Mock;
18+
import org.mockito.MockedStatic;
19+
import org.mockito.Mockito;
20+
import org.springframework.beans.factory.annotation.Autowired;
21+
import org.springframework.security.access.AccessDeniedException;
22+
import org.springframework.security.core.Authentication;
23+
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
24+
import org.springframework.security.core.context.SecurityContext;
25+
import org.springframework.test.annotation.DirtiesContext;
26+
import org.springframework.test.util.ReflectionTestUtils;
27+
import reactor.core.publisher.Mono;
28+
import reactor.test.StepVerifier;
29+
30+
/**
31+
* Test cases for issue #274.
32+
*/
33+
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
34+
class RbacClusterMistakenTest extends AbstractIntegrationTest {
35+
36+
public static final String ADMIN_ROLE_NAME = "Admin Roles";
37+
38+
public static final String DEV_CLUSTER_ADM = "DEV";
39+
public static final String TST_CLUSTER_ADM = "TST";
40+
public static final String UAT_CLUSTER_ADM = "UAT";
41+
public static final String LAB_CLUSTER_ALL = "LAB";
42+
public static final String LAB_ROLE_NAME = "LAB for ALL";
43+
44+
@Autowired
45+
AccessControlService accessControlService;
46+
47+
@Mock
48+
SecurityContext securityContext;
49+
50+
@Mock
51+
Authentication authentication;
52+
53+
@Mock
54+
RbacUser user;
55+
56+
@BeforeEach
57+
void setUp() {
58+
// Mock roles
59+
List<Role> roles = List.of(
60+
getAdminRole(),
61+
getDevRole()
62+
);
63+
RoleBasedAccessControlProperties properties = mock();
64+
when(properties.getRoles()).thenReturn(roles);
65+
66+
ReflectionTestUtils.setField(accessControlService, "properties", properties);
67+
ReflectionTestUtils.setField(accessControlService, "rbacEnabled", true);
68+
69+
// Mock security context
70+
when(securityContext.getAuthentication()).thenReturn(authentication);
71+
when(authentication.getPrincipal()).thenReturn(user);
72+
}
73+
74+
public void withSecurityContext(Runnable runnable) {
75+
try (MockedStatic<ReactiveSecurityContextHolder> ctxHolder = Mockito.mockStatic(
76+
ReactiveSecurityContextHolder.class)) {
77+
// Mock static method to get security context
78+
ctxHolder.when(ReactiveSecurityContextHolder::getContext).thenReturn(Mono.just(securityContext));
79+
runnable.run();
80+
}
81+
}
82+
83+
/**
84+
* Anyone editing LAB.
85+
*/
86+
@Test
87+
void validateAccess() {
88+
withSecurityContext(() -> {
89+
when(user.groups()).thenReturn(List.of(LAB_ROLE_NAME));
90+
AccessContext context = AccessContext.builder()
91+
.cluster(LAB_CLUSTER_ALL)
92+
.aclActions(AclAction.EDIT)
93+
.build();
94+
Mono<Void> validateAccessMono = accessControlService.validateAccess(context);
95+
StepVerifier.create(validateAccessMono)
96+
.expectComplete()
97+
.verify();
98+
});
99+
}
100+
101+
/**
102+
* Admin with both roles editing LAB.
103+
*/
104+
@Test
105+
void validateAccess_bothRoles() {
106+
withSecurityContext(() -> {
107+
when(user.groups()).thenReturn(List.of(ADMIN_ROLE_NAME, LAB_ROLE_NAME));
108+
AccessContext context = AccessContext.builder()
109+
.cluster(LAB_CLUSTER_ALL)
110+
.aclActions(AclAction.EDIT)
111+
.build();
112+
Mono<Void> validateAccessMono = accessControlService.validateAccess(context);
113+
StepVerifier.create(validateAccessMono)
114+
.expectComplete()
115+
.verify();
116+
});
117+
}
118+
119+
/**
120+
* Anyone editing Dev cluster, denied.
121+
*/
122+
@Test
123+
void validateAccess_Denied() {
124+
withSecurityContext(() -> {
125+
when(user.groups()).thenReturn(List.of(LAB_ROLE_NAME));
126+
AccessContext context = AccessContext.builder()
127+
.cluster(DEV_CLUSTER_ADM)
128+
.aclActions(AclAction.EDIT)
129+
.build();
130+
Mono<Void> validateAccessMono = accessControlService.validateAccess(context);
131+
StepVerifier.create(validateAccessMono)
132+
.expectErrorMatches(e -> e instanceof AccessDeniedException)
133+
.verify();
134+
});
135+
}
136+
137+
/**
138+
* Admin editing dev cluster, denied.
139+
*/
140+
@Test
141+
void validateAccess_DeniedAdminEditing() {
142+
withSecurityContext(() -> {
143+
when(user.groups()).thenReturn(List.of(ADMIN_ROLE_NAME));
144+
AccessContext context = AccessContext.builder()
145+
.cluster(DEV_CLUSTER_ADM)
146+
.aclActions(AclAction.EDIT)
147+
.build();
148+
Mono<Void> validateAccessMono = accessControlService.validateAccess(context);
149+
StepVerifier.create(validateAccessMono)
150+
.expectErrorMatches(e -> e instanceof AccessDeniedException)
151+
.verify();
152+
});
153+
}
154+
155+
/**
156+
* Admin viewing Dev cluster, allowed.
157+
*/
158+
@Test
159+
void validateAccess_viewAllowedAdmin() {
160+
withSecurityContext(() -> {
161+
when(user.groups()).thenReturn(List.of(ADMIN_ROLE_NAME));
162+
AccessContext context = AccessContext.builder()
163+
.cluster(DEV_CLUSTER_ADM)
164+
.aclActions(AclAction.VIEW)
165+
.build();
166+
Mono<Void> validateAccessMono = accessControlService.validateAccess(context);
167+
StepVerifier.create(validateAccessMono)
168+
.expectComplete()
169+
.verify();
170+
});
171+
}
172+
173+
private Role getAdminRole() {
174+
Role role = new Role();
175+
role.setName(ADMIN_ROLE_NAME);
176+
role.setClusters(List.of(DEV_CLUSTER_ADM, TST_CLUSTER_ADM, UAT_CLUSTER_ADM));
177+
178+
Permission permission = new Permission();
179+
permission.setResource(Resource.ACL.name());
180+
permission.setActions(List.of(AclAction.VIEW.name()));
181+
182+
List<Permission> permissions = List.of(
183+
permission
184+
);
185+
role.setPermissions(permissions);
186+
role.validate();
187+
return role;
188+
}
189+
190+
private Role getDevRole() {
191+
Role role = new Role();
192+
role.setName(LAB_ROLE_NAME);
193+
role.setClusters(List.of(LAB_CLUSTER_ALL));
194+
195+
Permission permission = new Permission();
196+
permission.setResource(Resource.ACL.name());
197+
permission.setActions(List.of(AclAction.VIEW.name(), AclAction.EDIT.name()));
198+
199+
List<Permission> permissions = List.of(
200+
permission
201+
);
202+
role.setPermissions(permissions);
203+
role.validate();
204+
return role;
205+
}
206+
207+
}

0 commit comments

Comments
 (0)