Line data Source code
1 : // Copyright (C) 2016 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.account; 16 : 17 : import com.google.common.annotations.VisibleForTesting; 18 : import com.google.common.base.Splitter; 19 : import com.google.gerrit.entities.Account; 20 : import java.util.ArrayList; 21 : import java.util.Collection; 22 : import java.util.List; 23 : import java.util.Optional; 24 : import java.util.regex.Pattern; 25 : 26 0 : public class AuthorizedKeys { 27 : public static final String FILE_NAME = "authorized_keys"; 28 : 29 : @VisibleForTesting public static final String INVALID_KEY_COMMENT_PREFIX = "# INVALID "; 30 : 31 : @VisibleForTesting public static final String DELETED_KEY_COMMENT = "# DELETED"; 32 : 33 17 : private static final Pattern LINE_SPLIT_PATTERN = Pattern.compile("\\r?\\n"); 34 : 35 : public static List<Optional<AccountSshKey>> parse(Account.Id accountId, String s) { 36 17 : List<Optional<AccountSshKey>> keys = new ArrayList<>(); 37 17 : int seq = 1; 38 17 : for (String line : Splitter.on(LINE_SPLIT_PATTERN).split(s)) { 39 17 : line = line.trim(); 40 17 : if (line.isEmpty()) { 41 17 : continue; 42 17 : } else if (line.startsWith(INVALID_KEY_COMMENT_PREFIX)) { 43 2 : String pub = line.substring(INVALID_KEY_COMMENT_PREFIX.length()); 44 2 : AccountSshKey key = AccountSshKey.createInvalid(accountId, seq++, pub); 45 2 : keys.add(Optional.of(key)); 46 17 : } else if (line.startsWith(DELETED_KEY_COMMENT)) { 47 3 : keys.add(Optional.empty()); 48 3 : seq++; 49 17 : } else if (line.startsWith("#")) { 50 0 : continue; 51 : } else { 52 17 : AccountSshKey key = AccountSshKey.create(accountId, seq++, line); 53 17 : keys.add(Optional.of(key)); 54 : } 55 17 : } 56 17 : return keys; 57 : } 58 : 59 : public static String serialize(Collection<Optional<AccountSshKey>> keys) { 60 17 : StringBuilder b = new StringBuilder(); 61 17 : for (Optional<AccountSshKey> key : keys) { 62 17 : if (key.isPresent()) { 63 17 : if (!key.get().valid()) { 64 2 : b.append(INVALID_KEY_COMMENT_PREFIX); 65 : } 66 17 : b.append(key.get().sshPublicKey().trim()); 67 : } else { 68 4 : b.append(DELETED_KEY_COMMENT); 69 : } 70 17 : b.append("\n"); 71 17 : } 72 17 : return b.toString(); 73 : } 74 : }