1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.provisioning.api.utils;
20
21 import java.util.Collection;
22 import java.util.HashSet;
23 import java.util.Optional;
24 import java.util.Set;
25 import java.util.function.Predicate;
26 import java.util.stream.Collectors;
27 import org.apache.commons.lang3.tuple.Pair;
28 import org.apache.syncope.common.lib.SyncopeConstants;
29
30 public final class RealmUtils {
31
32 public static String getGroupOwnerRealm(final String realmPath, final String groupKey) {
33 return realmPath + '@' + groupKey;
34 }
35
36 public static Optional<Pair<String, String>> parseGroupOwnerRealm(final String input) {
37 String[] split = input.split("@");
38 return split == null || split.length < 2
39 ? Optional.empty()
40 : Optional.of(Pair.of(split[0], split[1]));
41 }
42
43 public static boolean normalizingAddTo(final Set<String> realms, final String newRealm) {
44 boolean dontAdd = false;
45 Set<String> toRemove = new HashSet<>();
46 for (String realm : realms) {
47 if (newRealm.startsWith(realm)) {
48 dontAdd = true;
49 } else if (realm.startsWith(newRealm)) {
50 toRemove.add(realm);
51 }
52 }
53
54 realms.removeAll(toRemove);
55 if (!dontAdd) {
56 realms.add(newRealm);
57 }
58 return !dontAdd;
59 }
60
61 public static Pair<Set<String>, Set<String>> normalize(final Collection<String> realms) {
62 Set<String> normalized = new HashSet<>();
63 Set<String> groupOwnership = new HashSet<>();
64 if (realms != null) {
65 realms.forEach(realm -> {
66 if (realm.indexOf('@') == -1) {
67 normalizingAddTo(normalized, realm);
68 } else {
69 groupOwnership.add(realm);
70 }
71 });
72 }
73
74 return Pair.of(normalized, groupOwnership);
75 }
76
77 private static class StartsWithPredicate implements Predicate<String> {
78
79 private final Collection<String> targets;
80
81 StartsWithPredicate(final Collection<String> targets) {
82 this.targets = targets;
83 }
84
85 @Override
86 public boolean test(final String realm) {
87 return targets.stream().anyMatch(realm::startsWith);
88 }
89 }
90
91 private static final Predicate<String> DYN_REALMS_PREDICATE = r -> !r.startsWith(SyncopeConstants.ROOT_REALM);
92
93 public static Set<String> getEffective(final Set<String> allowedRealms, final String requestedRealm) {
94 Pair<Set<String>, Set<String>> normalized = normalize(allowedRealms);
95
96 Set<String> requested = Set.of(requestedRealm);
97
98 StartsWithPredicate normalizedFilter = new StartsWithPredicate(normalized.getLeft());
99 StartsWithPredicate requestedFilter = new StartsWithPredicate(requested);
100
101 Set<String> effective = new HashSet<>();
102 effective.addAll(requested.stream().filter(normalizedFilter).collect(Collectors.toSet()));
103 effective.addAll(normalized.getLeft().stream().filter(requestedFilter).collect(Collectors.toSet()));
104
105
106 effective.addAll(normalized.getRight());
107
108
109 if (allowedRealms != null) {
110 effective.addAll(allowedRealms.stream().filter(DYN_REALMS_PREDICATE).collect(Collectors.toSet()));
111 }
112
113 return effective;
114 }
115
116 private RealmUtils() {
117
118 }
119 }