Skip to content

Commit bd2c6fd

Browse files
author
François
committed
Issues/300: rbac now supports regex for values
1 parent 0ad8695 commit bd2c6fd

File tree

3 files changed

+104
-2
lines changed

3 files changed

+104
-2
lines changed

api/src/main/java/io/kafbat/ui/service/rbac/extractor/OauthAuthorityExtractor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ private Set<String> extractUsernameRoles(AccessControlService acs, DefaultOAuth2
6060
.filter(s -> s.getType().equals("user"))
6161
.peek(s -> log.trace("[{}] matches [{}]? [{}]", s.getValue(), principalName,
6262
s.getValue().equalsIgnoreCase(principalName)))
63-
.anyMatch(s -> s.getValue().equalsIgnoreCase(principalName)))
63+
.anyMatch(s -> principalName.matches(s.getValue())))
6464
.map(Role::getName)
6565
.collect(Collectors.toSet());
6666

@@ -96,7 +96,7 @@ private Set<String> extractRoles(AccessControlService acs, DefaultOAuth2User pri
9696
.filter(s -> s.getType().equals("role"))
9797
.anyMatch(subject -> {
9898
var roleName = subject.getValue();
99-
return principalRoles.contains(roleName);
99+
return principalRoles.stream().anyMatch(s -> s.matches(subject.getValue()));
100100
})
101101
)
102102
.map(Role::getName)
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package io.kafbat.ui.config;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.mockito.Mockito.when;
5+
6+
import io.kafbat.ui.config.auth.OAuthProperties;
7+
import io.kafbat.ui.model.rbac.Role;
8+
import io.kafbat.ui.service.rbac.AccessControlService;
9+
import io.kafbat.ui.service.rbac.extractor.OauthAuthorityExtractor;
10+
import io.kafbat.ui.service.rbac.extractor.ProviderAuthorityExtractor;
11+
import io.kafbat.ui.util.AccessControlServiceMock;
12+
import java.io.InputStream;
13+
import java.util.HashMap;
14+
import java.util.List;
15+
import java.util.Map;
16+
import java.util.Set;
17+
import lombok.SneakyThrows;
18+
import org.junit.jupiter.api.BeforeEach;
19+
import org.junit.jupiter.api.Test;
20+
import org.springframework.security.core.authority.AuthorityUtils;
21+
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
22+
import org.springframework.security.oauth2.core.user.OAuth2User;
23+
import org.yaml.snakeyaml.Yaml;
24+
import org.yaml.snakeyaml.introspector.BeanAccess;
25+
26+
public class ProviderAuthorityExtractorTest {
27+
28+
29+
private final AccessControlService accessControlService = new AccessControlServiceMock().getMock();
30+
Yaml yaml;
31+
ProviderAuthorityExtractor extractor;
32+
33+
@BeforeEach
34+
void setUp() {
35+
yaml = new Yaml();
36+
yaml.setBeanAccess(BeanAccess.FIELD);
37+
extractor = new OauthAuthorityExtractor();
38+
39+
InputStream rolesFile = this.getClass()
40+
.getClassLoader()
41+
.getResourceAsStream("roles_definition.yaml");
42+
43+
Role[] roleArray = yaml.loadAs(rolesFile, Role[].class);
44+
when(accessControlService.getRoles()).thenReturn(List.of(roleArray));
45+
46+
}
47+
48+
@SneakyThrows
49+
@Test
50+
void ExtractAuthoritiesFromRegex() {
51+
52+
OAuth2User oauth2User = new DefaultOAuth2User(
53+
AuthorityUtils.createAuthorityList("SCOPE_message:read"),
54+
Map.of("role_definition", Set.of("ROLE-ADMIN", "ANOTHER-ROLE"), "user_name", "[email protected]"),
55+
"user_name");
56+
57+
HashMap<String, Object> additionalParams = new HashMap<>();
58+
OAuthProperties.OAuth2Provider oAuth2Provider = new OAuthProperties.OAuth2Provider();
59+
oAuth2Provider.setCustomParams(Map.of("roles-field", "role_definition"));
60+
additionalParams.put("provider", oAuth2Provider);
61+
62+
Set<String> roles = extractor.extract(accessControlService, oauth2User, additionalParams).block();
63+
64+
assertEquals(Set.of("viewer", "admin"), roles);
65+
66+
}
67+
68+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
- name: 'admin'
2+
subjects:
3+
- provider: 'OAUTH'
4+
value: 'ROLE-[A-Z]+'
5+
type: 'role'
6+
clusters:
7+
- local
8+
- remote
9+
permissions:
10+
- resource: APPLICATIONCONFIG
11+
actions: [ all ]
12+
- name: 'viewer'
13+
subjects:
14+
- provider: 'LDAP'
15+
value: 'CS-XXX'
16+
type: 'kafka-viewer'
17+
- provider: 'OAUTH'
18+
value: '.*@kafka.com'
19+
type: 'user'
20+
clusters:
21+
- remote
22+
permissions:
23+
- resource: APPLICATIONCONFIG
24+
actions: [ all ]
25+
- name: 'editor'
26+
subjects:
27+
- provider: 'OAUTH'
28+
value: 'ROLE_EDITOR'
29+
type: 'role'
30+
clusters:
31+
- local
32+
permissions:
33+
- resource: APPLICATIONCONFIG
34+
actions: [ all ]

0 commit comments

Comments
 (0)