Move contents from __init__.py to backends.py with much more docstrings.
parent
c206f34644
commit
842d02ed12
|
@ -1,75 +1 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import base64
|
||||
import re
|
||||
|
||||
from django.core import signing
|
||||
from django.db.models import get_model
|
||||
from rest_framework.authentication import BaseAuthentication
|
||||
|
||||
import taiga.base.exceptions as exc
|
||||
|
||||
|
||||
class Session(BaseAuthentication):
|
||||
"""
|
||||
Same as rest_framework.authentication.SessionAuthentication
|
||||
but without csrf.
|
||||
"""
|
||||
|
||||
def authenticate(self, request):
|
||||
"""
|
||||
Returns a `User` if the request session currently has a logged in user.
|
||||
Otherwise returns `None`.
|
||||
"""
|
||||
|
||||
http_request = request._request
|
||||
user = getattr(http_request, 'user', None)
|
||||
|
||||
if not user or not user.is_active:
|
||||
return None
|
||||
|
||||
return (user, None)
|
||||
|
||||
|
||||
def get_token_for_user(user):
|
||||
data = {"user_id": user.id}
|
||||
return signing.dumps(data)
|
||||
|
||||
|
||||
def get_user_for_token(token):
|
||||
try:
|
||||
data = signing.loads(token)
|
||||
except signing.BadSignature:
|
||||
raise exc.NotAuthenticated("Invalid token")
|
||||
|
||||
model_cls = get_model("users", "User")
|
||||
|
||||
try:
|
||||
user = model_cls.objects.get(pk=data["user_id"])
|
||||
except model_cls.DoesNotExist:
|
||||
raise exc.NotAuthenticated("Invalid token")
|
||||
else:
|
||||
return user
|
||||
|
||||
|
||||
class Token(BaseAuthentication):
|
||||
"""
|
||||
Stateless authentication system partially based on oauth.
|
||||
"""
|
||||
|
||||
auth_rx = re.compile(r"^Bearer (.+)$")
|
||||
|
||||
def authenticate(self, request):
|
||||
if "HTTP_AUTHORIZATION" not in request.META:
|
||||
return None
|
||||
|
||||
token_rx_match = self.auth_rx.search(request.META["HTTP_AUTHORIZATION"])
|
||||
if not token_rx_match:
|
||||
return None
|
||||
|
||||
token = token_rx_match.group(1)
|
||||
user = get_user_for_token(token)
|
||||
return (user, token)
|
||||
|
||||
def authenticate_header(self, request):
|
||||
return 'Bearer realm="api"'
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
"""
|
||||
Authentication backends for rest framework.
|
||||
|
||||
This module exposes two backends: session and token.
|
||||
|
||||
The first (session) is a modified version of standard
|
||||
session authentication backend of restframework with
|
||||
csrf token disabled.
|
||||
|
||||
And the second (token) implements own version of oauth2
|
||||
like authentiacation but with selfcontained tokens. Thats
|
||||
makes authentication totally stateles.
|
||||
|
||||
It uses django signing framework for create new
|
||||
selfcontained tokens. This trust tokes from external
|
||||
fraudulent modifications.
|
||||
"""
|
||||
|
||||
import base64
|
||||
import re
|
||||
|
||||
from django.core import signing
|
||||
from django.db.models import get_model
|
||||
from rest_framework.authentication import BaseAuthentication
|
||||
from taiga.base import exceptions as exc
|
||||
|
||||
|
||||
class Session(BaseAuthentication):
|
||||
"""
|
||||
Session based authentication like the standard
|
||||
`rest_framework.authentication.SessionAuthentication`
|
||||
but with csrf disabled (for obvious reasons because
|
||||
it is for api.
|
||||
|
||||
NOTE: this is only for api web interface. Is not used
|
||||
for common api usage and should be disabled on production.
|
||||
"""
|
||||
|
||||
def authenticate(self, request):
|
||||
http_request = request._request
|
||||
user = getattr(http_request, 'user', None)
|
||||
|
||||
if not user or not user.is_active:
|
||||
return None
|
||||
|
||||
return (user, None)
|
||||
|
||||
|
||||
def get_token_for_user(user):
|
||||
"""
|
||||
Generate a new signed token containing
|
||||
a specified user.
|
||||
"""
|
||||
data = {"user_id": user.id}
|
||||
return signing.dumps(data)
|
||||
|
||||
|
||||
def get_user_for_token(token):
|
||||
"""
|
||||
Given a selfcontained token, try parse and
|
||||
unsign it.
|
||||
|
||||
If token passes a validation, returns
|
||||
a user instance corresponding with user_id stored
|
||||
in the incoming token.
|
||||
"""
|
||||
try:
|
||||
data = signing.loads(token)
|
||||
except signing.BadSignature:
|
||||
raise exc.NotAuthenticated("Invalid token")
|
||||
|
||||
model_cls = get_model("users", "User")
|
||||
|
||||
try:
|
||||
user = model_cls.objects.get(pk=data["user_id"])
|
||||
except model_cls.DoesNotExist:
|
||||
raise exc.NotAuthenticated("Invalid token")
|
||||
else:
|
||||
return user
|
||||
|
||||
|
||||
class Token(BaseAuthentication):
|
||||
"""
|
||||
Self-contained stateles authentication implementatrion
|
||||
that work similar to oauth2.
|
||||
It uses django signing framework for trust data stored
|
||||
in the token.
|
||||
"""
|
||||
|
||||
auth_rx = re.compile(r"^Bearer (.+)$")
|
||||
|
||||
def authenticate(self, request):
|
||||
if "HTTP_AUTHORIZATION" not in request.META:
|
||||
return None
|
||||
|
||||
token_rx_match = self.auth_rx.search(request.META["HTTP_AUTHORIZATION"])
|
||||
if not token_rx_match:
|
||||
return None
|
||||
|
||||
token = token_rx_match.group(1)
|
||||
user = get_user_for_token(token)
|
||||
return (user, token)
|
||||
|
||||
def authenticate_header(self, request):
|
||||
return 'Bearer realm="api"'
|
Loading…
Reference in New Issue