keycloak
クラス | 公開メンバ関数 | 非公開メンバ関数 | 静的非公開変数類 | 全メンバ一覧
org.keycloak.storage.ldap.mappers.membership.group.GroupTreeResolver クラス
org.keycloak.storage.ldap.mappers.membership.group.GroupTreeResolver 連携図
Collaboration graph

クラス

class  Group
 
class  GroupTreeEntry
 
class  GroupTreeResolveException
 

公開メンバ関数

List< GroupTreeEntryresolveGroupTree (List< Group > groups, boolean ignoreMissingGroups) throws GroupTreeResolveException
 

非公開メンバ関数

Map< String, List< String > > getParentsTree (List< Group > groups, boolean ignoreMissingGroups) throws GroupTreeResolveException
 
GroupTreeEntry resolveGroupTree (String groupName, Map< String, Group > asMap, Set< String > visitedGroups, List< String > currentSubtree) throws GroupTreeResolveException
 

静的非公開変数類

static final Logger logger = Logger.getLogger(GroupTreeResolver.class)
 

詳解

著者
Marek Posolda

関数詳解

◆ getParentsTree()

Map<String, List<String> > org.keycloak.storage.ldap.mappers.membership.group.GroupTreeResolver.getParentsTree ( List< Group groups,
boolean  ignoreMissingGroups 
) throws GroupTreeResolveException
inlineprivate
105  {
106  Map<String, List<String>> result = new TreeMap<>();
107 
108  for (Group group : groups) {
109  result.put(group.getGroupName(), new LinkedList<String>());
110  }
111 
112  for (Group group : groups) {
113  Iterator<String> iterator = group.getChildrenNames().iterator();
114  while (iterator.hasNext()) {
115  String child = iterator.next();
116  List<String> list = result.get(child);
117  if (list != null) {
118  list.add(group.getGroupName());
119  } else if (ignoreMissingGroups) {
120  // Need to remove the missing group
121  iterator.remove();
122  logger.debug("Group '" + child + "' referenced as member of group '" + group.getGroupName() + "' doesn't exists. Ignoring.");
123  } else {
124  throw new GroupTreeResolveException("Group '" + child + "' referenced as member of group '" + group.getGroupName() + "' doesn't exists");
125  }
126  }
127  }
128  return result;
129  }
static final Logger logger
Definition: GroupTreeResolver.java:37

◆ resolveGroupTree() [1/2]

List<GroupTreeEntry> org.keycloak.storage.ldap.mappers.membership.group.GroupTreeResolver.resolveGroupTree ( List< Group groups,
boolean  ignoreMissingGroups 
) throws GroupTreeResolveException
inline

Fully resolves list of group trees to be used in Keycloak. The input is group info (usually from LDAP) where each "Group" object contains just it's name and direct children.

The operation also performs validation as rules for LDAP are less strict than for Keycloak (In LDAP, the recursion is possible and multiple parents of single group is also allowed)

引数
groups
ignoreMissingGroups
戻り値
例外
GroupTreeResolveException
51  {
52  // 1- Get parents of each group
53  Map<String, List<String>> parentsTree = getParentsTree(groups, ignoreMissingGroups);
54 
55  // 2 - Get rootGroups (groups without parent) and check if there is no group with multiple parents
56  List<String> rootGroups = new LinkedList<>();
57  for (Map.Entry<String, List<String>> group : parentsTree.entrySet()) {
58  int parentCount = group.getValue().size();
59  if (parentCount == 0) {
60  rootGroups.add(group.getKey());
61  } else if (parentCount > 1) {
62  throw new GroupTreeResolveException("Group '" + group.getKey() + "' detected to have multiple parents. This is not allowed in Keycloak. Parents are: " + group.getValue());
63  }
64  }
65 
66  // 3 - Just convert to map for easier retrieval
67  Map<String, Group> asMap = new TreeMap<>();
68  for (Group group : groups) {
69  asMap.put(group.getGroupName(), group);
70  }
71 
72  // 4 - Now we have rootGroups. Let's resolve them
73  List<GroupTreeEntry> finalResult = new LinkedList<>();
74  Set<String> visitedGroups = new TreeSet<>();
75  for (String rootGroupName : rootGroups) {
76  List<String> subtree = new LinkedList<>();
77  subtree.add(rootGroupName);
78  GroupTreeEntry groupTree = resolveGroupTree(rootGroupName, asMap, visitedGroups, subtree);
79  finalResult.add(groupTree);
80  }
81 
82 
83  // 5 - Check recursion
84  if (visitedGroups.size() != asMap.size()) {
85  // Recursion detected. Try to find where it is
86  for (Map.Entry<String, Group> entry : asMap.entrySet()) {
87  String groupName = entry.getKey();
88  if (!visitedGroups.contains(groupName)) {
89  List<String> subtree = new LinkedList<>();
90  subtree.add(groupName);
91 
92  Set<String> newVisitedGroups = new TreeSet<>();
93  resolveGroupTree(groupName, asMap, newVisitedGroups, subtree);
94  visitedGroups.addAll(newVisitedGroups);
95  }
96  }
97 
98  // Shouldn't happen
99  throw new GroupTreeResolveException("Illegal state: Recursion detected, but wasn't able to find it");
100  }
101 
102  return finalResult;
103  }
List< GroupTreeEntry > resolveGroupTree(List< Group > groups, boolean ignoreMissingGroups)
Definition: GroupTreeResolver.java:51
Map< String, List< String > > getParentsTree(List< Group > groups, boolean ignoreMissingGroups)
Definition: GroupTreeResolver.java:105

◆ resolveGroupTree() [2/2]

GroupTreeEntry org.keycloak.storage.ldap.mappers.membership.group.GroupTreeResolver.resolveGroupTree ( String  groupName,
Map< String, Group asMap,
Set< String >  visitedGroups,
List< String >  currentSubtree 
) throws GroupTreeResolveException
inlineprivate
131  {
132  if (visitedGroups.contains(groupName)) {
133  throw new GroupTreeResolveException("Recursion detected when trying to resolve group '" + groupName + "'. Whole recursion path: " + currentSubtree);
134  }
135 
136  visitedGroups.add(groupName);
137 
138  Group group = asMap.get(groupName);
139 
140  List<GroupTreeEntry> children = new LinkedList<>();
141  GroupTreeEntry result = new GroupTreeEntry(group.getGroupName(), children);
142 
143  for (String childrenName : group.getChildrenNames()) {
144  List<String> subtreeCopy = new LinkedList<>(currentSubtree);
145  subtreeCopy.add(childrenName);
146  GroupTreeEntry childEntry = resolveGroupTree(childrenName, asMap, visitedGroups, subtreeCopy);
147  children.add(childEntry);
148  }
149 
150  return result;
151  }
List< GroupTreeEntry > resolveGroupTree(List< Group > groups, boolean ignoreMissingGroups)
Definition: GroupTreeResolver.java:51

メンバ詳解

◆ logger

final Logger org.keycloak.storage.ldap.mappers.membership.group.GroupTreeResolver.logger = Logger.getLogger(GroupTreeResolver.class)
staticprivate

このクラス詳解は次のファイルから抽出されました: