<commit_before>import httplib as http
import functools
import logging

from framework import request, redirect
from framework.exceptions import HTTPError
from framework.auth import get_current_user, get_api_key
from framework.auth.decorators import Auth
from framework.sessions import get_redirect_from_key, session
from website.models import Node
from website.util import web_url_for

logger = logging.getLogger(__name__)

debug = logger.debug


def _kwargs_to_nodes(kwargs):
    """Retrieve project and component objects from keyword arguments.

    :param dict kwargs: Dictionary of keyword arguments
    :return: Tuple of project and component

    """
    project = kwargs.get('project') or Node.load(kwargs.get('pid', kwargs.get('nid')))
    if not project:
        raise HTTPError(http.NOT_FOUND)
    if project.category != 'project':
        raise HTTPError(http.BAD_REQUEST)
    if project.is_deleted:
        raise HTTPError(http.GONE)

    if kwargs.get('nid') or kwargs.get('node'):
        node = kwargs.get('node') or Node.load(kwargs.get('nid'))
        if not node:
            raise HTTPError(http.NOT_FOUND)
        if node.is_deleted:
            raise HTTPError(http.GONE)
    else:
        node = None

    return project, node


def must_be_valid_project(func):

    # TODO: Check private link

    @functools.wraps(func)
    def wrapped(*args, **kwargs):

        kwargs['project'], kwargs['node'] = _kwargs_to_nodes(kwargs)
        return func(*args, **kwargs)

    return wrapped


def must_not_be_registration(func):

    @functools.wraps(func)
    def wrapped(*args, **kwargs):

        kwargs['project'], kwargs['node'] = _kwargs_to_nodes(kwargs)
        node = kwargs['node'] or kwargs['project']

        if node.is_registration:
            raise HTTPError(http.BAD_REQUEST)
        return func(*args, **kwargs)

    return wrapped


def get_key_ring():
    return set(session.data.get('key', []))


def check_can_access(node, user, api_node=None):
    """View helper that returns whether a given user can access a node.
    If ``user`` is None, returns False.

    :rtype: boolean
    :raises: HTTPError (403) if user cannot access the node
    """
    if user is None:
        return False
    if not node.is_contributor(user) \
            and api_node != node:
        raise HTTPError(http.FORBIDDEN)
    return True


def choose_key(key, key_ring, node, auth, api_node=None):
    """Returns ``None`` if the given key is valid, else return a redirect
    response to the requested URL with the correct key from the key_ring.
    """
    if key in node.private_links:
        auth.private_key = key
        response = None
    else:
        auth.private_key = key_ring.intersection(
            node.private_links
        ).pop()
        #do a redirect to reappend the key to url only if the user
        # isn't a contributor
        if auth.user is None or (not node.is_contributor(auth.user) and api_node != node):
            response = get_redirect_from_key(auth.private_key)
    return response


def _must_be_contributor_factory(include_public):
    """Decorator factory for authorization wrappers. Decorators verify whether
    the current user is a contributor on the current project, or optionally
    whether the current project is public.

    :param bool include_public: Check whether current project is public
    :return: Authorization decorator

    """
    def wrapper(func):

        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            response = None
            kwargs['project'], kwargs['node'] = _kwargs_to_nodes(kwargs)
            node = kwargs['node'] or kwargs['project']

            kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs)
            user = kwargs['auth'].user

            if 'api_node' in kwargs:
                api_node = kwargs['api_node']
            else:
                api_node = get_api_key()
                kwargs['api_node'] = api_node

            link = request.args.get('key', '').strip('/')
            #if not login user check if the link is valid or the other privilege
            if not session:
                kwargs['auth'].private_key = link
                if not node.is_public or not include_public:
                    if link not in node.private_links:
                        if not check_can_access(node=node, user=user,
                                api_node=api_node):
                            response = redirect(
                                web_url_for('auth_login', next=request.path))
            #for login user
            else:
                #link first time show up record it in the key ring
                if link not in session.data['key']:
                    session.data['key'].append(link)
                key_ring = get_key_ring()

                #check if the keyring has intersection with node's private link
                # if no intersction check other privilege
                if not node.is_public or not include_public:
                    if key_ring.isdisjoint(node.private_links):
                        if not check_can_access(node=node, user=user,
                                api_node=api_node):
                            response = redirect(
                                web_url_for('auth_login', next=request.path))
                        kwargs['auth'].private_key = None

                    #has intersection: check if the link is valid if not use other key
                    # in the key ring
                    else:
                        response = choose_key(
                            key=link, key_ring=key_ring, node=node,
                            auth=kwargs['auth'], api_node=api_node)
                else:
                    kwargs['auth'].private_key = None
                return response or func(*args, **kwargs)<commit_msg>Decorator no longer needs request context (hack for tests to pass)<commit_after>import httplib as http
import functools
import logging

