Add account predicate that checks if user can see a certain change
This predicate is useful if account queries are used to suggest users in the context of a change, because then users that can't see the change should be filtered out. E.g. this predicate should be used when suggesting assignees for a change. Change-Id: I2c43d04c65718e1e6419cf94c4bbfb21aaf7d9f8 Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
		 Edwin Kempin
					Edwin Kempin
				
			
				
					committed by
					
						 David Pursehouse
						David Pursehouse
					
				
			
			
				
	
			
			
			 David Pursehouse
						David Pursehouse
					
				
			
						parent
						
							7676042a5e
						
					
				
				
					commit
					54664c1508
				
			| @@ -23,6 +23,11 @@ are added to the same query string, they further restrict the | |||||||
| returned results. Search can also be performed by typing only a | returned results. Search can also be performed by typing only a | ||||||
| text with no operator, which will match against a variety of fields. | text with no operator, which will match against a variety of fields. | ||||||
|  |  | ||||||
|  | [[cansee]] | ||||||
|  | cansee:'CHANGE':: | ||||||
|  | + | ||||||
|  | Matches accounts that can see the change 'CHANGE'. | ||||||
|  |  | ||||||
| [[email]] | [[email]] | ||||||
| email:'EMAIL':: | email:'EMAIL':: | ||||||
| + | + | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ import com.google.gerrit.server.index.TimestampRangePredicate; | |||||||
| import com.google.gerrit.server.query.AndPredicate; | import com.google.gerrit.server.query.AndPredicate; | ||||||
| import com.google.gerrit.server.query.NotPredicate; | import com.google.gerrit.server.query.NotPredicate; | ||||||
| import com.google.gerrit.server.query.OrPredicate; | import com.google.gerrit.server.query.OrPredicate; | ||||||
|  | import com.google.gerrit.server.query.PostFilterPredicate; | ||||||
| import com.google.gerrit.server.query.Predicate; | import com.google.gerrit.server.query.Predicate; | ||||||
| import com.google.gerrit.server.query.QueryParseException; | import com.google.gerrit.server.query.QueryParseException; | ||||||
| import com.google.gerrit.server.query.change.AfterPredicate; | import com.google.gerrit.server.query.change.AfterPredicate; | ||||||
| @@ -43,6 +44,8 @@ public class ElasticQueryBuilder { | |||||||
|       return not(p); |       return not(p); | ||||||
|     } else if (p instanceof IndexPredicate) { |     } else if (p instanceof IndexPredicate) { | ||||||
|       return fieldQuery((IndexPredicate<T>) p); |       return fieldQuery((IndexPredicate<T>) p); | ||||||
|  |     } else if (p instanceof PostFilterPredicate) { | ||||||
|  |       return QueryBuilders.matchAllQuery(); | ||||||
|     } else { |     } else { | ||||||
|       throw new QueryParseException("cannot create query for index: " + p); |       throw new QueryParseException("cannot create query for index: " + p); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ import com.google.gerrit.server.index.TimestampRangePredicate; | |||||||
| import com.google.gerrit.server.query.AndPredicate; | import com.google.gerrit.server.query.AndPredicate; | ||||||
| import com.google.gerrit.server.query.NotPredicate; | import com.google.gerrit.server.query.NotPredicate; | ||||||
| import com.google.gerrit.server.query.OrPredicate; | import com.google.gerrit.server.query.OrPredicate; | ||||||
|  | import com.google.gerrit.server.query.PostFilterPredicate; | ||||||
| import com.google.gerrit.server.query.Predicate; | import com.google.gerrit.server.query.Predicate; | ||||||
| import com.google.gerrit.server.query.QueryParseException; | import com.google.gerrit.server.query.QueryParseException; | ||||||
| import java.util.Date; | import java.util.Date; | ||||||
| @@ -76,6 +77,8 @@ public class QueryBuilder<V> { | |||||||
|       return not(p); |       return not(p); | ||||||
|     } else if (p instanceof IndexPredicate) { |     } else if (p instanceof IndexPredicate) { | ||||||
|       return fieldQuery((IndexPredicate<V>) p); |       return fieldQuery((IndexPredicate<V>) p); | ||||||
|  |     } else if (p instanceof PostFilterPredicate) { | ||||||
|  |       return new MatchAllDocsQuery(); | ||||||
|     } else { |     } else { | ||||||
|       throw new QueryParseException("cannot create query for index: " + p); |       throw new QueryParseException("cannot create query for index: " + p); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -40,6 +40,14 @@ public class ChangeFinder { | |||||||
|     this.queryProvider = queryProvider; |     this.queryProvider = queryProvider; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public ChangeControl findOne(String id, CurrentUser user) throws OrmException { | ||||||
|  |     List<ChangeControl> ctls = find(id, user); | ||||||
|  |     if (ctls.size() != 1) { | ||||||
|  |       return null; | ||||||
|  |     } | ||||||
|  |     return ctls.get(0); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Find changes matching the given identifier. |    * Find changes matching the given identifier. | ||||||
|    * |    * | ||||||
|   | |||||||
| @@ -14,21 +14,41 @@ | |||||||
|  |  | ||||||
| package com.google.gerrit.server.index.account; | package com.google.gerrit.server.index.account; | ||||||
|  |  | ||||||
|  | import static com.google.common.base.Preconditions.checkState; | ||||||
|  |  | ||||||
| import com.google.gerrit.reviewdb.client.Account; | import com.google.gerrit.reviewdb.client.Account; | ||||||
| import com.google.gerrit.server.account.AccountState; | import com.google.gerrit.server.account.AccountState; | ||||||
| import com.google.gerrit.server.index.Index; | import com.google.gerrit.server.index.Index; | ||||||
| import com.google.gerrit.server.index.IndexedQuery; | import com.google.gerrit.server.index.IndexedQuery; | ||||||
| import com.google.gerrit.server.index.QueryOptions; | import com.google.gerrit.server.index.QueryOptions; | ||||||
| import com.google.gerrit.server.query.DataSource; | import com.google.gerrit.server.query.DataSource; | ||||||
|  | import com.google.gerrit.server.query.Matchable; | ||||||
| import com.google.gerrit.server.query.Predicate; | import com.google.gerrit.server.query.Predicate; | ||||||
| import com.google.gerrit.server.query.QueryParseException; | import com.google.gerrit.server.query.QueryParseException; | ||||||
|  | import com.google.gwtorm.server.OrmException; | ||||||
|  |  | ||||||
| public class IndexedAccountQuery extends IndexedQuery<Account.Id, AccountState> | public class IndexedAccountQuery extends IndexedQuery<Account.Id, AccountState> | ||||||
|     implements DataSource<AccountState> { |     implements DataSource<AccountState>, Matchable<AccountState> { | ||||||
|  |  | ||||||
|   public IndexedAccountQuery( |   public IndexedAccountQuery( | ||||||
|       Index<Account.Id, AccountState> index, Predicate<AccountState> pred, QueryOptions opts) |       Index<Account.Id, AccountState> index, Predicate<AccountState> pred, QueryOptions opts) | ||||||
|       throws QueryParseException { |       throws QueryParseException { | ||||||
|     super(index, pred, opts.convertForBackend()); |     super(index, pred, opts.convertForBackend()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public boolean match(AccountState accountState) throws OrmException { | ||||||
|  |     Predicate<AccountState> pred = getChild(0); | ||||||
|  |     checkState( | ||||||
|  |         pred.isMatchable(), | ||||||
|  |         "match invoked, but child predicate %s doesn't implement %s", | ||||||
|  |         pred, | ||||||
|  |         Matchable.class.getName()); | ||||||
|  |     return pred.asMatchable().match(accountState); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public int getCost() { | ||||||
|  |     return 1; | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,21 @@ | |||||||
|  | // Copyright (C) 2016 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.google.gerrit.server.query; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Matches all documents in the index, with additional filtering done in the subclass's {@code | ||||||
|  |  * match} method. | ||||||
|  |  */ | ||||||
|  | public abstract class PostFilterPredicate<T> extends Predicate<T> implements Matchable<T> {} | ||||||
| @@ -22,8 +22,11 @@ import com.google.gerrit.server.account.AccountState; | |||||||
| import com.google.gerrit.server.index.FieldDef; | import com.google.gerrit.server.index.FieldDef; | ||||||
| import com.google.gerrit.server.index.IndexPredicate; | import com.google.gerrit.server.index.IndexPredicate; | ||||||
| import com.google.gerrit.server.index.account.AccountField; | import com.google.gerrit.server.index.account.AccountField; | ||||||
|  | import com.google.gerrit.server.notedb.ChangeNotes; | ||||||
|  | import com.google.gerrit.server.query.Matchable; | ||||||
| import com.google.gerrit.server.query.Predicate; | import com.google.gerrit.server.query.Predicate; | ||||||
| import com.google.gerrit.server.query.QueryBuilder; | import com.google.gerrit.server.query.QueryBuilder; | ||||||
|  | import com.google.gwtorm.server.OrmException; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| public class AccountPredicates { | public class AccountPredicates { | ||||||
| @@ -85,7 +88,14 @@ public class AccountPredicates { | |||||||
|     return new AccountPredicate(AccountField.WATCHED_PROJECT, project.get()); |     return new AccountPredicate(AccountField.WATCHED_PROJECT, project.get()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static class AccountPredicate extends IndexPredicate<AccountState> { |   static Predicate<AccountState> cansee( | ||||||
|  |       AccountQueryBuilder.Arguments args, ChangeNotes changeNotes) { | ||||||
|  |     return new CanSeeChangePredicate( | ||||||
|  |         args.db, args.changeControlFactory, args.userFactory, changeNotes); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static class AccountPredicate extends IndexPredicate<AccountState> | ||||||
|  |       implements Matchable<AccountState> { | ||||||
|     AccountPredicate(FieldDef<AccountState, ?> def, String value) { |     AccountPredicate(FieldDef<AccountState, ?> def, String value) { | ||||||
|       super(def, value); |       super(def, value); | ||||||
|     } |     } | ||||||
| @@ -93,6 +103,16 @@ public class AccountPredicates { | |||||||
|     AccountPredicate(FieldDef<AccountState, ?> def, String name, String value) { |     AccountPredicate(FieldDef<AccountState, ?> def, String name, String value) { | ||||||
|       super(def, name, value); |       super(def, name, value); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean match(AccountState object) throws OrmException { | ||||||
|  |       return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int getCost() { | ||||||
|  |       return 1; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private AccountPredicates() {} |   private AccountPredicates() {} | ||||||
|   | |||||||
| @@ -19,13 +19,17 @@ import com.google.common.collect.Lists; | |||||||
| import com.google.common.primitives.Ints; | import com.google.common.primitives.Ints; | ||||||
| import com.google.gerrit.common.errors.NotSignedInException; | import com.google.gerrit.common.errors.NotSignedInException; | ||||||
| import com.google.gerrit.reviewdb.client.Account; | import com.google.gerrit.reviewdb.client.Account; | ||||||
|  | import com.google.gerrit.reviewdb.server.ReviewDb; | ||||||
|  | import com.google.gerrit.server.ChangeFinder; | ||||||
| import com.google.gerrit.server.CurrentUser; | import com.google.gerrit.server.CurrentUser; | ||||||
| import com.google.gerrit.server.IdentifiedUser; | import com.google.gerrit.server.IdentifiedUser; | ||||||
| import com.google.gerrit.server.account.AccountState; | import com.google.gerrit.server.account.AccountState; | ||||||
|  | import com.google.gerrit.server.project.ChangeControl; | ||||||
| import com.google.gerrit.server.query.LimitPredicate; | import com.google.gerrit.server.query.LimitPredicate; | ||||||
| import com.google.gerrit.server.query.Predicate; | import com.google.gerrit.server.query.Predicate; | ||||||
| import com.google.gerrit.server.query.QueryBuilder; | import com.google.gerrit.server.query.QueryBuilder; | ||||||
| import com.google.gerrit.server.query.QueryParseException; | import com.google.gerrit.server.query.QueryParseException; | ||||||
|  | import com.google.gwtorm.server.OrmException; | ||||||
| import com.google.inject.Inject; | import com.google.inject.Inject; | ||||||
| import com.google.inject.Provider; | import com.google.inject.Provider; | ||||||
| import com.google.inject.ProvisionException; | import com.google.inject.ProvisionException; | ||||||
| @@ -43,11 +47,25 @@ public class AccountQueryBuilder extends QueryBuilder<AccountState> { | |||||||
|       new QueryBuilder.Definition<>(AccountQueryBuilder.class); |       new QueryBuilder.Definition<>(AccountQueryBuilder.class); | ||||||
|  |  | ||||||
|   public static class Arguments { |   public static class Arguments { | ||||||
|  |     final Provider<ReviewDb> db; | ||||||
|  |     final ChangeFinder changeFinder; | ||||||
|  |     final ChangeControl.GenericFactory changeControlFactory; | ||||||
|  |     final IdentifiedUser.GenericFactory userFactory; | ||||||
|  |  | ||||||
|     private final Provider<CurrentUser> self; |     private final Provider<CurrentUser> self; | ||||||
|  |  | ||||||
|     @Inject |     @Inject | ||||||
|     public Arguments(Provider<CurrentUser> self) { |     public Arguments( | ||||||
|  |         Provider<CurrentUser> self, | ||||||
|  |         Provider<ReviewDb> db, | ||||||
|  |         ChangeFinder changeFinder, | ||||||
|  |         ChangeControl.GenericFactory changeControlFactory, | ||||||
|  |         IdentifiedUser.GenericFactory userFactory) { | ||||||
|       this.self = self; |       this.self = self; | ||||||
|  |       this.db = db; | ||||||
|  |       this.changeFinder = changeFinder; | ||||||
|  |       this.changeControlFactory = changeControlFactory; | ||||||
|  |       this.userFactory = userFactory; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     IdentifiedUser getIdentifiedUser() throws QueryParseException { |     IdentifiedUser getIdentifiedUser() throws QueryParseException { | ||||||
| @@ -79,6 +97,16 @@ public class AccountQueryBuilder extends QueryBuilder<AccountState> { | |||||||
|     this.args = args; |     this.args = args; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @Operator | ||||||
|  |   public Predicate<AccountState> cansee(String change) throws QueryParseException, OrmException { | ||||||
|  |     ChangeControl changeControl = args.changeFinder.findOne(change, args.getUser()); | ||||||
|  |     if (changeControl == null || !changeControl.isVisible(args.db.get())) { | ||||||
|  |       throw error(String.format("change %s not found", change)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return AccountPredicates.cansee(args, changeControl.getNotes()); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   @Operator |   @Operator | ||||||
|   public Predicate<AccountState> email(String email) { |   public Predicate<AccountState> email(String email) { | ||||||
|     return AccountPredicates.email(email); |     return AccountPredicates.email(email); | ||||||
|   | |||||||
| @@ -0,0 +1,77 @@ | |||||||
|  | // Copyright (C) 2016 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.google.gerrit.server.query.account; | ||||||
|  |  | ||||||
|  | import com.google.gerrit.reviewdb.server.ReviewDb; | ||||||
|  | import com.google.gerrit.server.IdentifiedUser; | ||||||
|  | import com.google.gerrit.server.account.AccountState; | ||||||
|  | import com.google.gerrit.server.notedb.ChangeNotes; | ||||||
|  | import com.google.gerrit.server.project.ChangeControl; | ||||||
|  | import com.google.gerrit.server.query.PostFilterPredicate; | ||||||
|  | import com.google.gerrit.server.query.Predicate; | ||||||
|  | import com.google.gwtorm.server.OrmException; | ||||||
|  | import com.google.inject.Provider; | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.Objects; | ||||||
|  |  | ||||||
|  | public class CanSeeChangePredicate extends PostFilterPredicate<AccountState> { | ||||||
|  |   private final Provider<ReviewDb> db; | ||||||
|  |   private final ChangeControl.GenericFactory changeControlFactory; | ||||||
|  |   private final IdentifiedUser.GenericFactory userFactory; | ||||||
|  |   private final ChangeNotes changeNotes; | ||||||
|  |  | ||||||
|  |   CanSeeChangePredicate( | ||||||
|  |       Provider<ReviewDb> db, | ||||||
|  |       ChangeControl.GenericFactory changeControlFactory, | ||||||
|  |       IdentifiedUser.GenericFactory userFactory, | ||||||
|  |       ChangeNotes changeNotes) { | ||||||
|  |     this.db = db; | ||||||
|  |     this.changeControlFactory = changeControlFactory; | ||||||
|  |     this.userFactory = userFactory; | ||||||
|  |     this.changeNotes = changeNotes; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public boolean match(AccountState accountState) throws OrmException { | ||||||
|  |     return changeControlFactory | ||||||
|  |         .controlFor(changeNotes, userFactory.create(accountState.getAccount().getId())) | ||||||
|  |         .isVisible(db.get()); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public int getCost() { | ||||||
|  |     return 1; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public Predicate<AccountState> copy(Collection<? extends Predicate<AccountState>> children) { | ||||||
|  |     return new CanSeeChangePredicate(db, changeControlFactory, userFactory, changeNotes); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public int hashCode() { | ||||||
|  |     return Objects.hash(changeNotes.getChange().getChangeId()); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public boolean equals(Object other) { | ||||||
|  |     if (other == null) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     return getClass() == other.getClass() | ||||||
|  |         && changeNotes.getChange().getChangeId() | ||||||
|  |             == ((CanSeeChangePredicate) other).changeNotes.getChange().getChangeId(); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -19,12 +19,23 @@ import static java.util.stream.Collectors.toList; | |||||||
| import static org.junit.Assert.fail; | import static org.junit.Assert.fail; | ||||||
|  |  | ||||||
| import com.google.common.collect.ImmutableList; | import com.google.common.collect.ImmutableList; | ||||||
|  | import com.google.common.collect.ImmutableMap; | ||||||
| import com.google.common.collect.Iterables; | import com.google.common.collect.Iterables; | ||||||
|  | import com.google.gerrit.common.data.Permission; | ||||||
| import com.google.gerrit.extensions.api.GerritApi; | import com.google.gerrit.extensions.api.GerritApi; | ||||||
|  | import com.google.gerrit.extensions.api.access.AccessSectionInfo; | ||||||
|  | import com.google.gerrit.extensions.api.access.PermissionInfo; | ||||||
|  | import com.google.gerrit.extensions.api.access.PermissionRuleInfo; | ||||||
|  | import com.google.gerrit.extensions.api.access.ProjectAccessInput; | ||||||
| import com.google.gerrit.extensions.api.accounts.Accounts.QueryRequest; | import com.google.gerrit.extensions.api.accounts.Accounts.QueryRequest; | ||||||
|  | import com.google.gerrit.extensions.api.groups.GroupInput; | ||||||
|  | import com.google.gerrit.extensions.api.projects.ProjectInput; | ||||||
| import com.google.gerrit.extensions.client.ListAccountsOption; | import com.google.gerrit.extensions.client.ListAccountsOption; | ||||||
| import com.google.gerrit.extensions.client.ProjectWatchInfo; | import com.google.gerrit.extensions.client.ProjectWatchInfo; | ||||||
| import com.google.gerrit.extensions.common.AccountInfo; | import com.google.gerrit.extensions.common.AccountInfo; | ||||||
|  | import com.google.gerrit.extensions.common.ChangeInfo; | ||||||
|  | import com.google.gerrit.extensions.common.ChangeInput; | ||||||
|  | import com.google.gerrit.extensions.common.GroupInfo; | ||||||
| import com.google.gerrit.extensions.restapi.ResourceNotFoundException; | import com.google.gerrit.extensions.restapi.ResourceNotFoundException; | ||||||
| import com.google.gerrit.extensions.restapi.RestApiException; | import com.google.gerrit.extensions.restapi.RestApiException; | ||||||
| import com.google.gerrit.lifecycle.LifecycleManager; | import com.google.gerrit.lifecycle.LifecycleManager; | ||||||
| @@ -54,6 +65,7 @@ import com.google.inject.util.Providers; | |||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
|  | import java.util.HashMap; | ||||||
| import java.util.Iterator; | import java.util.Iterator; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import org.eclipse.jgit.lib.Config; | import org.eclipse.jgit.lib.Config; | ||||||
| @@ -272,6 +284,22 @@ public abstract class AbstractQueryAccountsTest extends GerritServerTests { | |||||||
|     assertQuery("name:" + quote(user2.name), user2); |     assertQuery("name:" + quote(user2.name), user2); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @Test | ||||||
|  |   public void byCansee() throws Exception { | ||||||
|  |     String domain = name("test.com"); | ||||||
|  |     AccountInfo user1 = newAccountWithEmail("account1", "account1@" + domain); | ||||||
|  |     AccountInfo user2 = newAccountWithEmail("account2", "account2@" + domain); | ||||||
|  |     AccountInfo user3 = newAccountWithEmail("account3", "account3@" + domain); | ||||||
|  |  | ||||||
|  |     Project.NameKey p = createProject(name("p")); | ||||||
|  |     ChangeInfo c = createChange(p); | ||||||
|  |     assertQuery("name:" + domain + " cansee:" + c.changeId, user1, user2, user3); | ||||||
|  |  | ||||||
|  |     GroupInfo group = createGroup(name("group"), user1, user2); | ||||||
|  |     blockRead(p, group); | ||||||
|  |     assertQuery("name:" + domain + " cansee:" + c.changeId, user3); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
|   public void byWatchedProject() throws Exception { |   public void byWatchedProject() throws Exception { | ||||||
|     Project.NameKey p = createProject(name("p")); |     Project.NameKey p = createProject(name("p")); | ||||||
| @@ -429,10 +457,43 @@ public abstract class AbstractQueryAccountsTest extends GerritServerTests { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   protected Project.NameKey createProject(String name) throws RestApiException { |   protected Project.NameKey createProject(String name) throws RestApiException { | ||||||
|     gApi.projects().create(name); |     ProjectInput in = new ProjectInput(); | ||||||
|  |     in.name = name; | ||||||
|  |     in.createEmptyCommit = true; | ||||||
|  |     gApi.projects().create(in); | ||||||
|     return new Project.NameKey(name); |     return new Project.NameKey(name); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   protected void blockRead(Project.NameKey project, GroupInfo group) throws RestApiException { | ||||||
|  |     ProjectAccessInput in = new ProjectAccessInput(); | ||||||
|  |     in.add = new HashMap<>(); | ||||||
|  |  | ||||||
|  |     AccessSectionInfo a = new AccessSectionInfo(); | ||||||
|  |     PermissionInfo p = new PermissionInfo(null, null); | ||||||
|  |     p.rules = | ||||||
|  |         ImmutableMap.of(group.id, new PermissionRuleInfo(PermissionRuleInfo.Action.BLOCK, false)); | ||||||
|  |     a.permissions = ImmutableMap.of(Permission.READ, p); | ||||||
|  |     in.add = ImmutableMap.of("refs/*", a); | ||||||
|  |  | ||||||
|  |     gApi.projects().name(project.get()).access(in); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   protected ChangeInfo createChange(Project.NameKey project) throws RestApiException { | ||||||
|  |     ChangeInput in = new ChangeInput(); | ||||||
|  |     in.subject = "A change"; | ||||||
|  |     in.project = project.get(); | ||||||
|  |     in.branch = "master"; | ||||||
|  |     return gApi.changes().create(in).get(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   protected GroupInfo createGroup(String name, AccountInfo... members) throws RestApiException { | ||||||
|  |     GroupInput in = new GroupInput(); | ||||||
|  |     in.name = name; | ||||||
|  |     in.members = | ||||||
|  |         Arrays.asList(members).stream().map(a -> String.valueOf(a._accountId)).collect(toList()); | ||||||
|  |     return gApi.groups().create(in).get(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   protected void watch(AccountInfo account, Project.NameKey project, String filter) |   protected void watch(AccountInfo account, Project.NameKey project, String filter) | ||||||
|       throws RestApiException { |       throws RestApiException { | ||||||
|     List<ProjectWatchInfo> projectsToWatch = new ArrayList<>(); |     List<ProjectWatchInfo> projectsToWatch = new ArrayList<>(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user