<commit_before># -*- coding: utf-8 -*-
"""OAuth views for the Dropbox addon."""
import httplib as http
import os
import logging

from dropbox.client import DropboxOAuth2Flow

from framework.auth import get_current_user
from framework.exceptions import HTTPError
from framework.sessions import session
from framework import redirect, request
from framework.status import push_status_message as flash
from framework.auth.decorators import must_be_logged_in
from website.project.model import Node
from website.project.decorators import must_have_addon
from website.util import api_url_for, web_url_for

from website.addons.dropbox import settings
from website.addons.dropbox.client import get_client_from_user_settings


logger = logging.getLogger(__name__)
debug = logger.debug


def get_auth_flow():
    redirect_uri = api_url_for('dropbox_oauth_finish', _external=True)
    return DropboxOAuth2Flow(
        consumer_key=settings.DROPBOX_KEY,
        consumer_secret=settings.DROPBOX_SECRET,
        redirect_uri=redirect_uri,
        session=session.data,
        csrf_token_session_key=settings.DROPBOX_AUTH_CSRF_TOKEN
    )


def finish_auth():
    """View helper for finishing the Dropbox Oauth2 flow. Returns the
    access_token, dropbox_id, and url_state.

    Handles various errors that may be raised by the Dropbox client.
    """
    try:
        access_token, dropbox_id, url_state = get_auth_flow().finish(request.args)
    except DropboxOAuth2Flow.BadRequestException:
        raise HTTPError(http.BAD_REQUEST)
    except DropboxOAuth2Flow.BadStateException:
        # Start auth flow again
        redirect(api_url_for('dropbox_oauth_start'))
    except DropboxOAuth2Flow.CsrfException:
        raise HTTPError(http.FORBIDDEN)
    except DropboxOAuth2Flow.NotApprovedException:
        flash('Could not approve token.')
        return redirect(web_url_for('profile_settings'))
    except DropboxOAuth2Flow.ProviderException:
        raise HTTPError(http.FORBIDDEN)
    return access_token, dropbox_id, url_state


@must_be_logged_in
def dropbox_oauth_start(**kwargs):
    user = get_current_user()
    # Store the node ID on the session in order to get the correct redirect URL
    # upon finishing the flow
    nid = kwargs.get('pid') or kwargs.get('nid')
    if nid:
        session.data['dropbox_auth_nid'] = nid
    if not user:
        raise HTTPError(http.FORBIDDEN)
    # If user has already authorized dropbox, flash error message
    if user.has_addon('dropbox') and user.get_addon('dropbox').has_auth:
        flash('You have already authorized Dropbox for this account', 'warning')
        return redirect(web_url_for('profile_settings'))
    return redirect(get_auth_flow().start())


def dropbox_oauth_finish(**kwargs):
    """View called when the Oauth flow is completed. Adds a new DropboxUserSettings
    record to the user and saves the user's access token and account info.
    """
    user = get_current_user()
    if not user:
        raise HTTPError(http.FORBIDDEN)
    node = Node.load(session.data.get('dropbox_auth_nid'))
    access_token, dropbox_id, url_state = finish_auth()
    # Make sure user has dropbox enabled
    user.add_addon('dropbox')
    user.save()
    user_settings = user.get_addon('dropbox')
    user_settings.owner = user
    user_settings.access_token = access_token
    user_settings.dropbox_id = dropbox_id
    user_settings.update_account_info()
    user_settings.save()

    flash('Successfully authorized Dropbox', 'success')
    if node:
        del session.data['dropbox_auth_nid']
        # Automatically use newly-created auth
        if node.has_addon('dropbox'):
            node_addon = node.get_addon('dropbox')
            node_addon.set_user_auth(user_settings)
            node_addon.save()
        return redirect(node.web_url_for('node_setting'))
    return redirect(web_url_for('profile_settings'))


@must_have_addon('dropbox', 'user')
def dropbox_oauth_delete_user(user_addon, **kwargs):
    """View for deauthorizing Dropbox."""
    client = get_client_from_user_settings(user_addon)
    client.disable_access_token()
    user_addon.clear_auth()
    user_addon.save()
    return None


@must_be_logged_in
@must_have_addon('dropbox', 'user')<commit_msg>Fix error raised if user cancels during OAuth flow<commit_after># -*- coding: utf-8 -*-
"""OAuth views for the Dropbox addon."""
import httplib as http
import logging
from collections import namedtuple

from dropbox.client import DropboxOAuth2Flow
from werkzeug.wrappers import BaseResponse

