| // 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 com.google.gerrit.common.data.GroupDescription; |
| import com.google.gerrit.extensions.common.AccountInfo; |
| import com.google.gerrit.extensions.restapi.MethodNotAllowedException; |
| import com.google.gerrit.extensions.restapi.ResourceNotFoundException; |
| import com.google.gerrit.extensions.restapi.RestApiException; |
| import com.google.gerrit.reviewdb.client.Account; |
| import com.google.gerrit.reviewdb.client.AccountGroup; |
| 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.permissions.PermissionBackendException; |
| 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.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Optional; |
| import java.util.Set; |
| import org.eclipse.jgit.errors.ConfigInvalidException; |
| 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 ConfigInvalidException, IOException, PermissionBackendException, 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().getAccount(); |
| return getServiceUser |
| .get() |
| .apply(new ServiceUserResource(genericUserFactory.create(account.getId()))); |
| } catch (ResourceNotFoundException | UnresolvableAccountException e) { |
| return null; |
| } |
| } |
| |
| List<AccountInfo> listOwners(ServiceUserInfo serviceUser) |
| throws MethodNotAllowedException, PermissionBackendException { |
| 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<>(); |
| for (AccountInfo a : lm.apply(rsrc)) { |
| owners.add(a); |
| } |
| return owners; |
| } finally { |
| tl.setContext(old); |
| } |
| } |
| |
| List<AccountInfo> listActiveOwners(ServiceUserInfo serviceUser) |
| throws MethodNotAllowedException, PermissionBackendException { |
| List<AccountInfo> activeOwners = new ArrayList<>(); |
| for (AccountInfo owner : listOwners(serviceUser)) { |
| Optional<AccountState> accountState = accountCache.get(new Account.Id(owner._accountId)); |
| if (accountState.isPresent() && accountState.get().getAccount().isActive()) { |
| activeOwners.add(owner); |
| } |
| } |
| return activeOwners; |
| } |
| } |