Skip to content

Commit f6fc0ac

Browse files
committed
feat: roles mapping support for condition groups
1 parent da7ff8b commit f6fc0ac

File tree

2 files changed

+91
-5
lines changed

2 files changed

+91
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,80 @@
11
package org.obiba.mica.security.service;
22

3+
import com.google.common.annotations.VisibleForTesting;
4+
import com.google.common.base.Joiner;
35
import com.google.common.collect.Maps;
46
import org.obiba.mica.security.Roles;
57
import org.obiba.shiro.realm.GroupsToRolesMapper;
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
610
import org.springframework.core.env.Environment;
711

812
import java.util.Arrays;
13+
import java.util.List;
914
import java.util.Map;
1015
import java.util.Set;
1116
import java.util.stream.Collectors;
1217

1318
public class MicaGroupsToRolesMapper implements GroupsToRolesMapper {
1419

15-
private Map<String, Set<String>> roleGroups = Maps.newHashMap();
20+
private static final Logger log = LoggerFactory.getLogger(MicaGroupsToRolesMapper.class);
21+
22+
private Map<String, List<Set<String>>> roleGroups = Maps.newHashMap();
1623

1724
public MicaGroupsToRolesMapper(Environment environment) {
1825
Roles.ALL_ROLES.forEach(role -> {
1926
addRoleGroups(environment, role);
2027
});
2128
}
2229

30+
@VisibleForTesting
31+
MicaGroupsToRolesMapper(String groupsStr, String someRole) {
32+
Roles.ALL_ROLES.forEach(role -> {
33+
if (role.equals(someRole)) {
34+
addRoleGroups(groupsStr, role);
35+
} else {
36+
addRoleGroups("", role);
37+
}
38+
});
39+
}
40+
41+
2342
@Override
2443
public Set<String> toRoles(Set<String> groups) {
2544
Set<String> roles = Roles.ALL_ROLES.stream()
2645
.filter(role -> hasRole(role, groups))
2746
.collect(Collectors.toSet());
28-
47+
log.debug("roles: {}", Joiner.on(",").join(roles));
2948
roles.addAll(groups);
3049

3150
return roles;
3251
}
3352

3453
private void addRoleGroups(Environment environment, String role) {
3554
String groupsStr = environment.getProperty(String.format("roles.%s", role), role);
36-
Set<String> groups = Arrays.stream(groupsStr.split(","))
55+
addRoleGroups(groupsStr, role);
56+
}
57+
58+
private void addRoleGroups(String groupsStr, String role) {
59+
Set<String> groupsCond = toSet(groupsStr, "\\|");
60+
List<Set<String>> groupsSets = groupsCond.stream()
61+
.map((cond) -> toSet(cond, ","))
62+
.toList();
63+
roleGroups.put(role, groupsSets);
64+
}
65+
66+
private Set<String> toSet(String groupsStr, String separator) {
67+
return Arrays.stream(groupsStr.split(separator))
3768
.map(String::trim)
3869
.filter(s -> !s.isEmpty()) // Remove empty strings
3970
.collect(Collectors.toSet());
40-
roleGroups.put(role, groups);
4171
}
4272

4373
private boolean hasRole(String role, Set<String> groups) {
4474
if (!roleGroups.containsKey(role)) return false;
45-
return groups.containsAll(roleGroups.get(role));
75+
for (Set<String> groupSet : roleGroups.get(role)) {
76+
if (groups.containsAll(groupSet)) return true;
77+
}
78+
return false;
4679
}
4780
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.obiba.mica.security.service;
2+
3+
import org.junit.Test;
4+
import org.obiba.mica.security.Roles;
5+
6+
import java.util.Set;
7+
8+
import static org.junit.Assert.assertFalse;
9+
import static org.junit.Assert.assertTrue;
10+
11+
public class MicaGroupsToRolesMapperTest {
12+
13+
14+
@Test
15+
public void testSingleGroup() {
16+
MicaGroupsToRolesMapper mapper = new MicaGroupsToRolesMapper("local-administrator", Roles.MICA_ADMIN);
17+
assertTrue(mapper.toRoles(Set.of("local-administrator")).contains(Roles.MICA_ADMIN));
18+
assertFalse(mapper.toRoles(Set.of("some-group")).contains(Roles.MICA_ADMIN));
19+
}
20+
21+
@Test
22+
public void testMultipleGroups() {
23+
MicaGroupsToRolesMapper mapper = new MicaGroupsToRolesMapper("opal-administrator,mica-user", Roles.MICA_ADMIN);
24+
assertTrue(mapper.toRoles(Set.of("opal-administrator", "mica-user")).contains(Roles.MICA_ADMIN));
25+
assertTrue(mapper.toRoles(Set.of("opal-administrator", "mica-user", "some-group")).contains(Roles.MICA_ADMIN));
26+
assertFalse(mapper.toRoles(Set.of("opal-administrator")).contains(Roles.MICA_ADMIN));
27+
assertFalse(mapper.toRoles(Set.of("mica-user")).contains(Roles.MICA_ADMIN));
28+
assertTrue(mapper.toRoles(Set.of("mica-user")).contains(Roles.MICA_USER));
29+
assertFalse(mapper.toRoles(Set.of("some-group")).contains(Roles.MICA_ADMIN));
30+
}
31+
32+
@Test
33+
public void testMultipleOptionsGroups() {
34+
MicaGroupsToRolesMapper mapper = new MicaGroupsToRolesMapper("opal-administrator,mica-user|local-administrator", Roles.MICA_ADMIN);
35+
assertTrue(mapper.toRoles(Set.of("opal-administrator", "mica-user")).contains(Roles.MICA_ADMIN));
36+
assertTrue(mapper.toRoles(Set.of("opal-administrator", "mica-user", "some-group")).contains(Roles.MICA_ADMIN));
37+
assertTrue(mapper.toRoles(Set.of("local-administrator")).contains(Roles.MICA_ADMIN));
38+
assertFalse(mapper.toRoles(Set.of("opal-administrator")).contains(Roles.MICA_ADMIN));
39+
assertFalse(mapper.toRoles(Set.of("mica-user")).contains(Roles.MICA_ADMIN));
40+
assertTrue(mapper.toRoles(Set.of("mica-user")).contains(Roles.MICA_USER));
41+
assertFalse(mapper.toRoles(Set.of("some-group")).contains(Roles.MICA_ADMIN));
42+
}
43+
44+
@Test
45+
public void testDefaults() {
46+
MicaGroupsToRolesMapper mapper = new MicaGroupsToRolesMapper("", Roles.MICA_ADMIN);
47+
assertTrue(mapper.toRoles(Set.of(Roles.MICA_USER)).contains(Roles.MICA_USER));
48+
assertTrue(mapper.toRoles(Set.of(Roles.MICA_DAO)).contains(Roles.MICA_DAO));
49+
assertTrue(mapper.toRoles(Set.of(Roles.MICA_EDITOR)).contains(Roles.MICA_EDITOR));
50+
assertTrue(mapper.toRoles(Set.of(Roles.MICA_REVIEWER)).contains(Roles.MICA_REVIEWER));
51+
assertTrue(mapper.toRoles(Set.of(Roles.MICA_ADMIN)).contains(Roles.MICA_ADMIN));
52+
}
53+
}

0 commit comments

Comments
 (0)