authentication.py 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. from __future__ import unicode_literals
  2. import base64
  3. from rest_framework import exceptions, HTTP_HEADER_ENCODING
  4. from rest_framework.authentication import BaseAuthentication, get_authorization_header, authenticate
  5. from desecapi.models import Token
  6. from rest_framework.authentication import TokenAuthentication as RestFrameworkTokenAuthentication
  7. class TokenAuthentication(RestFrameworkTokenAuthentication):
  8. model = Token
  9. class BasicTokenAuthentication(BaseAuthentication):
  10. """
  11. HTTP Basic authentication that uses username and token.
  12. Clients should authenticate by passing the username and the token as a
  13. password in the "Authorization" HTTP header, according to the HTTP
  14. Basic Authentication Scheme
  15. Authorization: Basic dXNlcm5hbWU6dG9rZW4=
  16. For username "username" and password "token".
  17. """
  18. # A custom token model may be used, but must have the following properties.
  19. #
  20. # * key -- The string identifying the token
  21. # * user -- The user to which the token belongs
  22. model = Token
  23. def authenticate(self, request):
  24. auth = get_authorization_header(request).split()
  25. if not auth or auth[0].lower() != b'basic':
  26. return None
  27. if len(auth) == 1:
  28. msg = 'Invalid basic auth token header. No credentials provided.'
  29. raise exceptions.AuthenticationFailed(msg)
  30. elif len(auth) > 2:
  31. msg = 'Invalid basic auth token header. Basic authentication string should not contain spaces.'
  32. raise exceptions.AuthenticationFailed(msg)
  33. return self.authenticate_credentials(auth[1])
  34. def authenticate_credentials(self, basic):
  35. invalid_token_message = 'Invalid basic auth token'
  36. try:
  37. user, key = base64.b64decode(basic).decode(HTTP_HEADER_ENCODING).split(':')
  38. token = self.model.objects.get(key=key)
  39. except:
  40. raise exceptions.AuthenticationFailed(invalid_token_message)
  41. if not token.user.is_active:
  42. raise exceptions.AuthenticationFailed(invalid_token_message)
  43. return token.user, token
  44. def authenticate_header(self, request):
  45. return 'Basic'
  46. class URLParamAuthentication(BaseAuthentication):
  47. """
  48. Authentication against username/password as provided in URL parameters.
  49. """
  50. model = Token
  51. def authenticate(self, request):
  52. """
  53. Returns a `User` if a correct username and password have been supplied
  54. using URL parameters. Otherwise returns `None`.
  55. """
  56. if not 'username' in request.query_params:
  57. msg = 'No username URL parameter provided.'
  58. raise exceptions.AuthenticationFailed(msg)
  59. if not 'password' in request.query_params:
  60. msg = 'No password URL parameter provided.'
  61. raise exceptions.AuthenticationFailed(msg)
  62. return self.authenticate_credentials(request.query_params['username'], request.query_params['password'])
  63. def authenticate_credentials(self, userid, key):
  64. try:
  65. token = self.model.objects.get(key=key)
  66. except self.model.DoesNotExist:
  67. raise exceptions.AuthenticationFailed('badauth')
  68. if not token.user.is_active:
  69. raise exceptions.AuthenticationFailed('badauth')
  70. return token.user, token