<commit_before>from __future__ import absolute_import

import requests
import logging
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth import logout as auth_logout
from django.shortcuts import redirect
from .models import OAuth
import json
from datetime import datetime, timedelta
import dateutil.parser
import pytz

logger = logging.getLogger(__name__)


def auto_logout(get_response):
    def middleware(request):
        # Only check for auto logout if we're logged in.
        if not request.user.is_authenticated():
            return get_response(request)

        last_active_at_iso = request.session.get(settings.SESSION_USER_LAST_ACTIVE_AT)
        if last_active_at_iso:
            # Check if our inactive time has exceeded the auto logout time limit.
            last_active_at = dateutil.parser.parse(last_active_at_iso)
            time_passed = datetime.utcnow().replace(tzinfo=pytz.utc) - last_active_at
            if time_passed >= timedelta(0, settings.AUTO_LOGOUT_SECONDS, 0):
                # Force logout and redirect to login page.
                auth_logout(request)
                response = redirect('login')
                if settings.SESSION_USER_LAST_ACTIVE_AT in request.session:
                    del request.session[settings.SESSION_USER_LAST_ACTIVE_AT]
                response.delete_cookie(settings.AUTO_LOGOUT_COOKIE_NAME, domain=settings.SESSION_COOKIE_DOMAIN)
                return response

        return get_response(request)

    return middleware


def fetch_user_from_token(access_token):
    """
    
    :param access_token: Uses OAuth token to retrieve user data from the resource server.
    :return: User object.
    """

    logger.debug('Sending request: access_token="{0}"'.format(access_token))
    try:
        response = requests.get(
            '{0}'.format(settings.OAUTH_PROFILE_URL),
            headers={
                'Authorization': 'Bearer {0}'.format(access_token),
            },
        )
        logger.debug('Received response: {0}'.format(response.text))
        response.raise_for_status()
    except requests.ConnectionError as err:
        logger.error('Could not reach OAuth Resource Server: {0}'.format(err))
        raise OAuthServerUnreachable()
    except requests.HTTPError as err:
        status_code = err.response.status_code
        if status_code == 401:
            logger.error('OAuth Resource Server rejected access token: {0}'.format(err.response.text))
            raise Unauthorized('OAuth Resource Server rejected access token')
        logger.error('OAuth Resource Server returned HTTP {0} {1}'.format(status_code, err.response.text))
        raise OAuthError(status_code)

    orig_data = response.json()
    user_data = get_user_data_from_schema(orig_data)

    return get_user(user_data, orig_data)


def get_user(user_data, orig_data=None):
    """
    A helper function for retrieving or creating a user given a user_data dictionary.
    :param user_data: A dict containg user data.
    :param orig_data: The original dictionary returned from the OAuth response, not modified to fit our User model.
    :return: 
    """
    oauth = OAuth.objects.filter(identification=user_data.get('identification')).first()
    if not oauth:
        if orig_data is None:
            orig_data = {}
        try:
            identification = user_data.pop('identification')
            commonname = user_data.pop('commonname')
        except KeyError as ke:
            logger.error("Required field not provided.")
            raise ke
        try:
            user = User.objects.create(**user_data)
        except Exception as e:
            logger.error("The user data provided could not be used to create a user, "
                         "it most likely caused by OAUTH_PROFILE_SCHEMA containing an invalid key.")
            raise e
        try:
            OAuth.objects.create(user=user, identification=identification, commonname=commonname, user_info=orig_data)
        except Exception as e:
            logger.error("The user data provided by the resource server could not be used to create a user, "
                         "it most likely caused by OAUTH_PROFILE_SCHEMA mapping is incorrect and/or not providing "
                         "a valid identification and commonname.")
            user.delete()
            raise e
        user_data['identification'] = identification
        user_data['commonname'] = commonname
        return user
    else:
        return oauth.user


def get_user_data_from_schema(data):
    """
    Uses schema provided in settings to get user_data.
    :param data: user profile data from oauth_service 
    :return: a dict of user_data.
    """
    user_data = dict()
    try:
        mapping = json.loads(settings.OAUTH_PROFILE_SCHEMA)
    except AttributeError:
        logger.error("AN OAUTH_PROFILE_SCHEMA was not added to the environment variables.")
        raise
    except ValueError:
        raise Error("An invalid json string was added to OAUTH_PROFILE_SCHEMA, please ensure names and values are "
                    "quoted properly, that quotes are terminated, and that it is surrounded by braces.")
    except TypeError:
        raise Error("AN OAUTH_PROFILE_SCHEMA was added to the environment but it is empty.  Please add a valid "
                    "mapping.")
    if not mapping:
        raise Error("AN OAUTH_PROFILE_SCHEMA was added to the environment but it an empty json object.  Please add a "
                    "valid mapping.")
    for key, value_list in mapping.iteritems():
        if value_list is not list:
            value_list = [value_list]
        for value in value_list:
            try:
                user_data[key] = data[value]
                break
            except KeyError:
                continue
    return user_data


