View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.util.repository;
20  
21  import javax.net.ssl.HostnameVerifier;
22  
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  import org.eclipse.aether.repository.Authentication;
27  import org.eclipse.aether.repository.AuthenticationContext;
28  
29  /**
30   * A utility class to build authentication info for repositories and proxies.
31   */
32  public final class AuthenticationBuilder {
33  
34      private final List<Authentication> authentications;
35  
36      /**
37       * Creates a new authentication builder.
38       */
39      public AuthenticationBuilder() {
40          authentications = new ArrayList<>();
41      }
42  
43      /**
44       * Builds a new authentication object from the current data of this builder. The state of the builder itself remains
45       * unchanged.
46       *
47       * @return The authentication or {@code null} if no authentication data was supplied to the builder.
48       */
49      public Authentication build() {
50          if (authentications.isEmpty()) {
51              return null;
52          }
53          if (authentications.size() == 1) {
54              return authentications.get(0);
55          }
56          return new ChainedAuthentication(authentications);
57      }
58  
59      /**
60       * Adds username data to the authentication.
61       *
62       * @param username The username, may be {@code null}.
63       * @return This builder for chaining, never {@code null}.
64       */
65      public AuthenticationBuilder addUsername(String username) {
66          return addString(AuthenticationContext.USERNAME, username);
67      }
68  
69      /**
70       * Adds password data to the authentication.
71       *
72       * @param password The password, may be {@code null}.
73       * @return This builder for chaining, never {@code null}.
74       */
75      public AuthenticationBuilder addPassword(String password) {
76          return addSecret(AuthenticationContext.PASSWORD, password);
77      }
78  
79      /**
80       * Adds password data to the authentication. The resulting authentication object uses an encrypted copy of the
81       * supplied character data and callers are advised to clear the input array soon after this method returns.
82       *
83       * @param password The password, may be {@code null}.
84       * @return This builder for chaining, never {@code null}.
85       */
86      public AuthenticationBuilder addPassword(char[] password) {
87          return addSecret(AuthenticationContext.PASSWORD, password);
88      }
89  
90      /**
91       * Adds NTLM data to the authentication.
92       *
93       * @param workstation The NTLM workstation name, may be {@code null}.
94       * @param domain The NTLM domain name, may be {@code null}.
95       * @return This builder for chaining, never {@code null}.
96       */
97      public AuthenticationBuilder addNtlm(String workstation, String domain) {
98          addString(AuthenticationContext.NTLM_WORKSTATION, workstation);
99          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 }