MongoCredentialStore.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /* Copyright 2010-present MongoDB Inc.
  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. using System;
  16. using System.Collections.Generic;
  17. using System.Collections.ObjectModel;
  18. using System.Linq;
  19. namespace MongoDB.Driver
  20. {
  21. /// <summary>
  22. /// Represents a list of credentials and the rules about how credentials can be used together.
  23. /// </summary>
  24. internal class MongoCredentialStore : IEnumerable<MongoCredential>, IEquatable<MongoCredentialStore>
  25. {
  26. // private fields
  27. private readonly ReadOnlyCollection<MongoCredential> _credentials;
  28. // constructors
  29. /// <summary>
  30. /// Creates a new instance of the MongoCredentialStore class.
  31. /// </summary>
  32. /// <param name="credentials">The credentials.</param>
  33. public MongoCredentialStore(IEnumerable<MongoCredential> credentials)
  34. {
  35. if (credentials == null)
  36. {
  37. throw new ArgumentNullException("credentials");
  38. }
  39. _credentials = new ReadOnlyCollection<MongoCredential>(new List<MongoCredential>(credentials));
  40. EnsureCredentialsAreCompatibleWithEachOther();
  41. }
  42. // public operators
  43. /// <summary>
  44. /// Determines whether two <see cref="MongoCredentialStore"/> instances are equal.
  45. /// </summary>
  46. /// <param name="lhs">The LHS.</param>
  47. /// <param name="rhs">The RHS.</param>
  48. /// <returns>
  49. /// <c>true</c> if the left hand side is equal to the right hand side; otherwise, <c>false</c>.
  50. /// </returns>
  51. public static bool operator ==(MongoCredentialStore lhs, MongoCredentialStore rhs)
  52. {
  53. return object.Equals(lhs, rhs); // handles lhs == null correctly
  54. }
  55. /// <summary>
  56. /// Determines whether two <see cref="MongoCredentialStore"/> instances are not equal.
  57. /// </summary>
  58. /// <param name="lhs">The LHS.</param>
  59. /// <param name="rhs">The RHS.</param>
  60. /// <returns>
  61. /// <c>true</c> if the left hand side is not equal to the right hand side; otherwise, <c>false</c>.
  62. /// </returns>
  63. public static bool operator !=(MongoCredentialStore lhs, MongoCredentialStore rhs)
  64. {
  65. return !(lhs == rhs);
  66. }
  67. // public methods
  68. /// <summary>
  69. /// Determines whether the specified <see cref="MongoCredentialStore" /> is equal to this instance.
  70. /// </summary>
  71. /// <param name="obj">The <see cref="MongoCredentialStore" /> to compare with this instance.</param>
  72. /// <returns>
  73. /// <c>true</c> if the specified <see cref="MongoCredentialStore" /> is equal to this instance; otherwise, <c>false</c>.
  74. /// </returns>
  75. public bool Equals(MongoCredentialStore obj)
  76. {
  77. return Equals((object)obj); // handles obj == null correctly
  78. }
  79. /// <summary>
  80. /// Determines whether the specified <see cref="System.Object" /> is equal to this instance.
  81. /// </summary>
  82. /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
  83. /// <returns>
  84. /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
  85. /// </returns>
  86. public override bool Equals(object obj)
  87. {
  88. if (object.ReferenceEquals(obj, null) || GetType() != obj.GetType()) { return false; }
  89. var rhs = (MongoCredentialStore)obj;
  90. return _credentials.SequenceEqual(rhs._credentials);
  91. }
  92. /// <summary>
  93. /// Gets the enumerator.
  94. /// </summary>
  95. /// <returns></returns>
  96. public IEnumerator<MongoCredential> GetEnumerator()
  97. {
  98. return _credentials.GetEnumerator();
  99. }
  100. /// <summary>
  101. /// Gets the hashcode for the credential store.
  102. /// </summary>
  103. /// <returns>The hashcode.</returns>
  104. public override int GetHashCode()
  105. {
  106. // see Effective Java by Joshua Bloch
  107. int hash = 17;
  108. foreach (var credential in _credentials)
  109. {
  110. hash = 37 * hash + credential.GetHashCode();
  111. }
  112. return hash;
  113. }
  114. /// <summary>
  115. /// Returns a string representation of the credential store.
  116. /// </summary>
  117. /// <returns>A string representation of the credential store.</returns>
  118. public override string ToString()
  119. {
  120. return string.Format("{{{0}}}", string.Join(",", _credentials.Select(c => c.ToString()).ToArray()));
  121. }
  122. // explicit interface implementations
  123. /// <summary>
  124. /// Returns an enumerator that iterates through a collection.
  125. /// </summary>
  126. /// <returns>
  127. /// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
  128. /// </returns>
  129. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  130. {
  131. return _credentials.GetEnumerator();
  132. }
  133. // private metods
  134. private void EnsureCredentialsAreCompatibleWithEachOther()
  135. {
  136. var sources = new HashSet<string>(_credentials.Select(c => c.Source));
  137. if (sources.Count < _credentials.Count)
  138. {
  139. throw new ArgumentException("The server requires that each credential provided be from a different source.");
  140. }
  141. }
  142. }
  143. }