summaryrefslogtreecommitdiffstats
path: root/gerrit-server/src/main/java/com/google/gerrit/server/account/VersionedAuthorizedKeys.java
diff options
context:
space:
mode:
Diffstat (limited to 'gerrit-server/src/main/java/com/google/gerrit/server/account/VersionedAuthorizedKeys.java')
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/account/VersionedAuthorizedKeys.java279
1 files changed, 0 insertions, 279 deletions
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/VersionedAuthorizedKeys.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/VersionedAuthorizedKeys.java
deleted file mode 100644
index 8cffe92aa2..0000000000
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/VersionedAuthorizedKeys.java
+++ /dev/null
@@ -1,279 +0,0 @@
-// 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.account;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Comparator.comparing;
-import static java.util.stream.Collectors.toList;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.Ordering;
-import com.google.gerrit.common.errors.InvalidSshKeyException;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.AccountSshKey;
-import com.google.gerrit.reviewdb.client.AccountSshKey.Id;
-import com.google.gerrit.reviewdb.client.RefNames;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.config.AllUsersName;
-import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.server.git.MetaDataUpdate;
-import com.google.gerrit.server.git.VersionedMetaData;
-import com.google.gerrit.server.ssh.SshKeyCreator;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
-import com.google.inject.assistedinject.Assisted;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.eclipse.jgit.lib.CommitBuilder;
-import org.eclipse.jgit.lib.Repository;
-
-/**
- * 'authorized_keys' file in the refs/users/CD/ABCD branches of the All-Users repository.
- *
- * <p>The `authorized_keys' files stores the public SSH keys of the user. The file format matches
- * the standard SSH file format, which means that each key is stored on a separate line (see
- * https://en.wikibooks.org/wiki/OpenSSH/Client_Configuration_Files#.7E.2F.ssh.2Fauthorized_keys).
- *
- * <p>The order of the keys in the file determines the sequence numbers of the keys. The first line
- * corresponds to sequence number 1.
- *
- * <p>Invalid keys are marked with the prefix <code># INVALID</code>.
- *
- * <p>To keep the sequence numbers intact when a key is deleted, a <code># DELETED</code> line is
- * inserted at the position where the key was deleted.
- *
- * <p>Other comment lines are ignored on read, and are not written back when the file is modified.
- */
-public class VersionedAuthorizedKeys extends VersionedMetaData {
- @Singleton
- public static class Accessor {
- private final GitRepositoryManager repoManager;
- private final AllUsersName allUsersName;
- private final VersionedAuthorizedKeys.Factory authorizedKeysFactory;
- private final Provider<MetaDataUpdate.User> metaDataUpdateFactory;
- private final IdentifiedUser.GenericFactory userFactory;
-
- @Inject
- Accessor(
- GitRepositoryManager repoManager,
- AllUsersName allUsersName,
- VersionedAuthorizedKeys.Factory authorizedKeysFactory,
- Provider<MetaDataUpdate.User> metaDataUpdateFactory,
- IdentifiedUser.GenericFactory userFactory) {
- this.repoManager = repoManager;
- this.allUsersName = allUsersName;
- this.authorizedKeysFactory = authorizedKeysFactory;
- this.metaDataUpdateFactory = metaDataUpdateFactory;
- this.userFactory = userFactory;
- }
-
- public List<AccountSshKey> getKeys(Account.Id accountId)
- throws IOException, ConfigInvalidException {
- return read(accountId).getKeys();
- }
-
- public AccountSshKey getKey(Account.Id accountId, int seq)
- throws IOException, ConfigInvalidException {
- return read(accountId).getKey(seq);
- }
-
- public synchronized AccountSshKey addKey(Account.Id accountId, String pub)
- throws IOException, ConfigInvalidException, InvalidSshKeyException {
- VersionedAuthorizedKeys authorizedKeys = read(accountId);
- AccountSshKey key = authorizedKeys.addKey(pub);
- commit(authorizedKeys);
- return key;
- }
-
- public synchronized void deleteKey(Account.Id accountId, int seq)
- throws IOException, ConfigInvalidException {
- VersionedAuthorizedKeys authorizedKeys = read(accountId);
- if (authorizedKeys.deleteKey(seq)) {
- commit(authorizedKeys);
- }
- }
-
- public synchronized void markKeyInvalid(Account.Id accountId, int seq)
- throws IOException, ConfigInvalidException {
- VersionedAuthorizedKeys authorizedKeys = read(accountId);
- if (authorizedKeys.markKeyInvalid(seq)) {
- commit(authorizedKeys);
- }
- }
-
- private VersionedAuthorizedKeys read(Account.Id accountId)
- throws IOException, ConfigInvalidException {
- try (Repository git = repoManager.openRepository(allUsersName)) {
- VersionedAuthorizedKeys authorizedKeys = authorizedKeysFactory.create(accountId);
- authorizedKeys.load(git);
- return authorizedKeys;
- }
- }
-
- private void commit(VersionedAuthorizedKeys authorizedKeys) throws IOException {
- try (MetaDataUpdate md =
- metaDataUpdateFactory
- .get()
- .create(allUsersName, userFactory.create(authorizedKeys.accountId))) {
- authorizedKeys.commit(md);
- }
- }
- }
-
- public static class SimpleSshKeyCreator implements SshKeyCreator {
- @Override
- public AccountSshKey create(Id id, String encoded) {
- return new AccountSshKey(id, encoded);
- }
- }
-
- public interface Factory {
- VersionedAuthorizedKeys create(Account.Id accountId);
- }
-
- private final SshKeyCreator sshKeyCreator;
- private final Account.Id accountId;
- private final String ref;
- private List<Optional<AccountSshKey>> keys;
-
- @Inject
- public VersionedAuthorizedKeys(SshKeyCreator sshKeyCreator, @Assisted Account.Id accountId) {
- this.sshKeyCreator = sshKeyCreator;
- this.accountId = accountId;
- this.ref = RefNames.refsUsers(accountId);
- }
-
- @Override
- protected String getRefName() {
- return ref;
- }
-
- @Override
- protected void onLoad() throws IOException {
- keys = AuthorizedKeys.parse(accountId, readUTF8(AuthorizedKeys.FILE_NAME));
- }
-
- @Override
- protected boolean onSave(CommitBuilder commit) throws IOException {
- if (Strings.isNullOrEmpty(commit.getMessage())) {
- commit.setMessage("Updated SSH keys\n");
- }
-
- saveUTF8(AuthorizedKeys.FILE_NAME, AuthorizedKeys.serialize(keys));
- return true;
- }
-
- /** Returns all SSH keys. */
- private List<AccountSshKey> getKeys() {
- checkLoaded();
- return keys.stream().filter(Optional::isPresent).map(Optional::get).collect(toList());
- }
-
- /**
- * Returns the SSH key with the given sequence number.
- *
- * @param seq sequence number
- * @return the SSH key, <code>null</code> if there is no SSH key with this sequence number, or if
- * the SSH key with this sequence number has been deleted
- */
- private AccountSshKey getKey(int seq) {
- checkLoaded();
- return keys.get(seq - 1).orElse(null);
- }
-
- /**
- * Adds a new public SSH key.
- *
- * <p>If the specified public key exists already, the existing key is returned.
- *
- * @param pub the public SSH key to be added
- * @return the new SSH key
- * @throws InvalidSshKeyException
- */
- private AccountSshKey addKey(String pub) throws InvalidSshKeyException {
- checkLoaded();
-
- for (Optional<AccountSshKey> key : keys) {
- if (key.isPresent() && key.get().getSshPublicKey().trim().equals(pub.trim())) {
- return key.get();
- }
- }
-
- int seq = keys.size() + 1;
- AccountSshKey.Id keyId = new AccountSshKey.Id(accountId, seq);
- AccountSshKey key = sshKeyCreator.create(keyId, pub);
- keys.add(Optional.of(key));
- return key;
- }
-
- /**
- * Deletes the SSH key with the given sequence number.
- *
- * @param seq the sequence number
- * @return <code>true</code> if a key with this sequence number was found and deleted, <code>false
- * </code> if no key with the given sequence number exists
- */
- private boolean deleteKey(int seq) {
- checkLoaded();
- if (seq <= keys.size() && keys.get(seq - 1).isPresent()) {
- keys.set(seq - 1, Optional.empty());
- return true;
- }
- return false;
- }
-
- /**
- * Marks the SSH key with the given sequence number as invalid.
- *
- * @param seq the sequence number
- * @return <code>true</code> if a key with this sequence number was found and marked as invalid,
- * <code>false</code> if no key with the given sequence number exists or if the key was
- * already marked as invalid
- */
- private boolean markKeyInvalid(int seq) {
- checkLoaded();
- AccountSshKey key = getKey(seq);
- if (key != null && key.isValid()) {
- key.setInvalid();
- return true;
- }
- return false;
- }
-
- /**
- * Sets new SSH keys.
- *
- * <p>The existing SSH keys are overwritten.
- *
- * @param newKeys the new public SSH keys
- */
- public void setKeys(Collection<AccountSshKey> newKeys) {
- Ordering<AccountSshKey> o = Ordering.from(comparing(k -> k.getKey().get()));
- keys = new ArrayList<>(Collections.nCopies(o.max(newKeys).getKey().get(), Optional.empty()));
- for (AccountSshKey key : newKeys) {
- keys.set(key.getKey().get() - 1, Optional.of(key));
- }
- }
-
- private void checkLoaded() {
- checkState(keys != null, "SSH keys not loaded yet");
- }
-}