001package org.kuali.common.util.ssh.model; 002 003import org.kuali.common.util.Assert; 004import org.kuali.common.util.enc.EncUtils; 005import org.kuali.common.util.enc.EncryptionService; 006import org.kuali.common.util.nullify.NullUtils; 007import org.kuali.common.util.spring.SpringUtils; 008import org.kuali.common.util.spring.env.EnvUtils; 009import org.kuali.common.util.spring.env.EnvironmentService; 010 011import com.google.common.base.Optional; 012 013public final class KeyPair { 014 015 public String getName() { 016 return name; 017 } 018 019 public Optional<String> getPublicKey() { 020 return publicKey; 021 } 022 023 public Optional<String> getPrivateKey() { 024 return privateKey; 025 } 026 027 public Optional<String> getFingerprint() { 028 return fingerprint; 029 } 030 031 private final String name; 032 private final Optional<String> publicKey; 033 private final Optional<String> privateKey; 034 private final Optional<String> fingerprint; 035 036 private KeyPair(Builder builder) { 037 this.name = builder.name; 038 this.publicKey = builder.publicKey; 039 this.privateKey = builder.privateKey; 040 this.fingerprint = builder.fingerprint; 041 } 042 043 public static class Builder { 044 045 // Required 046 private final String name; // No default 047 private final Optional<EnvironmentService> env; // Defaults to Optional.absent() if not supplied 048 private final Optional<EncryptionService> enc; // Defaults to Optional.absent() if not supplied 049 050 // Optional 051 private Optional<String> publicKey = Optional.absent(); 052 private Optional<String> privateKey = Optional.absent(); 053 private Optional<String> fingerprint = Optional.absent(); 054 055 private static final String NAME_KEY = "ssh.keyName"; 056 private static final String PUBLIC_KEY = "ssh.publicKey"; 057 private static final String PRIVATE_KEY = "ssh.privateKey"; 058 private static final String FINGERPRINT_KEY = "ssh.fingerprint"; 059 060 public Builder(String name) { 061 this(EnvUtils.ABSENT, EncUtils.ABSENT, name); 062 } 063 064 public Builder(EnvironmentService env, String name) { 065 this(Optional.of(env), EncUtils.ABSENT, name); 066 } 067 068 public Builder(EnvironmentService env, EncryptionService enc, String name) { 069 this(Optional.of(env), Optional.of(enc), name); 070 } 071 072 public Builder(EnvironmentService env, KeyPair provided) { 073 this(Optional.of(env), EncUtils.ABSENT, provided.getName()); 074 initialize(provided); 075 } 076 077 public Builder(EnvironmentService env, EncryptionService enc, KeyPair provided) { 078 this(Optional.of(env), Optional.of(enc), provided.getName()); 079 initialize(provided); 080 } 081 082 private Builder(Optional<EnvironmentService> env, Optional<EncryptionService> enc, String name) { 083 if (env.isPresent()) { 084 this.name = env.get().getString(NAME_KEY, name); 085 } else { 086 this.name = name; 087 } 088 this.env = env; 089 this.enc = enc; 090 } 091 092 public Builder publicKey(String publicKey) { 093 this.publicKey = NullUtils.toAbsent(publicKey); 094 return this; 095 } 096 097 public Builder privateKey(String privateKey) { 098 this.privateKey = NullUtils.toAbsent(privateKey); 099 return this; 100 } 101 102 public Builder fingerprint(String fingerprint) { 103 this.fingerprint = NullUtils.toAbsent(fingerprint); 104 return this; 105 } 106 107 private void initialize(KeyPair provided) { 108 publicKey(provided.getPublicKey().orNull()); 109 privateKey(provided.getPrivateKey().orNull()); 110 fingerprint(provided.getFingerprint().orNull()); 111 } 112 113 private void override() { 114 if (env.isPresent()) { 115 publicKey(SpringUtils.getString(env.get(), PUBLIC_KEY, publicKey).orNull()); 116 privateKey(SpringUtils.getString(env.get(), PRIVATE_KEY, privateKey).orNull()); 117 fingerprint(SpringUtils.getString(env.get(), FINGERPRINT_KEY, fingerprint).orNull()); 118 } 119 } 120 121 private void finish() { 122 override(); 123 privateKey(EncUtils.decrypt(enc, privateKey).orNull()); 124 } 125 126 private void validate(KeyPair pair, boolean assertDecryptedPrivateKey) { 127 Assert.noBlanks(pair.getName()); 128 Assert.noNulls(pair.getPublicKey(), pair.getPrivateKey(), pair.getFingerprint()); 129 Assert.noBlanks(pair.getPublicKey(), pair.getPrivateKey(), pair.getFingerprint()); 130 if (assertDecryptedPrivateKey && pair.getPrivateKey().isPresent()) { 131 Assert.notEncrypted(pair.getPrivateKey().get()); 132 } 133 } 134 135 public KeyPair build() { 136 finish(); 137 boolean assertDecryptedPrivateKey = enc.isPresent(); 138 KeyPair pair = new KeyPair(this); 139 validate(pair, assertDecryptedPrivateKey); 140 return pair; 141 } 142 143 } 144 145}