浏览代码

refactor(api): streamline BasicTokenAuth and URLParamAuth

Peter Thomassen 4 年之前
父节点
当前提交
fd4a554da4
共有 1 个文件被更改,包括 20 次插入29 次删除
  1. 20 29
      api/desecapi/authentication.py

+ 20 - 29
api/desecapi/authentication.py

@@ -14,6 +14,16 @@ from desecapi.models import Token
 from desecapi.serializers import AuthenticatedBasicUserActionSerializer, EmailPasswordSerializer
 from desecapi.serializers import AuthenticatedBasicUserActionSerializer, EmailPasswordSerializer
 
 
 
 
+class DynAuthenticationMixin:
+    def authenticate_credentials(self, username, key):
+        user, token = TokenAuthentication().authenticate_credentials(key)
+        if not user.is_active:
+            raise exceptions.AuthenticationFailed
+        if username not in ['', user.email] and not user.domains.filter(name=username.lower()).exists():
+            raise exceptions.AuthenticationFailed
+        return user, token
+
+
 class TokenAuthentication(RestFrameworkTokenAuthentication):
 class TokenAuthentication(RestFrameworkTokenAuthentication):
     model = Token
     model = Token
 
 
@@ -55,7 +65,7 @@ class TokenAuthentication(RestFrameworkTokenAuthentication):
         return super().authenticate_credentials(key)
         return super().authenticate_credentials(key)
 
 
 
 
-class BasicTokenAuthentication(BaseAuthentication):
+class BasicTokenAuthentication(BaseAuthentication, DynAuthenticationMixin):
     """
     """
     HTTP Basic authentication that uses username and token.
     HTTP Basic authentication that uses username and token.
 
 
@@ -87,28 +97,17 @@ class BasicTokenAuthentication(BaseAuthentication):
             msg = 'Invalid basic auth token header. Basic authentication string should not contain spaces.'
             msg = 'Invalid basic auth token header. Basic authentication string should not contain spaces.'
             raise exceptions.AuthenticationFailed(msg)
             raise exceptions.AuthenticationFailed(msg)
 
 
-        return self.authenticate_credentials(auth[1])
-
-    def authenticate_credentials(self, basic):
-        invalid_token_message = 'Invalid basic auth token'
         try:
         try:
-            username, key = base64.b64decode(basic).decode(HTTP_HEADER_ENCODING).split(':')
-            user, token = TokenAuthentication().authenticate_credentials(key)
-            if username not in ['', user.email] and not user.domains.filter(name=username.lower()).exists():
-                raise Exception
+            username, key = base64.b64decode(auth[1]).decode(HTTP_HEADER_ENCODING).split(':')
+            return self.authenticate_credentials(username, key)
         except Exception:
         except Exception:
-            raise exceptions.AuthenticationFailed(invalid_token_message)
-
-        if not user.is_active:
-            raise exceptions.AuthenticationFailed(invalid_token_message)
-
-        return user, token
+            raise exceptions.AuthenticationFailed("badauth")
 
 
     def authenticate_header(self, request):
     def authenticate_header(self, request):
         return 'Basic'
         return 'Basic'
 
 
 
 
-class URLParamAuthentication(BaseAuthentication):
+class URLParamAuthentication(BaseAuthentication, DynAuthenticationMixin):
     """
     """
     Authentication against username/password as provided in URL parameters.
     Authentication against username/password as provided in URL parameters.
     """
     """
@@ -116,8 +115,8 @@ class URLParamAuthentication(BaseAuthentication):
 
 
     def authenticate(self, request):
     def authenticate(self, request):
         """
         """
-        Returns a `User` if a correct username and password have been supplied
-        using URL parameters.  Otherwise returns `None`.
+        Returns `(User, Token)` if a correct username and token have been supplied
+        using URL parameters.  Otherwise raises `AuthenticationFailed`.
         """
         """
 
 
         if 'username' not in request.query_params:
         if 'username' not in request.query_params:
@@ -127,18 +126,10 @@ class URLParamAuthentication(BaseAuthentication):
             msg = 'No password URL parameter provided.'
             msg = 'No password URL parameter provided.'
             raise exceptions.AuthenticationFailed(msg)
             raise exceptions.AuthenticationFailed(msg)
 
 
-        return self.authenticate_credentials(request.query_params['username'], request.query_params['password'])
-
-    def authenticate_credentials(self, _, key):
         try:
         try:
-            user, token = TokenAuthentication().authenticate_credentials(key)
-        except self.model.DoesNotExist:
-            raise exceptions.AuthenticationFailed('badauth')
-
-        if not user.is_active:
-            raise exceptions.AuthenticationFailed('badauth')
-
-        return token.user, token
+            return self.authenticate_credentials(request.query_params['username'], request.query_params['password'])
+        except Exception:
+            raise exceptions.AuthenticationFailed("badauth")
 
 
 
 
 class EmailPasswordPayloadAuthentication(BaseAuthentication):
 class EmailPasswordPayloadAuthentication(BaseAuthentication):