<commit_before>#-*- coding: utf-8 -*-


"""OAuth 2.0 Authentication"""


from hashlib import sha256
from urlparse import parse_qsl
from simplejson import dumps
from django.conf import settings
from django.http import HttpResponse
from .exceptions import OAuth2Exception
from .models import AccessToken, AccessRange, TimestampGenerator
from .consts import REALM, AUTHENTICATION_METHOD, MAC, BEARER

class AuthenticationException(OAuth2Exception):
    """Authentication exception base class."""
    pass


class InvalidRequest(AuthenticationException):
    """The request is missing a required parameter, includes an
    unsupported parameter or parameter value, repeats the same
    parameter, uses more than one method for including an access
    token, or is otherwise malformed."""
    error = 'invalid_request'


class InvalidToken(AuthenticationException):
    """The access token provided is expired, revoked, malformed, or
    invalid for other reasons."""
    error = 'invalid_token'


class InsufficientScope(AuthenticationException):
    """The request requires higher privileges than provided by the
    access token."""
    error = 'insufficient_scope'

class UnvalidatedRequest(OAuth2Exception):
    """The method requested requires a validated request to continue."""
    pass

class Authenticator(object):
    """Django HttpRequest authenticator. Checks a request for valid
    credentials and scope.

    **Kwargs:**

    * *scope:* An iterable of oauth2app.models.AccessRange objects representing
      the scope the authenticator will authenticate.
      *Default None*
    * *authentication_method:* Accepted authentication methods. Possible
      values are: oauth2app.consts.MAC, oauth2app.consts.BEARER, 
      oauth2app.consts.MAC | oauth2app.consts.BEARER, 
      *Default oauth2app.consts.BEARER*

    """

    valid = False
    access_token = None
    auth_type = None
    auth_value = None
    error = None
    attempted_validation = False

    def __init__(
            self, 
            scope=None, 
            authentication_method=AUTHENTICATION_METHOD):         
        if authentication_method not in [BEARER, MAC, BEARER | MAC]:
            raise OAuth2Exception("Possible values for authentication_method" 
                " are oauth2app.consts.MAC, oauth2app.consts.BEARER, "
                "oauth2app.consts.MAC | oauth2app.consts.BEARER")
        self.authentication_method = authentication_method
        if scope is None:
            self.authorized_scope = None
        elif isinstance(scope, AccessRange):
            self.authorized_scope = set([scope.key])
        else:
            self.authorized_scope = set([x.key for x in scope])

    def validate(self, request):
        """Validate the request. Raises an AuthenticationException if the
        request fails authentication.

        **Args:**

        * *request:* Django HttpRequest object.

        *Returns None*"""
        self.request = request
        self.bearer_token = request.REQUEST.get('bearer_token')
        if "HTTP_AUTHORIZATION" in self.request.META:
            auth = self.request.META["HTTP_AUTHORIZATION"].split()
            self.auth_type = auth[0].lower()
            self.auth_value = " ".join(auth[1:]).strip()
        self.request_hostname = self.request.META.get("REMOTE_HOST")
        self.request_port = self.request.META.get("SERVER_PORT")
        try:
            self._validate()
        except AuthenticationException, e:
            self.error = e
            raise e
        self.valid = True

    def _validate(self):
        """Validate the request."""
        # Check for Bearer or Mac authorization
        if self.auth_type in ["bearer", "mac"]:
            self.attempted_validation = True
            if self.auth_type == "bearer":
                self._validate_bearer(self.auth_value)
            elif self.auth_type == "mac":
                self._validate_mac(self.auth_value)
            self.valid = True
        # Check for posted/paramaterized bearer token.
        elif self.bearer_token is not None:
            self.attempted_validation = True
            self._validate_bearer(self.bearer_token)
            self.valid = True
            return
        else:
            raise InvalidRequest("Request authentication failed, no "
                "authentication credentials provided.")
        if self.authorized_scope is not None:
            token_scope = set([x.key for x in self.access_token.scope.all()])
            new_scope = self.authorized_scope - token_scope
            if len(new_scope) > 0:
                raise InsufficientScope(("Access token has insufficient "
                    "scope: %s") % ','.join(self.authorized_scope))
        now = TimestampGenerator()()
        if self.access_token.expire < now:
            raise InvalidToken("Token is expired")

    def _validate_bearer(self, token):
        """Validate Bearer token."""
        if self.authentication_method & BEARER == 0:
            raise InvalidToken("Bearer authentication is not supported.")
        try:
            self.access_token = AccessToken.objects.get(token=token)
        except AccessToken.DoesNotExist:
            raise InvalidToken("Token doesn't exist")

    def _validate_mac(self, mac_header):
        """Validate MAC authentication. Not implemented."""
        if self.authentication_method & MAC == 0:
            raise InvalidToken("MAC authentication is not supported.")
        mac_header = parse_qsl(mac_header.replace(",","&").replace('"', ''))
        mac_header = dict([(x[0].strip(), x[1].strip()) for x in mac_header])
        for parameter in ["id", "nonce", "mac"]:
            if "parameter" not in mac_header:<commit_msg>Check for sufficient scope when bearer_token is provided as GET/POST param<commit_after>#-*- coding: utf-8 -*-


"""OAuth 2.0 Authentication"""


