Skip account visibility checks when querying changes

On the change screen users can see who participates in the change (the
change owner, reviewers, CCs etc.). The names of the participating users
are linkified and clicking on them leads to a dashboard with all changes
that are owned by this user. Due to Gerrit's account visibility setting
it can happen that the accounts of some of these users are not visible.
In this case clicking on the user link results in an error that is
unintelligible and confuses users (the error message is: "An error
occurred Error 400: Account [REDACTED_EMAIL_ADDRESS]' not found").

To solve this problem we skip the account visibility check when querying
changes (except if the user is referenced by a secondary email, see
reasoning below). This way clicking on a participating user on the
change screen will work even if their account is not visible.

Skipping the account visibility check when querying changes of
participating users is okay because:

* It doesn't reveal the existence of any account:
  The calling user already knows that this account exists since they can
  see it as a participating user on the change.

* The change query only returns changes that are visible to the calling
  user: The calling user could have found the same changes by other
  means (e.g. iterate over all changes that are visible to them and then
  check which of these changes have the participating user as the change
  owner).

Skipping the account visibility check for change queries in general is
okay because:

* Users can confirm the existence of non-visible accounts that
  participated on any visible change by other means: The calling user
  can iterate over all changes that are visible to them and collect all
  users that participate in them.

To avoid that users can probe whether an account exists, we will no
longer return an error if an account doesn't exist, but instead we
return an empty query result. Otherwise users could deduce from the
response whether an arbitrary account exists (error -> account doesn't
exist, empty result -> account exists but didn't take part in any
visible changes).

Secondary emails are usually not visible to other users (e.g. to avoid
exposing dead names) and can only be seen by the user themselves, admin
users and special privileged users that have the Modify Account
capability assigned to them.

Secondary emails of participating users are not visible on the change
screen. In other words if a non-visible account takes part in a change,
all their account properties are visible to the users that can see the
change, except their secondary emails.

To avoid that users can probe for secondary emails by doing a change
query (e.g. by doing a 'owner:<secondary-email>' query) we still check
whether the calling user has permission to see secondary emails when the
given user identifier is resolved to a secondary email and return an
empty result if not (we can't return an error as this would reveal to
the calling user that this email exists).

Skipping the account visibility check for change queries affects several
search predicates:

* owner / uploader / label + user / reviewer / attention / commentby:
  - Account visibility is not checked and matching changes are returned
    if they are visible.
  - For non-visible accounts that didn't participate in visible changes
    and non-existing accounts an empty result is returned. Note that
    the reviewer predicate already returned an empty result in this case
    (if the specified account doesn't exist or is not visible the
    reviewer predicate falls back to searching with the
    reviewerByEmailPredicate which is for matching reviewers by email
    that have no account). This means with this change we are making the
    behaviour of these predicates consistent again.

The following predicates which are also based on users still check
account visibility:

* visibleto:
  Account visibility is still checked. Whether a change is visible to an
  account cannot be seen on the change. This means users that can see
  the change, don't know about other accounts that can see the change.
  Skipping the account visibility check for this predicate could reveal
  the existence of non-visible accounts even if they didn't participate
  in any visible changes (if the query returns results users can deduce
  that the account exists).

* destination / query:
  Account visibility is still checked. These predicates read a resource
  of the account (a destination/query) that determines which changes
  should be matched. Accessing this resource should only be allowed if
  the account is visible, even if the account participated in any
  visible changes as these resources are not exposed via the visible
  changes.

Release-Notes: Account visibility is no longer checked when querying changes
Signed-off-by: Edwin Kempin <ekempin@google.com>
Bug: Google b/254824035
Change-Id: I022c6a13cd8df9284f526c9262a417cc757578dc
Signed-off-by: Edwin Kempin <ekempin@google.com>
4 files changed
tree: 5af3d56758211aed7e4eeb249226b918ad0ce194
  1. .settings/
  2. .ts-out/
  3. antlr3/
  4. contrib/
  5. Documentation/
  6. e2e-tests/
  7. java/
  8. javatests/
  9. lib/
  10. modules/
  11. plugins/
  12. polygerrit-ui/
  13. prolog/
  14. prologtests/
  15. proto/
  16. resources/
  17. tools/
  18. webapp/
  19. .bazelignore
  20. .bazelproject
  21. .bazelrc
  22. .bazelversion
  23. .editorconfig
  24. .git-blame-ignore-revs
  25. .gitignore
  26. .gitmodules
  27. .gitreview
  28. .mailmap
  29. .pydevproject
  30. .zuul.yaml
  31. BUILD
  32. COPYING
  33. INSTALL
  34. Jenkinsfile
  35. package.json
  36. README.md
  37. SUBMITTING_PATCHES
  38. version.bzl
  39. web-dev-server.config.mjs
  40. WORKSPACE
  41. yarn.lock
README.md

Gerrit Code Review

Gerrit is a code review and project management tool for Git based projects.

Build Status Maven Central

Objective

Gerrit makes reviews easier by showing changes in a side-by-side display, and allowing inline comments to be added by any reviewer.

Gerrit simplifies Git based project maintainership by permitting any authorized user to submit changes to the master Git repository, rather than requiring all approved changes to be merged in by hand by the project maintainer.

Documentation

For information about how to install and use Gerrit, refer to the documentation.

Source

Our canonical Git repository is located on googlesource.com. There is a mirror of the repository on Github.

Reporting bugs

Please report bugs on the issue tracker.

Contribute

Gerrit is the work of hundreds of contributors. We appreciate your help!

Please read the contribution guidelines.

Note that we do not accept Pull Requests via the Github mirror.

Getting in contact

The Developer Mailing list is repo-discuss on Google Groups.

License

Gerrit is provided under the Apache License 2.0.

Build

Install Bazel and run the following:

    git clone --recurse-submodules https://gerrit.googlesource.com/gerrit
    cd gerrit && bazel build release

Install binary packages (Deb/Rpm)

The instruction how to configure GerritForge/BinTray repositories is here

On Debian/Ubuntu run:

    apt-get update && apt-get install gerrit=<version>-<release>

NOTE: release is a counter that starts with 1 and indicates the number of packages that have been released with the same version of the software.

On CentOS/RedHat run:

    yum clean all && yum install gerrit-<version>[-<release>]

On Fedora run:

    dnf clean all && dnf install gerrit-<version>[-<release>]

Use pre-built Gerrit images on Docker

Docker images of Gerrit are available on DockerHub

To run a CentOS 8 based Gerrit image:

    docker run -p 8080:8080 gerritcodereview/gerrit[:version]-centos8

To run a Ubuntu 20.04 based Gerrit image:

    docker run -p 8080:8080 gerritcodereview/gerrit[:version]-ubuntu20

NOTE: release is optional. Last released package of the version is installed if the release number is omitted.