from framework import request, redirect
from framework.exceptions import HTTPError
from framework.auth import get_current_user, get_api_key
from framework.auth.decorators import Auth
from framework.sessions import get_redirect_from_key, session
from website.models import Node
from website.util import web_url_for

logger = logging.getLogger(__name__)

debug = logger.debug


def _kwargs_to_nodes(kwargs):
    """Retrieve project and component objects from keyword arguments.

    :param dict kwargs: Dictionary of keyword arguments
    :return: Tuple of project and component

    """
    project = kwargs.get('project') or Node.load(kwargs.get('pid', kwargs.get('nid')))
    if not project:
        raise HTTPError(http.NOT_FOUND)
    if project.category != 'project':
        raise HTTPError(http.BAD_REQUEST)
    if project.is_deleted:
        raise HTTPError(http.GONE)

    if kwargs.get('nid') or kwargs.get('node'):
        node = kwargs.get('node') or Node.load(kwargs.get('nid'))
        if not node:
            raise HTTPError(http.NOT_FOUND)
        if node.is_deleted:
            raise HTTPError(http.GONE)
    else:
        node = None

    return project, node


def must_be_valid_project(func):

    # TODO: Check private link

    @functools.wraps(func)
    def wrapped(*args, **kwargs):

        kwargs['project'], kwargs['node'] = _kwargs_to_nodes(kwargs)
        return func(*args, **kwargs)

    return wrapped


def must_not_be_registration(func):

    @functools.wraps(func)
    def wrapped(*args, **kwargs):

        kwargs['project'], kwargs['node'] = _kwargs_to_nodes(kwargs)
        node = kwargs['node'] or kwargs['project']

        if node.is_registration:
            raise HTTPError(http.BAD_REQUEST)
        return func(*args, **kwargs)

    return wrapped


def get_key_ring():
    return set(session.data.get('key', []))


def check_can_access(node, user, api_node=None):
    """View helper that returns whether a given user can access a node.
    If ``user`` is None, returns False.

    :rtype: boolean
    :raises: HTTPError (403) if user cannot access the node
    """
    if user is None:
        return False
    if not node.is_contributor(user) \
            and api_node != node:
        raise HTTPError(http.FORBIDDEN)
    return True


def choose_key(key, key_ring, node, auth, api_node=None):
    """Returns ``None`` if the given key is valid, else return a redirect
    response to the requested URL with the correct key from the key_ring.
    """
    if key in node.private_links:
        auth.private_key = key
        response = None
    else:
        auth.private_key = key_ring.intersection(
            node.private_links
        ).pop()
        #do a redirect to reappend the key to url only if the user
        # isn't a contributor
        if auth.user is None or (not node.is_contributor(auth.user) and api_node != node):
            response = get_redirect_from_key(auth.private_key)
    return response


def _must_be_contributor_factory(include_public):
    """Decorator factory for authorization wrappers. Decorators verify whether
    the current user is a contributor on the current project, or optionally
    whether the current project is public.

    :param bool include_public: Check whether current project is public
    :return: Authorization decorator

    """
    def wrapper(func):

        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            response = None
            kwargs['project'], kwargs['node'] = _kwargs_to_nodes(kwargs)
            node = kwargs['node'] or kwargs['project']

            kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs)
            user = kwargs['auth'].user

            if 'api_node' in kwargs:
                api_node = kwargs['api_node']
            else:
                api_node = get_api_key()
                kwargs['api_node'] = api_node

            link = request.args.get('key', '').strip('/')
            #if not login user check if the link is valid or the other privilege
            if not session:
                kwargs['auth'].private_key = link
                if not node.is_public or not include_public:
                    if link not in node.private_links:
                        if not check_can_access(node=node, user=user,
                                api_node=api_node):
                            url = '/login/?next={0}'.format(request.path)
                            response = redirect(url)
            #for login user
            else:
                #link first time show up record it in the key ring
                if link not in session.data['key']:
                    session.data['key'].append(link)
                key_ring = get_key_ring()

                #check if the keyring has intersection with node's private link
                # if no intersction check other privilege
                if not node.is_public or not include_public:
                    if key_ring.isdisjoint(node.private_links):
                        if not check_can_access(node=node, user=user,
                                api_node=api_node):
                            redirect_url = '/login/?next={0}'.format(request.path)
                            response = redirect(redirect_url)
                        kwargs['auth'].private_key = None

                    #has intersection: check if the link is valid if not use other key
                    # in the key ring
                    else:
                        response = choose_key(
                            key=link, key_ring=key_ring, node=node,
                            auth=kwargs['auth'], api_node=api_node)
                else:
                    kwargs['auth'].private_key = None
            return response or func(*args, **kwargs)
{'fraction_non_alphanumeric': 0.08799796143718679, 'fraction_numerical': 0.0006795209377388941, 'mean_word_length': 2.1239055452374633, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '1439053', 'n_tokens_mistral': 3207, 'n_tokens_neox': 3149, 'n_words': 967}