def request_access_token(auth_code):

    logger.debug('Requesting: code="{0}"'.format(auth_code))
    try:
        response = requests.post(
            settings.OAUTH_TOKEN_URL,
            auth=(settings.OAUTH_CLIENT_ID, settings.OAUTH_CLIENT_SECRET),
            data={
                'grant_type': 'authorization_code',<commit_msg>fixing type issue<commit_after>from __future__ import absolute_import

import requests
import logging
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth import logout as auth_logout
from django.shortcuts import redirect
from .models import OAuth
import json
from datetime import datetime, timedelta
import dateutil.parser
import pytz

logger = logging.getLogger(__name__)


def auto_logout(get_response):
    def middleware(request):
        # Only check for auto logout if we're logged in.
        if not request.user.is_authenticated():
            return get_response(request)

        last_active_at_iso = request.session.get(settings.SESSION_USER_LAST_ACTIVE_AT)
        if last_active_at_iso:
            # Check if our inactive time has exceeded the auto logout time limit.
            last_active_at = dateutil.parser.parse(last_active_at_iso)
            time_passed = datetime.utcnow().replace(tzinfo=pytz.utc) - last_active_at
            if time_passed >= timedelta(0, settings.AUTO_LOGOUT_SECONDS, 0):
                # Force logout and redirect to login page.
                auth_logout(request)
                response = redirect('login')
                if settings.SESSION_USER_LAST_ACTIVE_AT in request.session:
                    del request.session[settings.SESSION_USER_LAST_ACTIVE_AT]
                response.delete_cookie(settings.AUTO_LOGOUT_COOKIE_NAME, domain=settings.SESSION_COOKIE_DOMAIN)
                return response

        return get_response(request)

    return middleware


def fetch_user_from_token(access_token):
    """
    
    :param access_token: Uses OAuth token to retrieve user data from the resource server.
    :return: User object.
    """

    logger.debug('Sending request: access_token="{0}"'.format(access_token))
    try:
        response = requests.get(
            '{0}'.format(settings.OAUTH_PROFILE_URL),
            headers={
                'Authorization': 'Bearer {0}'.format(access_token),
            },
        )
        logger.debug('Received response: {0}'.format(response.text))
        response.raise_for_status()
    except requests.ConnectionError as err:
        logger.error('Could not reach OAuth Resource Server: {0}'.format(err))
        raise OAuthServerUnreachable()
    except requests.HTTPError as err:
        status_code = err.response.status_code
        if status_code == 401:
            logger.error('OAuth Resource Server rejected access token: {0}'.format(err.response.text))
            raise Unauthorized('OAuth Resource Server rejected access token')
        logger.error('OAuth Resource Server returned HTTP {0} {1}'.format(status_code, err.response.text))
        raise OAuthError(status_code)

    orig_data = response.json()
    user_data = get_user_data_from_schema(orig_data)

    return get_user(user_data, orig_data)


def get_user(user_data, orig_data=None):
    """
    A helper function for retrieving or creating a user given a user_data dictionary.
    :param user_data: A dict containg user data.
    :param orig_data: The original dictionary returned from the OAuth response, not modified to fit our User model.
    :return: 
    """
    oauth = OAuth.objects.filter(identification=user_data.get('identification')).first()
    if not oauth:
        if orig_data is None:
            orig_data = {}
        try:
            identification = user_data.pop('identification')
            commonname = user_data.pop('commonname')
        except KeyError as ke:
            logger.error("Required field not provided.")
            raise ke
        try:
            user = User.objects.create(**user_data)
        except Exception as e:
            logger.error("The user data provided could not be used to create a user, "
                         "it most likely caused by OAUTH_PROFILE_SCHEMA containing an invalid key.")
            raise e
        try:
            OAuth.objects.create(user=user, identification=identification, commonname=commonname, user_info=orig_data)
        except Exception as e:
            logger.error("The user data provided by the resource server could not be used to create a user, "
                         "it most likely caused by OAUTH_PROFILE_SCHEMA mapping is incorrect and/or not providing "
                         "a valid identification and commonname.")
            user.delete()
            raise e
        user_data['identification'] = identification
        user_data['commonname'] = commonname
        return user
    else:
        return oauth.user


def get_user_data_from_schema(data):
    """
    Uses schema provided in settings to get user_data.
    :param data: user profile data from oauth_service 
    :return: a dict of user_data.
    """
    user_data = dict()
    try:
        mapping = json.loads(settings.OAUTH_PROFILE_SCHEMA)
    except AttributeError:
        logger.error("AN OAUTH_PROFILE_SCHEMA was not added to the environment variables.")
        raise
    except ValueError:
        raise Error("An invalid json string was added to OAUTH_PROFILE_SCHEMA, please ensure names and values are "
                    "quoted properly, that quotes are terminated, and that it is surrounded by braces.")
    except TypeError:
        raise Error("AN OAUTH_PROFILE_SCHEMA was added to the environment but it is empty.  Please add a valid "
                    "mapping.")
    if not mapping:
        raise Error("AN OAUTH_PROFILE_SCHEMA was added to the environment but it an empty json object.  Please add a "
                    "valid mapping.")
    for key, value_list in mapping.iteritems():
        if type(value_list) is not list:
            value_list = [value_list]
        for value in value_list:
            try:
                user_data[key] = data[value]
                break
            except KeyError:
                continue
    return user_data


def request_access_token(auth_code):

    logger.debug('Requesting: code="{0}"'.format(auth_code))
    try:
        response = requests.post(
            settings.OAUTH_TOKEN_URL,
            auth=(settings.OAUTH_CLIENT_ID, settings.OAUTH_CLIENT_SECRET),
            data={
                'grant_type': 'authorization_code',
{'fraction_non_alphanumeric': 0.07471819645732689, 'fraction_numerical': 0.0022544283413848632, 'mean_word_length': 2.5276909968758874, 'pattern_counts': {'":': 0, '<': 3, '<?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': '7630067', 'n_tokens_mistral': 3377, 'n_tokens_neox': 3306, 'n_words': 993}