Merge changes If69cf4d0,Ic2aad5eb * changes: Move emailOnlyAuthors and emailiOnlyAttentionSetIfEnabled to isRecipientAllowed. Remove NotificationEmail class.
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt index 348649d..cf89982 100644 --- a/Documentation/access-control.txt +++ b/Documentation/access-control.txt
@@ -1417,8 +1417,8 @@ Allow to link:cmd-set-account.html[modify accounts over the ssh prompt]. This capability allows the granted group members to modify any user account -setting. In addition this capability is required to view secondary emails -of other accounts. +setting. In addition this capability allows to view secondary emails of other +accounts. [[capability_priority]] === Priority @@ -1520,7 +1520,8 @@ This capability allows to view all accounts but not all account data. E.g. secondary emails of all accounts can only be viewed with the -link:#capability_modifyAccount[Modify Account] capability. +link:#capability_viewSecondaryEmails[View Secondary Emails] capability +or the link:#capability_modifyAccount[Modify Account] capability. [[capability_viewCaches]] @@ -1553,6 +1554,15 @@ link:cmd-show-queue.html[look at the Gerrit task queue via ssh]. +[[capability_viewSecondaryEmails]] +=== View Secondary Emails + +Allows viewing secondary emails of other accounts. + +Users with the link:#capability_modifyAccount[Modify Account] capability have +this capbility implicitly. + + [[reference]] == Permission evaluation reference
diff --git a/Documentation/rest-api-accounts.txt b/Documentation/rest-api-accounts.txt index 7e06e4a..7646777 100644 --- a/Documentation/rest-api-accounts.txt +++ b/Documentation/rest-api-accounts.txt
@@ -2316,6 +2316,9 @@ link:access-control.html#capability_viewPlugins[View Plugins] capability. |`viewQueue` |not set if `false`|Whether the user has the link:access-control.html#capability_viewQueue[View Queue] capability. +|`viewSecondaryEmails`|not set if `false`|Whether the user has the +link:access-control.html#capability_viewSecondaryEmails[View Secondary +Emails] capability. |================================= [[contributor-agreement-info]]
diff --git a/Documentation/user-search.txt b/Documentation/user-search.txt index 4293fd6..67b8d75 100644 --- a/Documentation/user-search.txt +++ b/Documentation/user-search.txt
@@ -647,7 +647,7 @@ last update (comment or patch set) from the change owner. [[author]] -author:'AUTHOR':: +author:'AUTHOR', a:'AUTHOR':: + Changes where 'AUTHOR' is the author of the current patch set. 'AUTHOR' may be the author's exact email address, or part of the name or email address. The
diff --git a/java/com/google/gerrit/common/data/GlobalCapability.java b/java/com/google/gerrit/common/data/GlobalCapability.java index c7a9a63..23151c2 100644 --- a/java/com/google/gerrit/common/data/GlobalCapability.java +++ b/java/com/google/gerrit/common/data/GlobalCapability.java
@@ -129,6 +129,9 @@ /** Can view all pending tasks in the queue (not just the filtered set). */ public static final String VIEW_QUEUE = "viewQueue"; + /** Can view secondary emails of other accounts. */ + public static final String VIEW_SECONDARY_EMAILS = "viewSecondaryEmails"; + private static final List<String> NAMES_ALL; private static final List<String> NAMES_LC; private static final String[] RANGE_NAMES = { @@ -160,6 +163,7 @@ NAMES_ALL.add(VIEW_CONNECTIONS); NAMES_ALL.add(VIEW_PLUGINS); NAMES_ALL.add(VIEW_QUEUE); + NAMES_ALL.add(VIEW_SECONDARY_EMAILS); NAMES_LC = new ArrayList<>(NAMES_ALL.size()); for (String name : NAMES_ALL) {
diff --git a/java/com/google/gerrit/server/account/AccountResolver.java b/java/com/google/gerrit/server/account/AccountResolver.java index 1818b1b..2020d2f 100644 --- a/java/com/google/gerrit/server/account/AccountResolver.java +++ b/java/com/google/gerrit/server/account/AccountResolver.java
@@ -434,16 +434,16 @@ @Override public Stream<AccountState> search(String input, CurrentUser asUser) throws IOException { - boolean canSeeSecondaryEmails = false; + boolean canViewSecondaryEmails = false; try { - if (permissionBackend.user(asUser).test(GlobalPermission.MODIFY_ACCOUNT)) { - canSeeSecondaryEmails = true; + if (permissionBackend.user(asUser).test(GlobalPermission.VIEW_SECONDARY_EMAILS)) { + canViewSecondaryEmails = true; } } catch (PermissionBackendException e) { // remains false } - if (canSeeSecondaryEmails) { + if (canViewSecondaryEmails) { return toAccountStates(emails.getAccountFor(input)); } @@ -549,15 +549,15 @@ // up with a reasonable result list. // TODO(dborowitz): This doesn't match the documentation; consider whether it's possible to be // more strict here. - boolean canSeeSecondaryEmails = false; + boolean canViewSecondaryEmails = false; try { - if (permissionBackend.user(asUser).test(GlobalPermission.MODIFY_ACCOUNT)) { - canSeeSecondaryEmails = true; + if (permissionBackend.user(asUser).test(GlobalPermission.VIEW_SECONDARY_EMAILS)) { + canViewSecondaryEmails = true; } } catch (PermissionBackendException e) { // remains false } - return accountQueryProvider.get().byDefault(input, canSeeSecondaryEmails).stream(); + return accountQueryProvider.get().byDefault(input, canViewSecondaryEmails).stream(); } @Override
diff --git a/java/com/google/gerrit/server/account/InternalAccountDirectory.java b/java/com/google/gerrit/server/account/InternalAccountDirectory.java index b895834..64b8ec0 100644 --- a/java/com/google/gerrit/server/account/InternalAccountDirectory.java +++ b/java/com/google/gerrit/server/account/InternalAccountDirectory.java
@@ -96,12 +96,12 @@ return; } - boolean canModifyAccount = false; + boolean canViewSecondaryEmails = false; Account.Id currentUserId = null; if (self.get().isIdentifiedUser()) { currentUserId = self.get().getAccountId(); - if (permissionBackend.currentUser().test(GlobalPermission.MODIFY_ACCOUNT)) { - canModifyAccount = true; + if (permissionBackend.currentUser().test(GlobalPermission.VIEW_SECONDARY_EMAILS)) { + canViewSecondaryEmails = true; } } @@ -115,7 +115,7 @@ if (state != null) { if (!options.contains(FillOptions.SECONDARY_EMAILS) || Objects.equals(currentUserId, state.account().id()) - || canModifyAccount) { + || canViewSecondaryEmails) { fill(info, accountStates.get(id), options); } else { // user is not allowed to see secondary emails
diff --git a/java/com/google/gerrit/server/config/CapabilityConstants.java b/java/com/google/gerrit/server/config/CapabilityConstants.java index 59819bb..1f799c6 100644 --- a/java/com/google/gerrit/server/config/CapabilityConstants.java +++ b/java/com/google/gerrit/server/config/CapabilityConstants.java
@@ -45,4 +45,5 @@ public String viewConnections; public String viewPlugins; public String viewQueue; + public String viewSecondaryEmails; }
diff --git a/java/com/google/gerrit/server/index/account/AccountField.java b/java/com/google/gerrit/server/index/account/AccountField.java index cc86ffc..e675003 100644 --- a/java/com/google/gerrit/server/index/account/AccountField.java +++ b/java/com/google/gerrit/server/index/account/AccountField.java
@@ -66,7 +66,8 @@ * External IDs. * * <p>This field includes secondary emails. Use this field only if the current user is allowed to - * see secondary emails (requires the {@link GlobalCapability#MODIFY_ACCOUNT} capability). + * see secondary emails (requires the {@link GlobalCapability#VIEW_SECONDARY_EMAILS} capability or + * the {@link GlobalCapability#MODIFY_ACCOUNT} capability). */ public static final IndexedField<AccountState, Iterable<String>> EXTERNAL_ID_FIELD = IndexedField.<AccountState>iterableStringBuilder("ExternalId") @@ -80,8 +81,9 @@ * Fuzzy prefix match on name and email parts. * * <p>This field includes parts from the secondary emails. Use this field only if the current user - * is allowed to see secondary emails (requires the {@link GlobalCapability#MODIFY_ACCOUNT} - * capability). + * is allowed to see secondary emails (requires requires the {@link + * GlobalCapability#VIEW_SECONDARY_EMAILS} capability or the {@link + * GlobalCapability#MODIFY_ACCOUNT} capability). * * <p>Use the {@link AccountField#NAME_PART_NO_SECONDARY_EMAIL_SPEC} if the current user can't see * secondary emails.
diff --git a/java/com/google/gerrit/server/permissions/DefaultPermissionBackend.java b/java/com/google/gerrit/server/permissions/DefaultPermissionBackend.java index bf4d05a..a4ee052 100644 --- a/java/com/google/gerrit/server/permissions/DefaultPermissionBackend.java +++ b/java/com/google/gerrit/server/permissions/DefaultPermissionBackend.java
@@ -195,12 +195,17 @@ case MODIFY_ACCOUNT: case READ_AS: case STREAM_EVENTS: + case VIEW_ACCESS: case VIEW_ALL_ACCOUNTS: case VIEW_CONNECTIONS: case VIEW_PLUGINS: - case VIEW_ACCESS: return has(globalPermissionName(perm)) || isAdmin(); + case VIEW_SECONDARY_EMAILS: + return has(globalPermissionName(perm)) + || has(globalPermissionName(GlobalPermission.MODIFY_ACCOUNT)) + || isAdmin(); + case ACCESS_DATABASE: case RUN_AS: return has(globalPermissionName(perm));
diff --git a/java/com/google/gerrit/server/permissions/DefaultPermissionMappings.java b/java/com/google/gerrit/server/permissions/DefaultPermissionMappings.java index da24dcd..958de1b 100644 --- a/java/com/google/gerrit/server/permissions/DefaultPermissionMappings.java +++ b/java/com/google/gerrit/server/permissions/DefaultPermissionMappings.java
@@ -61,6 +61,7 @@ .put(GlobalPermission.VIEW_CONNECTIONS, GlobalCapability.VIEW_CONNECTIONS) .put(GlobalPermission.VIEW_PLUGINS, GlobalCapability.VIEW_PLUGINS) .put(GlobalPermission.VIEW_QUEUE, GlobalCapability.VIEW_QUEUE) + .put(GlobalPermission.VIEW_SECONDARY_EMAILS, GlobalCapability.VIEW_SECONDARY_EMAILS) .build(); static {
diff --git a/java/com/google/gerrit/server/permissions/GlobalPermission.java b/java/com/google/gerrit/server/permissions/GlobalPermission.java index c0b44e5..3429978 100644 --- a/java/com/google/gerrit/server/permissions/GlobalPermission.java +++ b/java/com/google/gerrit/server/permissions/GlobalPermission.java
@@ -58,7 +58,8 @@ VIEW_CACHES, VIEW_CONNECTIONS, VIEW_PLUGINS, - VIEW_QUEUE; + VIEW_QUEUE, + VIEW_SECONDARY_EMAILS; private static final FluentLogger logger = FluentLogger.forEnclosingClass();
diff --git a/java/com/google/gerrit/server/query/account/AccountQueryBuilder.java b/java/com/google/gerrit/server/query/account/AccountQueryBuilder.java index d5c4a97..2f4a923 100644 --- a/java/com/google/gerrit/server/query/account/AccountQueryBuilder.java +++ b/java/com/google/gerrit/server/query/account/AccountQueryBuilder.java
@@ -151,7 +151,7 @@ @Operator public Predicate<AccountState> email(String email) throws PermissionBackendException, QueryParseException { - if (canSeeSecondaryEmails()) { + if (canViewSecondaryEmails()) { return AccountPredicates.emailIncludingSecondaryEmails(email); } @@ -185,7 +185,7 @@ @Operator public Predicate<AccountState> name(String name) throws PermissionBackendException, QueryParseException { - if (canSeeSecondaryEmails()) { + if (canViewSecondaryEmails()) { return AccountPredicates.equalsNameIncludingSecondaryEmails(name); } @@ -210,7 +210,7 @@ @Override protected Predicate<AccountState> defaultField(String query) { Predicate<AccountState> defaultPredicate = - AccountPredicates.defaultPredicate(args.schema(), checkedCanSeeSecondaryEmails(), query); + AccountPredicates.defaultPredicate(args.schema(), checkedCanViewSecondaryEmails(), query); if (query.startsWith("cansee:")) { try { return cansee(query.substring(7)); @@ -233,13 +233,13 @@ return args.getIdentifiedUser().getAccountId(); } - private boolean canSeeSecondaryEmails() throws PermissionBackendException, QueryParseException { - return args.permissionBackend.user(args.getUser()).test(GlobalPermission.MODIFY_ACCOUNT); + private boolean canViewSecondaryEmails() throws PermissionBackendException, QueryParseException { + return args.permissionBackend.user(args.getUser()).test(GlobalPermission.VIEW_SECONDARY_EMAILS); } - private boolean checkedCanSeeSecondaryEmails() { + private boolean checkedCanViewSecondaryEmails() { try { - return canSeeSecondaryEmails(); + return canViewSecondaryEmails(); } catch (PermissionBackendException e) { logger.atSevere().withCause(e).log("Permission check failed"); return false;
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java index ef067a1..57b59ef 100644 --- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java +++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -1539,6 +1539,11 @@ } @Operator + public Predicate<ChangeData> a(String who) throws QueryParseException { + return author(who); + } + + @Operator public Predicate<ChangeData> author(String who) throws QueryParseException { return getAuthorOrCommitterPredicate( who.trim(), ChangePredicates::exactAuthor, ChangePredicates::author);
diff --git a/java/com/google/gerrit/server/restapi/account/GetEmails.java b/java/com/google/gerrit/server/restapi/account/GetEmails.java index 4d70eb9..a518532 100644 --- a/java/com/google/gerrit/server/restapi/account/GetEmails.java +++ b/java/com/google/gerrit/server/restapi/account/GetEmails.java
@@ -52,7 +52,7 @@ public Response<List<EmailInfo>> apply(AccountResource rsrc) throws AuthException, PermissionBackendException { if (!self.get().hasSameAccountId(rsrc.getUser())) { - permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT); + permissionBackend.currentUser().check(GlobalPermission.VIEW_SECONDARY_EMAILS); } return Response.ok( rsrc.getUser().getEmailAddresses().stream()
diff --git a/java/com/google/gerrit/server/restapi/account/QueryAccounts.java b/java/com/google/gerrit/server/restapi/account/QueryAccounts.java index 79737f3..9fc0c42 100644 --- a/java/com/google/gerrit/server/restapi/account/QueryAccounts.java +++ b/java/com/google/gerrit/server/restapi/account/QueryAccounts.java
@@ -173,7 +173,7 @@ } boolean modifyAccountCapabilityChecked = false; if (options.contains(ListAccountsOption.ALL_EMAILS)) { - permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT); + permissionBackend.currentUser().check(GlobalPermission.VIEW_SECONDARY_EMAILS); modifyAccountCapabilityChecked = true; fillOptions.add(FillOptions.EMAIL); fillOptions.add(FillOptions.SECONDARY_EMAILS); @@ -185,7 +185,7 @@ if (modifyAccountCapabilityChecked) { fillOptions.add(FillOptions.SECONDARY_EMAILS); } else { - if (permissionBackend.currentUser().test(GlobalPermission.MODIFY_ACCOUNT)) { + if (permissionBackend.currentUser().test(GlobalPermission.VIEW_SECONDARY_EMAILS)) { fillOptions.add(FillOptions.SECONDARY_EMAILS); } }
diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java index a9a0b70..dd04200 100644 --- a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java +++ b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
@@ -991,14 +991,15 @@ } @Test - public void cannotGetEmailsOfOtherAccountWithoutModifyAccount() throws Exception { + public void cannotGetEmailsOfOtherAccountWithoutViewSecondaryEmailsAndWithoutModifyAccount() + throws Exception { String email = "preferred2@example.com"; TestAccount foo = accountCreator.create(name("foo"), email, "Foo", null); requestScopeOperations.setApiUser(user.id()); AuthException thrown = assertThrows(AuthException.class, () -> gApi.accounts().id(foo.id().get()).getEmails()); - assertThat(thrown).hasMessageThat().contains("modify account not permitted"); + assertThat(thrown).hasMessageThat().contains("view secondary emails not permitted"); } @Test
diff --git a/javatests/com/google/gerrit/acceptance/api/change/QueryChangesIT.java b/javatests/com/google/gerrit/acceptance/api/change/QueryChangesIT.java index 43c8684..3f3ad37 100644 --- a/javatests/com/google/gerrit/acceptance/api/change/QueryChangesIT.java +++ b/javatests/com/google/gerrit/acceptance/api/change/QueryChangesIT.java
@@ -549,6 +549,19 @@ @Test public void changesFoundWhenQueryingBySecondaryEmailWithModifyAccountCapability() throws Exception { + testCangesFoundWhenQueryingBySecondaryEmailWithModifyAccountCapability( + GlobalCapability.MODIFY_ACCOUNT); + } + + @Test + public void changesFoundWhenQueryingBySecondaryEmailWithViewSecondaryEmailsCapability() + throws Exception { + testCangesFoundWhenQueryingBySecondaryEmailWithModifyAccountCapability( + GlobalCapability.VIEW_SECONDARY_EMAILS); + } + + private void testCangesFoundWhenQueryingBySecondaryEmailWithModifyAccountCapability( + String globalCapability) throws Exception { String secondaryOwnerEmail = "owner-secondary@example.com"; Account.Id owner = accountOperations @@ -574,7 +587,7 @@ projectOperations .allProjectsForUpdate() - .add(allowCapability(GlobalCapability.MODIFY_ACCOUNT).group(REGISTERED_USERS)) + .add(allowCapability(globalCapability).group(REGISTERED_USERS)) .update(); requestScopeOperations.setApiUser(user.id());
diff --git a/javatests/com/google/gerrit/acceptance/rest/account/CapabilityInfo.java b/javatests/com/google/gerrit/acceptance/rest/account/CapabilityInfo.java index 7598062..3ce6d8d 100644 --- a/javatests/com/google/gerrit/acceptance/rest/account/CapabilityInfo.java +++ b/javatests/com/google/gerrit/acceptance/rest/account/CapabilityInfo.java
@@ -38,6 +38,7 @@ public boolean viewConnections; public boolean viewPlugins; public boolean viewQueue; + public boolean viewSecondaryEmails; static class QueryLimit { short min;
diff --git a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java index 0f6245f..a188251 100644 --- a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java +++ b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -676,11 +676,21 @@ } @Test + public void byAuthorExact_byAlias() throws Exception { + byAuthorOrCommitterExact("a:"); + } + + @Test public void byAuthorFullText() throws Exception { byAuthorOrCommitterFullText("author:"); } @Test + public void byAuthorFullText_byAlias() throws Exception { + byAuthorOrCommitterFullText("a:"); + } + + @Test public void byCommitterExact() throws Exception { byAuthorOrCommitterExact("committer:"); }
diff --git a/resources/com/google/gerrit/server/config/CapabilityConstants.properties b/resources/com/google/gerrit/server/config/CapabilityConstants.properties index 1a355eb..b6aca6f 100644 --- a/resources/com/google/gerrit/server/config/CapabilityConstants.properties +++ b/resources/com/google/gerrit/server/config/CapabilityConstants.properties
@@ -21,3 +21,4 @@ viewConnections = View Connections viewPlugins = View Plugins viewQueue = View Queue +viewSecondaryEmails = View Secondary Emails