# -*- 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 greenmine.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.BadRequest("Invalid token")

    model_cls = get_model("users", "User")

    try:
        user = model_cls.objects.get(pk=data["user_id"])
    except model_cls.DoesNotExist:
        raise exc.BadRequest("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"'

# -*- 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 greenmine.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"'

Change exceptions on token parsing.