Пример #1
0
def googledrive_oauth_start(auth, **kwargs):
    """View function that does OAuth Authorization
    and returns access token"""
    # Run through the OAuth flow and retrieve credentials
    # Store the node ID on the session in order to get the correct redirect URL
    # upon finishing the flow
    user = auth.user
    nid = kwargs.get('nid') or kwargs.get('pid')
    node = models.Node.load(nid) if nid else None
    node_addon = user.get_addon('googledrive')

    # Fail if node provided and user not contributor
    if node and not node.is_contributor(user):
        raise HTTPError(http.FORBIDDEN)

    # Handle if user has already authorized google drive
    if node_addon and node_addon.has_auth:
        return redirect(web_url_for('user_addons'))

    client = GoogleAuthClient()
    authorization_url, state = client.start()

    session.data['googledrive_auth_state'] = state
    if nid:
        session.data['googledrive_auth_nid'] = nid

    return redirect(authorization_url)
Пример #2
0
def googledrive_oauth_start(auth, **kwargs):
    """View function that does OAuth Authorization
    and returns access token"""
    # Run through the OAuth flow and retrieve credentials
    # Store the node ID on the session in order to get the correct redirect URL
    # upon finishing the flow
    user = auth.user
    nid = kwargs.get('nid') or kwargs.get('pid')
    node = models.Node.load(nid) if nid else None
    node_addon = user.get_addon('googledrive')

    # Fail if node provided and user not contributor
    if node and not node.is_contributor(user):
        raise HTTPError(http.FORBIDDEN)

    # Handle if user has already authorized google drive
    if node_addon and node_addon.has_auth:
        return redirect(web_url_for('user_addons'))

    client = GoogleAuthClient()
    authorization_url, state = client.start()

    session.data['googledrive_auth_state'] = state
    if nid:
        session.data['googledrive_auth_nid'] = nid

    return redirect(authorization_url)
Пример #3
0
    def refresh_access_token(self, force=False):
        if self._needs_refresh() or force:
            client = GoogleAuthClient()
            token = client.refresh(self.access_token, self.refresh_token)

            self.access_token = token['access_token']
            self.refresh_token = token['refresh_token']
            self.expires_at = datetime.utcfromtimestamp(token['expires_at'])
            self.save()
Пример #4
0
    def refresh_access_token(self, force=False):
        if self._needs_refresh() or force:
            client = GoogleAuthClient()
            token = client.refresh(self.access_token, self.refresh_token)

            self.access_token = token['access_token']
            self.refresh_token = token['refresh_token']
            self.expires_at = datetime.utcfromtimestamp(token['expires_at'])
            self.save()
Пример #5
0
def googledrive_oauth_finish(auth, **kwargs):
    """View called when the Oauth flow is completed. Adds a new GoogleDriveUserSettings
    record to the user and saves the user's access token and account info.
    """
    user = auth.user
    node = Node.load(session.data.pop('googledrive_auth_nid', None))

    # Handle request cancellations from Google's API
    if request.args.get('error'):
        flash('Google Drive authorization request cancelled.')
        if node:
            return redirect(node.web_url_for('node_setting'))
        return redirect(web_url_for('user_addons'))

    user.add_addon('googledrive')
    user.save()

    code = request.args.get('code')
    user_settings = user.get_addon('googledrive')

    state = session.data.pop('googledrive_auth_state')
    if state != request.args.get('state'):
        raise HTTPError(http.BAD_REQUEST)

    if code is None:
        raise HTTPError(http.BAD_REQUEST)

    auth_client = GoogleAuthClient()
    token = auth_client.finish(code)
    info = auth_client.userinfo(token['access_token'])

    # Attempt to attach an existing oauth settings model
    oauth_settings = GoogleDriveOAuthSettings.load(info['sub'])
    # Create a new oauth settings model
    if not oauth_settings:
        oauth_settings = GoogleDriveOAuthSettings()
        oauth_settings.user_id = info['sub']
        oauth_settings.save()
    user_settings.oauth_settings = oauth_settings

    user_settings.username = info['name']
    user_settings.access_token = token['access_token']
    user_settings.refresh_token = token['refresh_token']
    user_settings.expires_at = datetime.utcfromtimestamp(token['expires_at'])
    user_settings.save()

    flash('Successfully authorized Google Drive', 'success')
    if node:
        if node.has_addon('googledrive'):
            node_addon = node.get_addon('googledrive')
            node_addon.set_user_auth(user_settings)
            node_addon.save()
        return redirect(node.web_url_for('node_setting'))
    return redirect(web_url_for('user_addons'))