from framework.auth import get_current_user
from framework.exceptions import HTTPError
from framework.sessions import session
from framework import redirect, request
from framework.status import push_status_message as flash
from framework.auth.decorators import must_be_logged_in
from website.project.model import Node
from website.project.decorators import must_have_addon
from website.util import api_url_for, web_url_for

from website.addons.dropbox import settings
from website.addons.dropbox.client import get_client_from_user_settings


logger = logging.getLogger(__name__)
debug = logger.debug


def get_auth_flow():
    redirect_uri = api_url_for('dropbox_oauth_finish', _external=True)
    return DropboxOAuth2Flow(
        consumer_key=settings.DROPBOX_KEY,
        consumer_secret=settings.DROPBOX_SECRET,
        redirect_uri=redirect_uri,
        session=session.data,
        csrf_token_session_key=settings.DROPBOX_AUTH_CSRF_TOKEN
    )

AuthResult = namedtuple('AuthResult', ['access_token', 'dropbox_id', 'url_state'])

def finish_auth():
    """View helper for finishing the Dropbox Oauth2 flow. Returns the
    access_token, dropbox_id, and url_state.

    Handles various errors that may be raised by the Dropbox client.
    """
    try:
        access_token, dropbox_id, url_state = get_auth_flow().finish(request.args)
    except DropboxOAuth2Flow.BadRequestException:
        raise HTTPError(http.BAD_REQUEST)
    except DropboxOAuth2Flow.BadStateException:
        # Start auth flow again
        return redirect(api_url_for('dropbox_oauth_start'))
    except DropboxOAuth2Flow.CsrfException:
        raise HTTPError(http.FORBIDDEN)
    except DropboxOAuth2Flow.NotApprovedException:  # User canceled flow
        flash('Did not approve token.', 'info')
        return redirect(web_url_for('profile_settings'))
    except DropboxOAuth2Flow.ProviderException:
        raise HTTPError(http.FORBIDDEN)
    return AuthResult(access_token, dropbox_id, url_state)


@must_be_logged_in
def dropbox_oauth_start(**kwargs):
    user = get_current_user()
    # Store the node ID on the session in order to get the correct redirect URL
    # upon finishing the flow
    nid = kwargs.get('pid') or kwargs.get('nid')
    if nid:
        session.data['dropbox_auth_nid'] = nid
    if not user:
        raise HTTPError(http.FORBIDDEN)
    # If user has already authorized dropbox, flash error message
    if user.has_addon('dropbox') and user.get_addon('dropbox').has_auth:
        flash('You have already authorized Dropbox for this account', 'warning')
        return redirect(web_url_for('profile_settings'))
    return redirect(get_auth_flow().start())


def dropbox_oauth_finish(**kwargs):
    """View called when the Oauth flow is completed. Adds a new DropboxUserSettings
    record to the user and saves the user's access token and account info.
    """
    user = get_current_user()
    if not user:
        raise HTTPError(http.FORBIDDEN)
    node = Node.load(session.data.get('dropbox_auth_nid'))
    result = finish_auth()
    # If result is a redirect response, follow the redirect
    if isinstance(result, BaseResponse):
        return result
    # Make sure user has dropbox enabled
    user.add_addon('dropbox')
    user.save()
    user_settings = user.get_addon('dropbox')
    user_settings.owner = user
    user_settings.access_token = result.access_token
    user_settings.dropbox_id = result.dropbox_id
    user_settings.update_account_info()
    user_settings.save()

    flash('Successfully authorized Dropbox', 'success')
    if node:
        del session.data['dropbox_auth_nid']
        # Automatically use newly-created auth
        if node.has_addon('dropbox'):
            node_addon = node.get_addon('dropbox')
            node_addon.set_user_auth(user_settings)
            node_addon.save()
        return redirect(node.web_url_for('node_setting'))
    return redirect(web_url_for('profile_settings'))


@must_have_addon('dropbox', 'user')
def dropbox_oauth_delete_user(user_addon, **kwargs):
    """View for deauthorizing Dropbox."""
    client = get_client_from_user_settings(user_addon)
    client.disable_access_token()
    user_addon.clear_auth()
    user_addon.save()
    return None


@must_be_logged_in
@must_have_addon('dropbox', 'user')
{'fraction_non_alphanumeric': 0.08273748723186926, 'fraction_numerical': 0.0020429009193054137, 'mean_word_length': 4.093641618497109, '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': '6422258', 'n_tokens_mistral': 2683, 'n_tokens_neox': 2677, 'n_words': 655}