001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.eclipse.aether.util.repository; 020 021import javax.net.ssl.HostnameVerifier; 022 023import java.util.ArrayList; 024import java.util.List; 025 026import org.eclipse.aether.repository.Authentication; 027import org.eclipse.aether.repository.AuthenticationContext; 028 029/** 030 * A utility class to build authentication info for repositories and proxies. 031 */ 032public final class AuthenticationBuilder { 033 034 private final List<Authentication> authentications; 035 036 /** 037 * Creates a new authentication builder. 038 */ 039 public AuthenticationBuilder() { 040 authentications = new ArrayList<>(); 041 } 042 043 /** 044 * Builds a new authentication object from the current data of this builder. The state of the builder itself remains 045 * unchanged. 046 * 047 * @return The authentication or {@code null} if no authentication data was supplied to the builder. 048 */ 049 public Authentication build() { 050 if (authentications.isEmpty()) { 051 return null; 052 } 053 if (authentications.size() == 1) { 054 return authentications.get(0); 055 } 056 return new ChainedAuthentication(authentications); 057 } 058 059 /** 060 * Adds username data to the authentication. 061 * 062 * @param username The username, may be {@code null}. 063 * @return This builder for chaining, never {@code null}. 064 */ 065 public AuthenticationBuilder addUsername(String username) { 066 return addString(AuthenticationContext.USERNAME, username); 067 } 068 069 /** 070 * Adds password data to the authentication. 071 * 072 * @param password The password, may be {@code null}. 073 * @return This builder for chaining, never {@code null}. 074 */ 075 public AuthenticationBuilder addPassword(String password) { 076 return addSecret(AuthenticationContext.PASSWORD, password); 077 } 078 079 /** 080 * Adds password data to the authentication. The resulting authentication object uses an encrypted copy of the 081 * supplied character data and callers are advised to clear the input array soon after this method returns. 082 * 083 * @param password The password, may be {@code null}. 084 * @return This builder for chaining, never {@code null}. 085 */ 086 public AuthenticationBuilder addPassword(char[] password) { 087 return addSecret(AuthenticationContext.PASSWORD, password); 088 } 089 090 /** 091 * Adds NTLM data to the authentication. 092 * 093 * @param workstation The NTLM workstation name, may be {@code null}. 094 * @param domain The NTLM domain name, may be {@code null}. 095 * @return This builder for chaining, never {@code null}. 096 */ 097 public AuthenticationBuilder addNtlm(String workstation, String domain) { 098 addString(AuthenticationContext.NTLM_WORKSTATION, workstation); 099 return addString(AuthenticationContext.NTLM_DOMAIN, domain); 100 } 101 102 /** 103 * Adds private key data to the authentication. 104 * 105 * @param pathname The (absolute) path to the private key file, may be {@code null}. 106 * @param passphrase The passphrase protecting the private key, may be {@code null}. 107 * @return This builder for chaining, never {@code null}. 108 */ 109 public AuthenticationBuilder addPrivateKey(String pathname, String passphrase) { 110 if (pathname != null) { 111 addString(AuthenticationContext.PRIVATE_KEY_PATH, pathname); 112 addSecret(AuthenticationContext.PRIVATE_KEY_PASSPHRASE, passphrase); 113 } 114 return this; 115 } 116 117 /** 118 * Adds private key data to the authentication. The resulting authentication object uses an encrypted copy of the 119 * supplied character data and callers are advised to clear the input array soon after this method returns. 120 * 121 * @param pathname The (absolute) path to the private key file, may be {@code null}. 122 * @param passphrase The passphrase protecting the private key, may be {@code null}. 123 * @return This builder for chaining, never {@code null}. 124 */ 125 public AuthenticationBuilder addPrivateKey(String pathname, char[] passphrase) { 126 if (pathname != null) { 127 addString(AuthenticationContext.PRIVATE_KEY_PATH, pathname); 128 addSecret(AuthenticationContext.PRIVATE_KEY_PASSPHRASE, passphrase); 129 } 130 return this; 131 } 132 133 /** 134 * Adds a hostname verifier for SSL. <strong>Note:</strong> This method assumes that all possible instances of the 135 * verifier's runtime type exhibit the exact same behavior, i.e. the behavior of the verifier depends solely on the 136 * runtime type and not on any configuration. For verifiers that do not fit this assumption, use 137 * {@link #addCustom(Authentication)} with a suitable implementation instead. 138 * 139 * @param verifier The hostname verifier, may be {@code null}. 140 * @return This builder for chaining, never {@code null}. 141 */ 142 public AuthenticationBuilder addHostnameVerifier(HostnameVerifier verifier) { 143 if (verifier != null) { 144 authentications.add(new ComponentAuthentication(AuthenticationContext.SSL_HOSTNAME_VERIFIER, verifier)); 145 } 146 return this; 147 } 148 149 /** 150 * Adds custom string data to the authentication. <em>Note:</em> If the string data is confidential, use 151 * {@link #addSecret(String, char[])} instead. 152 * 153 * @param key The key for the authentication data, must not be {@code null}. 154 * @param value The value for the authentication data, may be {@code null}. 155 * @return This builder for chaining, never {@code null}. 156 */ 157 public AuthenticationBuilder addString(String key, String value) { 158 if (value != null) { 159 authentications.add(new StringAuthentication(key, value)); 160 } 161 return this; 162 } 163 164 /** 165 * Adds sensitive custom string data to the authentication. 166 * 167 * @param key The key for the authentication data, must not be {@code null}. 168 * @param value The value for the authentication data, may be {@code null}. 169 * @return This builder for chaining, never {@code null}. 170 */ 171 public AuthenticationBuilder addSecret(String key, String value) { 172 if (value != null) { 173 authentications.add(new SecretAuthentication(key, value)); 174 } 175 return this; 176 } 177 178 /** 179 * Adds sensitive custom string data to the authentication. The resulting authentication object uses an encrypted 180 * copy of the supplied character data and callers are advised to clear the input array soon after this method 181 * returns. 182 * 183 * @param key The key for the authentication data, must not be {@code null}. 184 * @param value The value for the authentication data, may be {@code null}. 185 * @return This builder for chaining, never {@code null}. 186 */ 187 public AuthenticationBuilder addSecret(String key, char[] value) { 188 if (value != null) { 189 authentications.add(new SecretAuthentication(key, value)); 190 } 191 return this; 192 } 193 194 /** 195 * Adds custom authentication data to the authentication. 196 * 197 * @param authentication The authentication to add, may be {@code null}. 198 * @return This builder for chaining, never {@code null}. 199 */ 200 public AuthenticationBuilder addCustom(Authentication authentication) { 201 if (authentication != null) { 202 authentications.add(authentication); 203 } 204 return this; 205 } 206}