Пример #6
0
    def revoke_access_token(self):
        # if there is only one osf user linked to this google drive user oauth, revoke the token,
        # otherwise, disconnect the osf user from the googledriveoauthsettings
        if len(self.googledriveusersettings__accessed) <= 1:
            client = GoogleAuthClient()
            try:
                client.revoke(self.access_token)
            except:
                # no need to fail, revoke is opportunistic
                pass

            # remove the object as its the last instance.
            GoogleDriveOAuthSettings.remove_one(self)
Пример #7
0
    def revoke_access_token(self):
        # if there is only one osf user linked to this google drive user oauth, revoke the token,
        # otherwise, disconnect the osf user from the googledriveoauthsettings
        if len(self.googledriveusersettings__accessed) <= 1:
            client = GoogleAuthClient()
            try:
                client.revoke(self.access_token)
            except:
                # no need to fail, revoke is opportunistic
                pass

            # remove the object as its the last instance.
            GoogleDriveOAuthSettings.remove_one(self)
Пример #8
0
class GoogleDriveProvider(ExternalProvider):
    name = 'Google Drive'
    short_name = 'googledrive'

    client_id = drive_settings.CLIENT_ID
    client_secret = drive_settings.CLIENT_SECRET

    auth_url_base = '{}{}'.format(
        drive_settings.OAUTH_BASE_URL,
        'auth?access_type=offline&approval_prompt=force')
    callback_url = '{}{}'.format(drive_settings.API_BASE_URL,
                                 'oauth2/v3/token')
    auto_refresh_url = callback_url
    refresh_time = drive_settings.REFRESH_TIME

    default_scopes = drive_settings.OAUTH_SCOPE
    _auth_client = GoogleAuthClient()
    _drive_client = GoogleDriveClient()

    def handle_callback(self, response):
        client = self._auth_client
        info = client.userinfo(response['access_token'])
        return {
            'provider_id': info['sub'],
            'display_name': info['name'],
            'profile_url': info.get('profile', None)
        }

    def fetch_access_token(self, force_refresh=False):
        self.refresh_oauth_key(force=force_refresh)
        return self.account.oauth_key
Пример #9
0
class GoogleDriveProvider(ExternalProvider):
    name = 'Google Drive'
    short_name = 'googledrive'

    client_id = drive_settings.CLIENT_ID
    client_secret = drive_settings.CLIENT_SECRET

    auth_url_base = '{}{}'.format(
        drive_settings.OAUTH_BASE_URL,
        'auth?access_type=offline&approval_prompt=force')
    callback_url = '{}{}'.format(drive_settings.API_BASE_URL,
                                 'oauth2/v3/token')

    default_scopes = drive_settings.OAUTH_SCOPE
    _auth_client = GoogleAuthClient()
    _drive_client = GoogleDriveClient()

    def handle_callback(self, response):
        client = self._auth_client
        info = client.userinfo(response['access_token'])
        return {
            'provider_id': info['sub'],
            'display_name': info['name'],
            'profile_url': info.get('profile', None)
        }

    def _refresh_token(self, access_token, refresh_token):
        """ Handles the actual request to refresh tokens

        :param str access_token: Access token (oauth key) associated with this account
        :param str refresh_token: Refresh token used to request a new access token
        :return dict token: New set of tokens
        """
        client = self._auth_client
        if refresh_token:
            token = client.refresh(access_token, refresh_token)
            return token
        else:
            return False

    def fetch_access_token(self, force_refresh=False):
        self.refresh_access_token(force=force_refresh)
        return self.account.oauth_key

    def refresh_access_token(self, force=False):
        """ If the token has expired or will soon, handles refreshing and the storage of new tokens

        :param bool force: Indicates whether or not to force the refreshing process, for the purpose of ensuring that authorization has not been unexpectedly removed.
        """
        if self._needs_refresh() or force:
            token = self._refresh_token(self.account.oauth_key,
                                        self.account.refresh_token)
            self.account.oauth_key = token['access_token']
            self.account.refresh_token = token['refresh_token']
            self.account.expires_at = datetime.utcfromtimestamp(
                token['expires_at'])
            self.account.save()

    def _needs_refresh(self):
        if self.account.expires_at is None:
            return False
        return (self.account.expires_at - datetime.utcnow()
                ).total_seconds() < drive_settings.REFRESH_TIME