|
1 | 1 | package org.obiba.mica.security.service;
|
2 | 2 |
|
| 3 | +import com.google.common.annotations.VisibleForTesting; |
| 4 | +import com.google.common.base.Joiner; |
3 | 5 | import com.google.common.collect.Maps;
|
4 | 6 | import org.obiba.mica.security.Roles;
|
5 | 7 | import org.obiba.shiro.realm.GroupsToRolesMapper;
|
| 8 | +import org.slf4j.Logger; |
| 9 | +import org.slf4j.LoggerFactory; |
6 | 10 | import org.springframework.core.env.Environment;
|
7 | 11 |
|
8 | 12 | import java.util.Arrays;
|
| 13 | +import java.util.List; |
9 | 14 | import java.util.Map;
|
10 | 15 | import java.util.Set;
|
11 | 16 | import java.util.stream.Collectors;
|
12 | 17 |
|
13 | 18 | public class MicaGroupsToRolesMapper implements GroupsToRolesMapper {
|
14 | 19 |
|
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(); |
16 | 23 |
|
17 | 24 | public MicaGroupsToRolesMapper(Environment environment) {
|
18 | 25 | Roles.ALL_ROLES.forEach(role -> {
|
19 | 26 | addRoleGroups(environment, role);
|
20 | 27 | });
|
21 | 28 | }
|
22 | 29 |
|
| 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 | + |
23 | 42 | @Override
|
24 | 43 | public Set<String> toRoles(Set<String> groups) {
|
25 | 44 | Set<String> roles = Roles.ALL_ROLES.stream()
|
26 | 45 | .filter(role -> hasRole(role, groups))
|
27 | 46 | .collect(Collectors.toSet());
|
28 |
| - |
| 47 | + log.debug("roles: {}", Joiner.on(",").join(roles)); |
29 | 48 | roles.addAll(groups);
|
30 | 49 |
|
31 | 50 | return roles;
|
32 | 51 | }
|
33 | 52 |
|
34 | 53 | private void addRoleGroups(Environment environment, String role) {
|
35 | 54 | 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)) |
37 | 68 | .map(String::trim)
|
38 | 69 | .filter(s -> !s.isEmpty()) // Remove empty strings
|
39 | 70 | .collect(Collectors.toSet());
|
40 |
| - roleGroups.put(role, groups); |
41 | 71 | }
|
42 | 72 |
|
43 | 73 | private boolean hasRole(String role, Set<String> groups) {
|
44 | 74 | 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; |
46 | 79 | }
|
47 | 80 | }
|
0 commit comments