blob: 65ac2329f39c85ca658e7625cc8fb424cf0fbde0 [file] [log] [blame]
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.googlesource.gerrit.plugins.serviceuser;
import static com.google.gerrit.server.api.ApiUtil.asRestApiException;
import com.google.gerrit.common.data.GroupDescription;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.account.AccountResolver.UnresolvableAccountException;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.GroupControl;
import com.google.gerrit.server.account.GroupMembership;
import com.google.gerrit.server.group.GroupResolver;
import com.google.gerrit.server.group.GroupResource;
import com.google.gerrit.server.restapi.group.ListMembers;
import com.google.gerrit.server.util.RequestContext;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.serviceuser.GetServiceUser.ServiceUserInfo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import org.eclipse.jgit.lib.PersonIdent;
@Singleton
class ServiceUserResolver {
private final AccountResolver resolver;
private final IdentifiedUser.GenericFactory genericUserFactory;
private final Provider<GetServiceUser> getServiceUser;
private final Provider<ListMembers> listMembers;
private final ThreadLocalRequestContext tl;
private final AccountCache accountCache;
private final GroupControl.Factory groupControlFactory;
private final GroupResolver groupResolver;
@Inject
ServiceUserResolver(
AccountResolver resolver,
IdentifiedUser.GenericFactory genericUserFactory,
Provider<GetServiceUser> getServiceUser,
Provider<ListMembers> listMembers,
ThreadLocalRequestContext tl,
AccountCache accountCache,
GroupControl.Factory groupControlFactory,
GroupResolver groupResolver) {
this.resolver = resolver;
this.genericUserFactory = genericUserFactory;
this.getServiceUser = getServiceUser;
this.listMembers = listMembers;
this.tl = tl;
this.accountCache = accountCache;
this.groupControlFactory = groupControlFactory;
this.groupResolver = groupResolver;
}
ServiceUserInfo getAsServiceUser(PersonIdent committerIdent) throws RestApiException {
StringBuilder committer = new StringBuilder();
committer.append(committerIdent.getName());
committer.append(" <");
committer.append(committerIdent.getEmailAddress());
committer.append("> ");
try {
Account account = resolver.resolve(committer.toString()).asUnique().account();
return getServiceUser
.get()
.apply(new ServiceUserResource(genericUserFactory.create(account.id())))
.value();
} catch (ResourceNotFoundException | UnresolvableAccountException e) {
return null;
} catch (Exception e) {
throw asRestApiException("Cannot get service user", e);
}
}
List<AccountInfo> listOwners(ServiceUserInfo serviceUser)
throws RestApiException, RuntimeException {
if (serviceUser.owner == null) {
return Collections.emptyList();
}
RequestContext context =
new RequestContext() {
@Override
public CurrentUser getUser() {
return new CurrentUser() {
@Override
public GroupMembership getEffectiveGroups() {
return new GroupMembership() {
@Override
public Set<AccountGroup.UUID> intersection(Iterable<AccountGroup.UUID> groupIds) {
return null;
}
@Override
public Set<AccountGroup.UUID> getKnownGroups() {
return null;
}
@Override
public boolean containsAnyOf(Iterable<AccountGroup.UUID> groupIds) {
return true;
}
@Override
public boolean contains(AccountGroup.UUID groupId) {
return true;
}
};
}
@Override
public Object getCacheKey() {
return null;
}
};
}
};
RequestContext old = tl.setContext(context);
try {
GroupDescription.Basic group = groupResolver.parseId(serviceUser.owner.id);
GroupControl ctl = groupControlFactory.controlFor(group);
ListMembers lm = listMembers.get();
GroupResource rsrc = new GroupResource(ctl);
lm.setRecursive(true);
List<AccountInfo> owners = new ArrayList<>();
try {
for (AccountInfo a : lm.apply(rsrc).value()) {
owners.add(a);
}
} catch (Exception e) {
throw asRestApiException("Cannot list group members", e);
}
return owners;
} finally {
tl.setContext(old);
}
}
List<AccountInfo> listActiveOwners(ServiceUserInfo serviceUser)
throws RestApiException, RuntimeException {
List<AccountInfo> activeOwners = new ArrayList<>();
for (AccountInfo owner : listOwners(serviceUser)) {
Optional<AccountState> accountState = accountCache.get(Account.id(owner._accountId));
if (accountState.isPresent() && accountState.get().account().isActive()) {
activeOwners.add(owner);
}
}
return activeOwners;
}
}