1 /*
2 * #%L
3 * Credential.java - mongodb-async-driver - Allanbank Consulting, Inc.
4 * %%
5 * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
6 * %%
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * #L%
19 */
20 package com.allanbank.mongodb;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.ObjectInputStream;
25 import java.io.Serializable;
26 import java.security.cert.X509Certificate;
27 import java.util.Arrays;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.Map;
31
32 import com.allanbank.mongodb.client.connection.auth.Authenticator;
33 import com.allanbank.mongodb.client.connection.auth.MongoDbAuthenticator;
34 import com.allanbank.mongodb.error.MongoDbAuthenticationException;
35
36 /**
37 * Credential provides an immutable set of credential for accessing MongoDB.
38 * <p>
39 * A given client can support a different set of credential for each database
40 * the client is accessing. The client can also authenticate against the
41 * {@value #ADMIN_DB} database which will apply across all databases.
42 * </p>
43 * <p>
44 * <em>Note:</em> While we use the term user name/password within this class the
45 * values may not actually be a user name or a password. In addition not all
46 * authentication mechanisms may use all of the fields in this class. See the
47 * documentation for the authenticator being used for details on what values are
48 * expected for each of the fields in this class.
49 * </p>
50 *
51 * @see <a
52 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication.html">Authentication
53 * Usage Guide</a>
54 * @api.yes This class is part of the driver's API. Public and protected members
55 * will be deprecated for at least 1 non-bugfix release (version
56 * numbers are <major>.<minor>.<bugfix>) before being
57 * removed or modified.
58 * @copyright 2013, Allanbank Consulting, Inc., All Rights Reserved
59 */
60 public final class Credential implements Serializable {
61
62 /**
63 * The name of the administration database used to authenticate a
64 * administrator to MongoDB.
65 */
66 public static final String ADMIN_DB = "admin";
67
68 /**
69 * Constant for Kerberos authentication.
70 * <p>
71 * <em>Note:</em> Use of the Kerberos for authentication requires the
72 * driver's extensions. See the <a href=
73 * "http://www.allanbank.com/mongodb-async-driver/userguide/authentication/kerberos.html"
74 * >Kerberos Usage Guide</a> for details.
75 * </p>
76 *
77 * @see <a
78 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication/kerberos.html">Kerberos
79 * Usage Guide</a>
80 */
81 public static final String KERBEROS;
82
83 /** Constant for traditional MongoDB Challenge/Response. */
84 public static final String MONGODB_CR;
85
86 /** An empty password array. */
87 public static final char[] NO_PASSWORD = new char[0];
88
89 /**
90 * Constant for authentication using plain SASL (LDAP/PAM) client
91 * certificates passed at connection establishment.
92 * <p>
93 * <em>Note:</em> Use of Plain SASL for authentication requires the driver's
94 * extensions. See the <a href=
95 * "http://www.allanbank.com/mongodb-async-driver/userguide/authentication/plain_sasl.html"
96 * >Plain SASL Usage Guide</a> for details.
97 * </p>
98 *
99 * @see <a
100 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication/plain_sasl.html">Plain
101 * SASL Usage Guide</a>
102 */
103 public static final String PLAIN_SASL;
104
105 /**
106 * Constant for authentication using x.509 client certificates passed at
107 * connection establishment.
108 * <p>
109 * <em>Note:</em> Use of the x.509 for authentication requires the driver's
110 * extensions. See the <a href=
111 * "http://www.allanbank.com/mongodb-async-driver/userguide/authentication/tls.html"
112 * >TLS/SSL Usage Guide</a> for details.
113 * </p>
114 *
115 * @see <a
116 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication/tls.html">TLS/SSL
117 * Usage Guide</a>
118 * @see <a
119 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication/x509.html">x.509
120 * Authentication Usage Guide</a>
121 */
122 public static final String X509;
123
124 /** Serialization version of the class. */
125 private static final long serialVersionUID = -6251469373336569336L;
126
127 static {
128 KERBEROS = "com.allanbank.mongodb.extensions.authentication.KerberosAuthenticator";
129 MONGODB_CR = MongoDbAuthenticator.class.getName();
130 PLAIN_SASL = "com.allanbank.mongodb.extensions.authentication.PlainSaslAuthenticator";
131 X509 = "com.allanbank.mongodb.extensions.authentication.X509Authenticator";
132 }
133
134 /**
135 * Creates a {@link Builder} for creating a {@link Credential}.
136 *
137 * @return The {@link Builder} for creating a {@link Credential}.
138 */
139 public static Builder builder() {
140 return new Builder();
141 }
142
143 /**
144 * The authentication type or mode that the credential should be used with.
145 */
146 private final String myAuthenticationType;
147
148 /** The template authenticator for the credential. */
149 private transient Authenticator myAuthenticator;
150
151 /** The database the credential are valid for. */
152 private final String myDatabase;
153
154 /** The file containing the full credentials. */
155 private final File myFile;
156
157 /** Other options for the credentials. */
158 private final Map<String, String> myOptions;
159
160 /** The password for the credential set. */
161 private final char[] myPassword;
162
163 /** The user name for the credential set. */
164 private final String myUserName;
165
166 /**
167 * Creates a new Credential.
168 *
169 * @param builder
170 * The builder for the credentials.
171 */
172 public Credential(final Builder builder) {
173 myUserName = builder.myUserName;
174 myDatabase = builder.myDatabase;
175 myFile = builder.myFile;
176 myAuthenticationType = builder.myAuthenticationType;
177 myAuthenticator = builder.myAuthenticator;
178 myPassword = builder.myPassword.clone();
179 myOptions = Collections.unmodifiableMap(new HashMap<String, String>(
180 builder.myOptions));
181 }
182
183 /**
184 * Returns an authenticator for the credential.
185 *
186 * @return The authenticator for the credential.
187 * @throws MongoDbAuthenticationException
188 * On a failure to load the authenticator for the credential.
189 */
190 public Authenticator authenticator() throws MongoDbAuthenticationException {
191 if (myAuthenticator == null) {
192 try {
193 loadAuthenticator();
194 }
195 catch (final ClassNotFoundException e) {
196 throw new MongoDbAuthenticationException(e);
197 }
198 catch (final InstantiationException e) {
199 throw new MongoDbAuthenticationException(e);
200 }
201 catch (final IllegalAccessException e) {
202 throw new MongoDbAuthenticationException(e);
203 }
204 }
205
206 return myAuthenticator.clone();
207 }
208
209 /**
210 * {@inheritDoc}
211 * <p>
212 * Overridden to return true if the passed value equals these credential.
213 * </p>
214 */
215 @Override
216 public boolean equals(final Object object) {
217 boolean result = false;
218 if (this == object) {
219 result = true;
220 }
221 else if ((object != null) && (getClass() == object.getClass())) {
222 final Credential other = (Credential) object;
223
224 result = nullSafeEquals(myAuthenticationType,
225 other.myAuthenticationType)
226 && nullSafeEquals(myDatabase, other.myDatabase)
227 && nullSafeEquals(myUserName, other.myUserName)
228 && nullSafeEquals(myFile, other.myFile)
229 && nullSafeEquals(myOptions, other.myOptions)
230 && Arrays.equals(myPassword, other.myPassword);
231 }
232 return result;
233 }
234
235 /**
236 * Returns the authentication type or mode that the credential should be
237 * used with.
238 *
239 * @return The authentication type or mode that the credential should be
240 * used with.
241 */
242 public String getAuthenticationType() {
243 return myAuthenticationType;
244 }
245
246 /**
247 * Returns the authenticator value.
248 *
249 * @return The authenticator value.
250 */
251 public Authenticator getAuthenticator() {
252 return myAuthenticator;
253 }
254
255 /**
256 * Returns the database the credential are valid for. Use {@link #ADMIN_DB}
257 * to authenticate as an administrator.
258 *
259 * @return The database the credential are valid for.
260 */
261 public String getDatabase() {
262 return myDatabase;
263 }
264
265 /**
266 * Returns the file containing the full credentials.
267 *
268 * @return The file containing the full credentials. May be
269 * <code>null</code>.
270 */
271 public File getFile() {
272 return myFile;
273 }
274
275 /**
276 * Returns the option value.
277 *
278 * @param optionName
279 * The name of the option to set.
280 * @param defaultValue
281 * The value of the option if it is not set or cannot be parsed
282 * via {@link Boolean#parseBoolean(String)}.
283 * @return The option value.
284 */
285 public boolean getOption(final String optionName, final boolean defaultValue) {
286 final String value = myOptions.get(optionName);
287 if (value != null) {
288 return Boolean.parseBoolean(value);
289 }
290 return defaultValue;
291 }
292
293 /**
294 * Returns the option value.
295 *
296 * @param optionName
297 * The name of the option to set.
298 * @param defaultValue
299 * The value of the option if it is not set or cannot be parsed
300 * via {@link Integer#parseInt(String)}.
301 * @return The option value.
302 */
303 public int getOption(final String optionName, final int defaultValue) {
304 final String value = myOptions.get(optionName);
305 if (value != null) {
306 try {
307 return Integer.parseInt(value);
308 }
309 catch (final NumberFormatException nfe) {
310 return defaultValue;
311 }
312 }
313 return defaultValue;
314 }
315
316 /**
317 * Returns the option value.
318 *
319 * @param optionName
320 * The name of the option to set.
321 * @param defaultValue
322 * The value of the option if it is not set.
323 * @return The option value.
324 */
325 public String getOption(final String optionName, final String defaultValue) {
326 String value = myOptions.get(optionName);
327 if (value == null) {
328 value = defaultValue;
329 }
330
331 return value;
332 }
333
334 /**
335 * Returns the password for the credential set. A clone of the internal
336 * array is returns that should be cleared when it is done being used via
337 * something like {@link java.util.Arrays#fill(char[], char)
338 * Arrays.fill(password, 0)}
339 *
340 * @return The password for the credential set.
341 */
342 public char[] getPassword() {
343 return myPassword.clone();
344 }
345
346 /**
347 * Returns the user name for the credential set.
348 *
349 * @return The user name for the credential set.
350 */
351 public String getUserName() {
352 return myUserName;
353 }
354
355 /**
356 * {@inheritDoc}
357 * <p>
358 * Overridden to hash the credential.
359 * </p>
360 */
361 @Override
362 public int hashCode() {
363 int result = 1;
364
365 result = (31 * result)
366 + ((myAuthenticationType == null) ? 0 : myAuthenticationType
367 .hashCode());
368 result = (31 * result)
369 + ((myDatabase == null) ? 0 : myDatabase.hashCode());
370 result = (31 * result) + myOptions.hashCode();
371 result = (31 * result) + Arrays.hashCode(myPassword);
372 result = (31 * result)
373 + ((myUserName == null) ? 0 : myUserName.hashCode());
374 result = (31 * result) + ((myFile == null) ? 0 : myFile.hashCode());
375
376 return result;
377 }
378
379 /**
380 * Returns true if the password has atleast a single character.
381 *
382 * @return True if the password has atleast a single character, false
383 * otherwise.
384 */
385 public boolean hasPassword() {
386 return (myPassword.length > 0);
387 }
388
389 /**
390 * {@inheritDoc}
391 * <p>
392 * Overridden to returns the credential in a human readable form.
393 * </p>
394 */
395 @Override
396 public String toString() {
397 final StringBuilder builder = new StringBuilder();
398 builder.append("{ username : '");
399 builder.append(myUserName);
400 builder.append("', database : '");
401 builder.append(myDatabase);
402 if (myFile != null) {
403 builder.append("', file : '");
404 builder.append(myFile.getName());
405 }
406 builder.append("', password : '<redacted>', type: '");
407 if (KERBEROS.equals(myAuthenticationType)) {
408 builder.append("KERBEROS");
409 }
410 else if (PLAIN_SASL.equals(myAuthenticationType)) {
411 builder.append("PLAIN SASL");
412 }
413 else if (X509.equals(myAuthenticationType)) {
414 builder.append("x.509");
415 }
416 else if (MONGODB_CR.equals(myAuthenticationType)) {
417 builder.append("MONGODB-CR");
418 }
419 else if (myAuthenticationType != null) {
420 builder.append(myAuthenticationType);
421 }
422
423 for (final Map.Entry<String, String> option : myOptions.entrySet()) {
424 builder.append("', '");
425 builder.append(option.getKey());
426 builder.append("': '");
427 builder.append(option.getValue());
428 }
429
430 builder.append("' }");
431
432 return builder.toString();
433 }
434
435 /**
436 * Loads the authenticator for the credential.
437 *
438 * @throws ClassNotFoundException
439 * If the authenticators Class cannot be found.
440 * @throws InstantiationException
441 * If the authenticator cannot be instantiated.
442 * @throws IllegalAccessException
443 * If the authenticator cannot be accessed.
444 */
445 /* package */void loadAuthenticator() throws ClassNotFoundException,
446 InstantiationException, IllegalAccessException {
447 if (myAuthenticator == null) {
448 myAuthenticator = (Authenticator) Class.forName(
449 getAuthenticationType()).newInstance();
450 }
451 }
452
453 /**
454 * Does a null safe equals comparison.
455 *
456 * @param rhs
457 * The right-hand-side of the comparison.
458 * @param lhs
459 * The left-hand-side of the comparison.
460 * @return True if the rhs equals the lhs. Note: nullSafeEquals(null, null)
461 * returns true.
462 */
463 private boolean nullSafeEquals(final Object rhs, final Object lhs) {
464 return (rhs == lhs) || ((rhs != null) && rhs.equals(lhs));
465 }
466
467 /**
468 * Sets the transient state of this {@link Credential}.
469 *
470 * @param in
471 * The input stream.
472 * @throws ClassNotFoundException
473 * On a failure loading a class in this classed reachable tree.
474 * @throws IOException
475 * On a failure reading from the stream.
476 */
477 private void readObject(final ObjectInputStream in)
478 throws ClassNotFoundException, IOException {
479 in.defaultReadObject();
480 myAuthenticator = null;
481 }
482
483 /**
484 * Builder provides a helper for creating a {@link Credential}.
485 *
486 * @copyright 2013, Allanbank Consulting, Inc., All Rights Reserved
487 */
488 public static class Builder {
489 /**
490 * The authentication type or mode that the credential should be used
491 * with.
492 */
493 protected String myAuthenticationType;
494
495 /** The template authenticator for the credential. */
496 protected Authenticator myAuthenticator;
497
498 /** The database the credential are valid for. */
499 protected String myDatabase;
500
501 /** The file containing the full credentials. */
502 protected File myFile;
503
504 /** Other options for the credentials. */
505 protected final Map<String, String> myOptions;
506
507 /** The password for the credential set. */
508 protected char[] myPassword;
509
510 /** The user name for the credential set. */
511 protected String myUserName;
512
513 /**
514 * Creates a new Builder.
515 */
516 public Builder() {
517 myOptions = new HashMap<String, String>();
518 reset();
519 }
520
521 /**
522 * Adds an option to the built credentials.
523 *
524 * @param optionName
525 * The name of the option to set.
526 * @param optionValue
527 * The value of the option to set.
528 * @return This {@link Builder} for method chaining.
529 */
530 public Builder addOption(final String optionName,
531 final boolean optionValue) {
532 myOptions.put(optionName, String.valueOf(optionValue));
533
534 return this;
535 }
536
537 /**
538 * Adds an option to the built credentials.
539 *
540 * @param optionName
541 * The name of the option to set.
542 * @param optionValue
543 * The value of the option to set.
544 * @return This {@link Builder} for method chaining.
545 */
546 public Builder addOption(final String optionName, final int optionValue) {
547 myOptions.put(optionName, String.valueOf(optionValue));
548
549 return this;
550 }
551
552 /**
553 * Adds an option to the built credentials.
554 *
555 * @param optionName
556 * The name of the option to set.
557 * @param optionValue
558 * The value of the option to set.
559 * @return This {@link Builder} for method chaining.
560 */
561 public Builder addOption(final String optionName,
562 final String optionValue) {
563 myOptions.put(optionName, optionValue);
564
565 return this;
566 }
567
568 /**
569 * Sets the value of the authentication type or mode that the credential
570 * should be used with.
571 * <p>
572 * This method delegates to {@link #setAuthenticationType(String)}.
573 * </p>
574 *
575 * @param authenticationType
576 * The new value for the authentication type or mode that the
577 * credential should be used with.
578 * @return This {@link Builder} for method chaining.
579 */
580 public Builder authenticationType(final String authenticationType) {
581 return setAuthenticationType(authenticationType);
582 }
583
584 /**
585 * Sets the value of the template authenticator for the credential.
586 * <p>
587 * This method delegates to {@link #setAuthenticator(Authenticator)}.
588 * </p>
589 *
590 * @param authenticator
591 * The new value for the template authenticator for the
592 * credential.
593 * @return This {@link Builder} for method chaining.
594 */
595 public Builder authenticator(final Authenticator authenticator) {
596 return setAuthenticator(authenticator);
597 }
598
599 /**
600 * Creates the credential from this builder.
601 *
602 * @return The {@link Credential} populated with the state of this
603 * builder.
604 */
605 public Credential build() {
606 return new Credential(this);
607 }
608
609 /**
610 * Sets the value of the database the credential are valid for.
611 * <p>
612 * This method delegates to {@link #setDatabase(String)}.
613 * </p>
614 *
615 * @param database
616 * The new value for the database the credential are valid
617 * for.
618 * @return This {@link Builder} for method chaining.
619 */
620 public Builder database(final String database) {
621 return setDatabase(database);
622 }
623
624 /**
625 * Sets the value of the file containing the full credentials.
626 * <p>
627 * This method delegates to {@link #setFile(File)}.
628 * </p>
629 *
630 * @param file
631 * The new value for the file containing the full
632 * credentials.
633 * @return This {@link Builder} for method chaining.
634 */
635 public Builder file(final File file) {
636 return setFile(file);
637 }
638
639 /**
640 * Sets the value of the authentication type or mode that the credential
641 * should be used with to Kerberos.
642 * <p>
643 * This method delegates to {@link #setAuthenticationType(String)
644 * setAuthenticationType(KERBEROS)}.
645 * </p>
646 * <p>
647 * <em>Note:</em> Use of Kerberos for authentication requires the
648 * driver's extensions. See the <a href=
649 * "http://www.allanbank.com/mongodb-async-driver/userguide/authentication/kerberos.html"
650 * >Kerberos Usage Guide</a> for details.
651 * </p>
652 *
653 * @see <a
654 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication/kerberos.html">Kerberos
655 * Usage Guide</a>
656 *
657 * @return This {@link Builder} for method chaining.
658 */
659 public Builder kerberos() {
660 return setAuthenticationType(KERBEROS);
661 }
662
663 /**
664 * Sets the value of the authentication type or mode that the credential
665 * should be used with LDAP via PLAIN SASL.
666 * <p>
667 * This method delegates to {@link #setAuthenticationType(String)
668 * setAuthenticationType(PLAIN_SASL)}.
669 * </p>
670 * <p>
671 * <em>Note:</em> Use of Plain SASL for authentication requires the
672 * driver's extensions. See the <a href=
673 * "http://www.allanbank.com/mongodb-async-driver/userguide/authentication/plain_sasl.html"
674 * >Plain SASL Usage Guide</a> for details.
675 * </p>
676 *
677 * @see <a
678 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication/plain_sasl.html">Plain
679 * SASL Usage Guide</a>
680 *
681 * @return This {@link Builder} for method chaining.
682 */
683 public Builder ldap() {
684 return setAuthenticationType(PLAIN_SASL);
685 }
686
687 /**
688 * Sets the value of the authentication type or mode that the credential
689 * should be used with to MongoDB Challenge/Response.
690 * <p>
691 * This method delegates to {@link #setAuthenticationType(String)
692 * setAuthenticationType(MONGODB_CR)}.
693 * </p>
694 *
695 * @return This {@link Builder} for method chaining.
696 */
697 public Builder mongodbCR() {
698 return setAuthenticationType(MONGODB_CR);
699 }
700
701 /**
702 * Sets the value of the authentication type or mode that the credential
703 * should be used with PAM via PLAIN SASL.
704 * <p>
705 * This method delegates to {@link #setAuthenticationType(String)
706 * setAuthenticationType(PLAIN_SASL)}.
707 * </p>
708 * <p>
709 * <em>Note:</em> Use of Plain SASL for authentication requires the
710 * driver's extensions. See the <a href=
711 * "http://www.allanbank.com/mongodb-async-driver/userguide/authentication/plain_sasl.html"
712 * >Plain SASL Usage Guide</a> for details.
713 * </p>
714 *
715 * @see <a
716 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication/plain_sasl.html">Plain
717 * SASL Usage Guide</a>
718 *
719 * @return This {@link Builder} for method chaining.
720 */
721 public Builder pam() {
722 return setAuthenticationType(PLAIN_SASL);
723 }
724
725 /**
726 * Sets the value of the password for the credential set.
727 * <p>
728 * This method delegates to {@link #setPassword(char[])}.
729 * </p>
730 *
731 * @param password
732 * The new value for the password for the credential set.
733 * @return This {@link Builder} for method chaining.
734 */
735 public Builder password(final char[] password) {
736 return setPassword(password);
737 }
738
739 /**
740 * Sets the value of the authentication type or mode that the credential
741 * should be used with to PLAIN SASL.
742 * <p>
743 * This method delegates to {@link #setAuthenticationType(String)
744 * setAuthenticationType(PLAIN_SASL)}.
745 * </p>
746 * <p>
747 * <em>Note:</em> Use of Plain SASL for authentication requires the
748 * driver's extensions. See the <a href=
749 * "http://www.allanbank.com/mongodb-async-driver/userguide/authentication/plain_sasl.html"
750 * >Plain SASL Usage Guide</a> for details.
751 * </p>
752 *
753 * @see <a
754 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication/plain_sasl.html">Plain
755 * SASL Usage Guide</a>
756 *
757 * @return This {@link Builder} for method chaining.
758 */
759 public Builder plainSasl() {
760 return setAuthenticationType(PLAIN_SASL);
761 }
762
763 /**
764 * Resets the builder to a known state.
765 *
766 * @return This {@link Builder} for method chaining.
767 */
768 public Builder reset() {
769 if (myPassword != null) {
770 Arrays.fill(myPassword, '\u0000');
771 }
772
773 myAuthenticationType = MONGODB_CR;
774 myAuthenticator = null;
775 myDatabase = ADMIN_DB;
776 myFile = null;
777 myPassword = NO_PASSWORD;
778 myUserName = null;
779 myOptions.clear();
780
781 return this;
782 }
783
784 /**
785 * Sets the value of the authentication type or mode that the credential
786 * should be used with.
787 *
788 * @param authenticationType
789 * The new value for the authentication type or mode that the
790 * credential should be used with.
791 * @return This {@link Builder} for method chaining.
792 */
793 public Builder setAuthenticationType(final String authenticationType) {
794 myAuthenticationType = authenticationType;
795 return this;
796 }
797
798 /**
799 * Sets the value of the template authenticator for the credential.
800 *
801 * @param authenticator
802 * The new value for the template authenticator for the
803 * credential.
804 * @return This {@link Builder} for method chaining.
805 */
806 public Builder setAuthenticator(final Authenticator authenticator) {
807 myAuthenticator = authenticator;
808 return this;
809 }
810
811 /**
812 * Sets the value of the database the credential are valid for.
813 *
814 * @param database
815 * The new value for the database the credential are valid
816 * for.
817 * @return This {@link Builder} for method chaining.
818 */
819 public Builder setDatabase(final String database) {
820 if (database == null) {
821 myDatabase = ADMIN_DB;
822 }
823 else {
824 myDatabase = database;
825 }
826 return this;
827 }
828
829 /**
830 * Sets the value of the file containing the full credentials.
831 *
832 * @param file
833 * The new value for the file containing the full
834 * credentials.
835 * @return This {@link Builder} for method chaining.
836 */
837 public Builder setFile(final File file) {
838 myFile = file;
839 return this;
840 }
841
842 /**
843 * Sets the value of the password for the credential set.
844 *
845 * @param password
846 * The new value for the password for the credential set.
847 * @return This {@link Builder} for method chaining.
848 */
849 public Builder setPassword(final char[] password) {
850 Arrays.fill(myPassword, '\u0000');
851
852 if (password == null) {
853 myPassword = NO_PASSWORD;
854 }
855 else {
856 myPassword = password.clone();
857 }
858 return this;
859 }
860
861 /**
862 * Sets the value of the user name for the credential set.
863 *
864 * @param userName
865 * The new value for the user name for the credential set.
866 * @return This {@link Builder} for method chaining.
867 */
868 public Builder setUserName(final String userName) {
869 myUserName = userName;
870 return this;
871 }
872
873 /**
874 * Sets the value of the user name for the credential set.
875 * <p>
876 * This method delegates to {@link #setUserName(String)}.
877 * </p>
878 *
879 * @param userName
880 * The new value for the user name for the credential set.
881 * @return This {@link Builder} for method chaining.
882 */
883 public Builder userName(final String userName) {
884 return setUserName(userName);
885 }
886
887 /**
888 * Sets the value of the authentication type or mode that the credential
889 * should be used with to x.509 client certificates exchanged via the
890 * TLS connection.
891 * <p>
892 * This method delegates to {@link #setAuthenticationType(String)
893 * setAuthenticationType(X509)}.
894 * </p>
895 * <p>
896 * <em>Note:</em> Use of x.509 for authentication requires the driver's
897 * extensions. See the <a href=
898 * "http://www.allanbank.com/mongodb-async-driver/userguide/authentication/tls.html"
899 * > TLS Usage Guide</a> for details.
900 * </p>
901 *
902 * @return This {@link Builder} for method chaining.
903 *
904 * @see <a
905 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication/tls.html">TLS/SSL
906 * Usage Guide</a>
907 * @see <a
908 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication/x509.html">x.509
909 * Authentication Usage Guide</a>
910 */
911 public Builder x509() {
912 return setAuthenticationType(X509);
913 }
914
915 /**
916 * Sets the {@link #userName(String) user name} to that of the x.509
917 * certificate subject name and then sets the value of the
918 * authentication type or mode that the credential should be used with
919 * to x.509 client certificates exchanged via the TLS connection.
920 * <p>
921 * This method delegates to {@link #userName(String)
922 * userName(cert.getSubjectX500Principal().toString())}.{@link #x509()
923 * x509()}.
924 * </p>
925 * <p>
926 * <em>Note:</em> Use of x.509 for authentication requires the driver's
927 * extensions. See the <a href=
928 * "http://www.allanbank.com/mongodb-async-driver/userguide/authentication/tls.html"
929 * > TLS Usage Guide</a> for details.
930 * </p>
931 *
932 * @param cert
933 * The client's certificate containing the client subject
934 * name.
935 * @return This {@link Builder} for method chaining.
936 *
937 * @see <a
938 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication/tls.html">TLS/SSL
939 * Usage Guide</a>
940 * @see <a
941 * href="http://www.allanbank.com/mongodb-async-driver/userguide/authentication/x509.html">x.509
942 * Authentication Usage Guide</a>
943 */
944 public Builder x509(final X509Certificate cert) {
945 return userName(cert.getSubjectX500Principal().toString()).x509();
946 }
947 }
948 }