from hashlib import sha256
from urlparse import parse_qsl
from simplejson import dumps
from django.conf import settings
from django.http import HttpResponse
from .exceptions import OAuth2Exception
from .models import AccessToken, AccessRange, TimestampGenerator
from .consts import REALM, AUTHENTICATION_METHOD, MAC, BEARER

class AuthenticationException(OAuth2Exception):
    """Authentication exception base class."""
    pass


class InvalidRequest(AuthenticationException):
    """The request is missing a required parameter, includes an
    unsupported parameter or parameter value, repeats the same
    parameter, uses more than one method for including an access
    token, or is otherwise malformed."""
    error = 'invalid_request'


class InvalidToken(AuthenticationException):
    """The access token provided is expired, revoked, malformed, or
    invalid for other reasons."""
    error = 'invalid_token'


class InsufficientScope(AuthenticationException):
    """The request requires higher privileges than provided by the
    access token."""
    error = 'insufficient_scope'

class UnvalidatedRequest(OAuth2Exception):
    """The method requested requires a validated request to continue."""
    pass

class Authenticator(object):
    """Django HttpRequest authenticator. Checks a request for valid
    credentials and scope.

    **Kwargs:**

    * *scope:* An iterable of oauth2app.models.AccessRange objects representing
      the scope the authenticator will authenticate.
      *Default None*
    * *authentication_method:* Accepted authentication methods. Possible
      values are: oauth2app.consts.MAC, oauth2app.consts.BEARER, 
      oauth2app.consts.MAC | oauth2app.consts.BEARER, 
      *Default oauth2app.consts.BEARER*

    """

    valid = False
    access_token = None
    auth_type = None
    auth_value = None
    error = None
    attempted_validation = False

    def __init__(
            self, 
            scope=None, 
            authentication_method=AUTHENTICATION_METHOD):         
        if authentication_method not in [BEARER, MAC, BEARER | MAC]:
            raise OAuth2Exception("Possible values for authentication_method" 
                " are oauth2app.consts.MAC, oauth2app.consts.BEARER, "
                "oauth2app.consts.MAC | oauth2app.consts.BEARER")
        self.authentication_method = authentication_method
        if scope is None:
            self.authorized_scope = None
        elif isinstance(scope, AccessRange):
            self.authorized_scope = set([scope.key])
        else:
            self.authorized_scope = set([x.key for x in scope])

    def validate(self, request):
        """Validate the request. Raises an AuthenticationException if the
        request fails authentication.

        **Args:**

        * *request:* Django HttpRequest object.

        *Returns None*"""
        self.request = request
        self.bearer_token = request.REQUEST.get('bearer_token')
        if "HTTP_AUTHORIZATION" in self.request.META:
            auth = self.request.META["HTTP_AUTHORIZATION"].split()
            self.auth_type = auth[0].lower()
            self.auth_value = " ".join(auth[1:]).strip()
        self.request_hostname = self.request.META.get("REMOTE_HOST")
        self.request_port = self.request.META.get("SERVER_PORT")
        try:
            self._validate()
        except AuthenticationException, e:
            self.error = e
            raise e
        self.valid = True

    def _validate(self):
        """Validate the request."""
        # Check for Bearer or Mac authorization
        if self.auth_type in ["bearer", "mac"]:
            self.attempted_validation = True
            if self.auth_type == "bearer":
                self._validate_bearer(self.auth_value)
            elif self.auth_type == "mac":
                self._validate_mac(self.auth_value)
            self.valid = True
        # Check for posted/paramaterized bearer token.
        elif self.bearer_token is not None:
            self.attempted_validation = True
            self._validate_bearer(self.bearer_token)
            self.valid = True
        else:
            raise InvalidRequest("Request authentication failed, no "
                "authentication credentials provided.")
        if self.authorized_scope is not None:
            token_scope = set([x.key for x in self.access_token.scope.all()])
            new_scope = self.authorized_scope - token_scope
            if len(new_scope) > 0:
                raise InsufficientScope(("Access token has insufficient "
                    "scope: %s") % ','.join(self.authorized_scope))
        now = TimestampGenerator()()
        if self.access_token.expire < now:
            raise InvalidToken("Token is expired")

    def _validate_bearer(self, token):
        """Validate Bearer token."""
        if self.authentication_method & BEARER == 0:
            raise InvalidToken("Bearer authentication is not supported.")
        try:
            self.access_token = AccessToken.objects.get(token=token)
        except AccessToken.DoesNotExist:
            raise InvalidToken("Token doesn't exist")

    def _validate_mac(self, mac_header):
        """Validate MAC authentication. Not implemented."""
        if self.authentication_method & MAC == 0:
            raise InvalidToken("MAC authentication is not supported.")
        mac_header = parse_qsl(mac_header.replace(",","&").replace('"', ''))
        mac_header = dict([(x[0].strip(), x[1].strip()) for x in mac_header])
        for parameter in ["id", "nonce", "mac"]:
            if "parameter" not in mac_header:
{'fraction_non_alphanumeric': 0.09269613838895684, 'fraction_numerical': 0.00471780534684606, 'mean_word_length': 2.6351222610352494, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3679425', 'n_tokens_mistral': 3095, 'n_tokens_neox': 3006, 'n_words': 862}