summaryrefslogtreecommitdiffstats
path: root/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountControl.java
diff options
context:
space:
mode:
Diffstat (limited to 'gerrit-server/src/main/java/com/google/gerrit/server/account/AccountControl.java')
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/account/AccountControl.java121
1 files changed, 121 insertions, 0 deletions
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountControl.java
new file mode 100644
index 0000000000..b297ed8391
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountControl.java
@@ -0,0 +1,121 @@
+// Copyright (C) 2012 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.account;
+
+import com.google.gerrit.common.errors.NoSuchGroupException;
+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.inject.Inject;
+import com.google.inject.Provider;
+
+import java.util.Set;
+
+/** Access control management for one account's access to other accounts. */
+public class AccountControl {
+ public static class Factory {
+ private final GroupControl.Factory groupControlFactory;
+ private final Provider<CurrentUser> user;
+ private final IdentifiedUser.GenericFactory userFactory;
+ private final AccountVisibility accountVisibility;
+
+ @Inject
+ Factory(final GroupControl.Factory groupControlFactory,
+ final Provider<CurrentUser> user,
+ final IdentifiedUser.GenericFactory userFactory,
+ final AccountVisibility accountVisibility) {
+ this.groupControlFactory = groupControlFactory;
+ this.user = user;
+ this.userFactory = userFactory;
+ this.accountVisibility = accountVisibility;
+ }
+
+ public AccountControl get() {
+ return new AccountControl(groupControlFactory, user.get(), userFactory,
+ accountVisibility);
+ }
+ }
+
+ private final GroupControl.Factory groupControlFactory;
+ private final CurrentUser currentUser;
+ private final IdentifiedUser.GenericFactory userFactory;
+ private final AccountVisibility accountVisibility;
+
+ AccountControl(final GroupControl.Factory groupControlFactory,
+ final CurrentUser currentUser,
+ final IdentifiedUser.GenericFactory userFactory,
+ final AccountVisibility accountVisibility) {
+ this.groupControlFactory = groupControlFactory;
+ this.currentUser = currentUser;
+ this.userFactory = userFactory;
+ this.accountVisibility = accountVisibility;
+ }
+
+ /**
+ * Returns true if the otherUser is allowed to see the current user, based
+ * on the account visibility policy. Depending on the group membership
+ * realms supported, this may not be able to determine SAME_GROUP or
+ * VISIBLE_GROUP correctly (defaulting to not being visible). This is because
+ * {@link GroupMembership#getKnownGroups()} may only return a subset of the
+ * effective groups.
+ */
+ public boolean canSee(final Account otherUser) {
+ // Special case: I can always see myself.
+ if (currentUser instanceof IdentifiedUser
+ && ((IdentifiedUser) currentUser).getAccountId()
+ .equals(otherUser.getId())) {
+ return true;
+ }
+
+ switch (accountVisibility) {
+ case ALL:
+ return true;
+ case SAME_GROUP: {
+ Set<AccountGroup.UUID> usersGroups = groupsOf(otherUser);
+ usersGroups.remove(AccountGroup.ANONYMOUS_USERS);
+ usersGroups.remove(AccountGroup.REGISTERED_USERS);
+ if (currentUser.getEffectiveGroups().containsAnyOf(usersGroups)) {
+ return true;
+ }
+ break;
+ }
+ case VISIBLE_GROUP: {
+ Set<AccountGroup.UUID> usersGroups = groupsOf(otherUser);
+ usersGroups.remove(AccountGroup.ANONYMOUS_USERS);
+ usersGroups.remove(AccountGroup.REGISTERED_USERS);
+ for (AccountGroup.UUID usersGroup : usersGroups) {
+ try {
+ if (groupControlFactory.controlFor(usersGroup).isVisible()) {
+ return true;
+ }
+ } catch (NoSuchGroupException e) {
+ continue;
+ }
+ }
+ break;
+ }
+ case NONE:
+ break;
+ default:
+ throw new IllegalStateException("Bad AccountVisibility " + accountVisibility);
+ }
+ return false;
+ }
+
+ private Set<AccountGroup.UUID> groupsOf(Account account) {
+ return userFactory.create(account.getId()).getEffectiveGroups().getKnownGroups();
+ }
+}