credentials.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. """The credentials classes are used to encapsulate all authentication
  2. information for the :class:`~pika.connection.ConnectionParameters` class.
  3. The :class:`~pika.credentials.PlainCredentials` class returns the properly
  4. formatted username and password to the :class:`~pika.connection.Connection`.
  5. To authenticate with Pika, create a :class:`~pika.credentials.PlainCredentials`
  6. object passing in the username and password and pass it as the credentials
  7. argument value to the :class:`~pika.connection.ConnectionParameters` object.
  8. If you are using :class:`~pika.connection.URLParameters` you do not need a
  9. credentials object, one will automatically be created for you.
  10. If you are looking to implement SSL certificate style authentication, you would
  11. extend the :class:`~pika.credentials.ExternalCredentials` class implementing
  12. the required behavior.
  13. """
  14. import logging
  15. from .compat import as_bytes
  16. LOGGER = logging.getLogger(__name__)
  17. class PlainCredentials(object):
  18. """A credentials object for the default authentication methodology with
  19. RabbitMQ.
  20. If you do not pass in credentials to the ConnectionParameters object, it
  21. will create credentials for 'guest' with the password of 'guest'.
  22. If you pass True to erase_on_connect the credentials will not be stored
  23. in memory after the Connection attempt has been made.
  24. :param str username: The username to authenticate with
  25. :param str password: The password to authenticate with
  26. :param bool erase_on_connect: erase credentials on connect.
  27. """
  28. TYPE = 'PLAIN'
  29. def __init__(self, username, password, erase_on_connect=False):
  30. """Create a new instance of PlainCredentials
  31. :param str username: The username to authenticate with
  32. :param str password: The password to authenticate with
  33. :param bool erase_on_connect: erase credentials on connect.
  34. """
  35. self.username = username
  36. self.password = password
  37. self.erase_on_connect = erase_on_connect
  38. def __eq__(self, other):
  39. if isinstance(other, PlainCredentials):
  40. return (self.username == other.username and
  41. self.password == other.password and
  42. self.erase_on_connect == other.erase_on_connect)
  43. return NotImplemented
  44. def __ne__(self, other):
  45. result = self.__eq__(other)
  46. if result is not NotImplemented:
  47. return not result
  48. return NotImplemented
  49. def response_for(self, start):
  50. """Validate that this type of authentication is supported
  51. :param spec.Connection.Start start: Connection.Start method
  52. :rtype: tuple(str|None, str|None)
  53. """
  54. if as_bytes(PlainCredentials.TYPE) not in\
  55. as_bytes(start.mechanisms).split():
  56. return None, None
  57. return (
  58. PlainCredentials.TYPE,
  59. b'\0' + as_bytes(self.username) + b'\0' + as_bytes(self.password))
  60. def erase_credentials(self):
  61. """Called by Connection when it no longer needs the credentials"""
  62. if self.erase_on_connect:
  63. LOGGER.info("Erasing stored credential values")
  64. self.username = None
  65. self.password = None
  66. class ExternalCredentials(object):
  67. """The ExternalCredentials class allows the connection to use EXTERNAL
  68. authentication, generally with a client SSL certificate.
  69. """
  70. TYPE = 'EXTERNAL'
  71. def __init__(self):
  72. """Create a new instance of ExternalCredentials"""
  73. self.erase_on_connect = False
  74. def __eq__(self, other):
  75. if isinstance(other, ExternalCredentials):
  76. return self.erase_on_connect == other.erase_on_connect
  77. return NotImplemented
  78. def __ne__(self, other):
  79. result = self.__eq__(other)
  80. if result is not NotImplemented:
  81. return not result
  82. return NotImplemented
  83. def response_for(self, start): # pylint: disable=R0201
  84. """Validate that this type of authentication is supported
  85. :param spec.Connection.Start start: Connection.Start method
  86. :rtype: tuple(str or None, str or None)
  87. """
  88. if as_bytes(ExternalCredentials.TYPE) not in\
  89. as_bytes(start.mechanisms).split():
  90. return None, None
  91. return ExternalCredentials.TYPE, b''
  92. def erase_credentials(self): # pylint: disable=R0201
  93. """Called by Connection when it no longer needs the credentials"""
  94. LOGGER.debug('Not supported by this Credentials type')
  95. # Append custom credential types to this list for validation support
  96. VALID_TYPES = [PlainCredentials, ExternalCredentials]