use of com.google.gerrit.entities.InternalGroup in project gerrit by GerritCodeReview.
the class GroupResolver method parseId.
/**
* Parses a group ID and returns the group without making any permission check whether the current
* user can see the group.
*
* @param id ID of the group, can be a group UUID, a group name or a legacy group ID
* @return the group, null if no group is found for the given group ID
*/
public GroupDescription.Basic parseId(String id) {
logger.atFine().log("Parsing group %s", id);
AccountGroup.UUID uuid = AccountGroup.uuid(id);
if (groupBackend.handles(uuid)) {
logger.atFine().log("Group UUID %s is handled by a group backend", uuid.get());
GroupDescription.Basic d = groupBackend.get(uuid);
if (d != null) {
logger.atFine().log("Found group %s", d.getName());
return d;
}
}
// Might be a numeric AccountGroup.Id. -> Internal group.
if (id.matches("^[1-9][0-9]*$")) {
logger.atFine().log("Group ID %s is a numeric ID", id);
try {
AccountGroup.Id groupId = AccountGroup.Id.parse(id);
Optional<InternalGroup> group = groupCache.get(groupId);
if (group.isPresent()) {
logger.atFine().log("Found internal group %s (UUID = %s)", group.get().getName(), group.get().getGroupUUID().get());
return new InternalGroupDescription(group.get());
}
} catch (IllegalArgumentException e) {
// Ignored
logger.atFine().withCause(e).log("Parsing numeric group ID %s failed", id);
}
}
// Might be a group name, be nice and accept unique names.
logger.atFine().log("Try finding a group with name %s", id);
GroupReference ref = GroupBackends.findExactSuggestion(groupBackend, id);
if (ref != null) {
GroupDescription.Basic d = groupBackend.get(ref.getUUID());
if (d != null) {
logger.atFine().log("Found group %s", d.getName());
return d;
}
}
logger.atFine().log("Group %s not found", id);
return null;
}
use of com.google.gerrit.entities.InternalGroup in project gerrit by GerritCodeReview.
the class GroupsNoteDbConsistencyChecker method checkGlobalConsistency.
/**
* Check invariants of the group refs with the group name refs.
*/
private List<ConsistencyProblemInfo> checkGlobalConsistency(Map<AccountGroup.UUID, InternalGroup> uuidToGroupMap, BiMap<AccountGroup.UUID, String> uuidNameBiMap) {
List<ConsistencyProblemInfo> problems = new ArrayList<>();
// Check consistency between the data coming from different refs.
for (AccountGroup.UUID uuid : uuidToGroupMap.keySet()) {
if (!uuidNameBiMap.containsKey(uuid)) {
problems.add(error("group %s has no entry in name map", uuid));
continue;
}
String noteName = uuidNameBiMap.get(uuid);
String groupRefName = uuidToGroupMap.get(uuid).getName();
if (!Objects.equals(noteName, groupRefName)) {
problems.add(error("inconsistent name for group %s (name map %s vs. group ref %s)", uuid, noteName, groupRefName));
}
}
for (AccountGroup.UUID uuid : uuidNameBiMap.keySet()) {
if (!uuidToGroupMap.containsKey(uuid)) {
problems.add(error("name map has entry (%s, %s), entry missing as group ref", uuid, uuidNameBiMap.get(uuid)));
}
}
if (problems.isEmpty()) {
// Check ids.
Map<AccountGroup.Id, InternalGroup> groupById = new HashMap<>();
for (InternalGroup g : uuidToGroupMap.values()) {
InternalGroup before = groupById.get(g.getId());
if (before != null) {
problems.add(error("shared group id %s for %s (%s) and %s (%s)", g.getId(), before.getName(), before.getGroupUUID(), g.getName(), g.getGroupUUID()));
}
groupById.put(g.getId(), g);
}
}
return problems;
}
use of com.google.gerrit.entities.InternalGroup in project gerrit by GerritCodeReview.
the class IncludingGroupMembership method containsAnyOf.
@Override
public boolean containsAnyOf(Iterable<AccountGroup.UUID> queryIds) {
// Prefer lookup of a cached result over expanding includes.
boolean tryExpanding = false;
for (AccountGroup.UUID id : queryIds) {
Boolean b = memberOf.get(id);
if (b == null) {
tryExpanding = true;
} else if (b) {
return true;
}
}
if (tryExpanding) {
Set<AccountGroup.UUID> queryIdsSet = new HashSet<>();
queryIds.forEach(i -> queryIdsSet.add(i));
Map<AccountGroup.UUID, InternalGroup> groups = groupCache.get(queryIdsSet);
for (AccountGroup.UUID id : queryIds) {
if (memberOf.containsKey(id)) {
// Membership was earlier proven to be false.
continue;
}
memberOf.put(id, false);
InternalGroup group = groups.get(id);
if (group == null) {
continue;
}
if (user.isIdentifiedUser() && group.getMembers().contains(user.getAccountId())) {
memberOf.put(id, true);
return true;
}
if (search(group.getSubgroups())) {
memberOf.put(id, true);
return true;
}
}
}
return false;
}
use of com.google.gerrit.entities.InternalGroup in project gerrit by GerritCodeReview.
the class GroupsConsistencyChecker method checkCycle.
/**
* checkCycle walks through root's subgroups recursively, and checks for cycles.
*/
private List<ConsistencyProblemInfo> checkCycle(InternalGroup root, Map<AccountGroup.UUID, InternalGroup> byUUID) {
List<ConsistencyProblemInfo> problems = new ArrayList<>();
Set<InternalGroup> todo = new LinkedHashSet<>();
Set<InternalGroup> seen = new HashSet<>();
todo.add(root);
while (!todo.isEmpty()) {
InternalGroup t = todo.iterator().next();
todo.remove(t);
if (seen.contains(t)) {
continue;
}
seen.add(t);
// We don't check for owner cycles, since those are normal in self-administered groups.
for (AccountGroup.UUID subUuid : t.getSubgroups()) {
InternalGroup g = byUUID.get(subUuid);
if (g == null) {
continue;
}
if (Objects.equals(g, root)) {
problems.add(warning("group %s (%s) contains a cycle: %s (%s) points to it as subgroup.", root.getName(), root.getGroupUUID(), t.getName(), t.getGroupUUID()));
}
todo.add(g);
}
}
return problems;
}
use of com.google.gerrit.entities.InternalGroup in project gerrit by GerritCodeReview.
the class GroupsUpdate method createGroup.
/**
* Creates the specified group for the specified members (accounts).
*
* @param groupCreation an {@link InternalGroupCreation} which specifies all mandatory properties
* of the group
* @param groupDelta a {@link GroupDelta} which specifies optional properties of the group. If
* this {@link GroupDelta} updates a property which was already specified by the {@link
* InternalGroupCreation}, the value of this {@link GroupDelta} wins.
* @throws DuplicateKeyException if a group with the chosen name already exists
* @throws IOException if indexing fails, or an error occurs while reading/writing from/to NoteDb
* @return the created {@link InternalGroup}
*/
public InternalGroup createGroup(InternalGroupCreation groupCreation, GroupDelta groupDelta) throws DuplicateKeyException, IOException, ConfigInvalidException {
try (TraceTimer ignored = TraceContext.newTimer("Creating group", Metadata.builder().groupName(groupDelta.getName().orElseGet(groupCreation::getNameKey).get()).build())) {
InternalGroup createdGroup = createGroupInNoteDbWithRetry(groupCreation, groupDelta);
evictCachesOnGroupCreation(createdGroup);
dispatchAuditEventsOnGroupCreation(createdGroup);
return createdGroup;
}
}
Aggregations