Example #1
0
    def get(self, provider=None):
        """
        Handle login initiation via a known OAuth 2 provider.
        """
        if settings.DEBUG and provider == "dummy":
            # Handle test dev login
            auth_id = 'dummy:test'
            UserPrefs.create_or_update(
                auth_id, {
                    'id':
                    '1234',
                    'name':
                    'Test User',
                    'email':
                    '*****@*****.**',
                    'avatar':
                    'http://www.gravatar.com/avatar/55502f40dc8b7c769880b10874abc9d0?s={0}&d=identicon'
                }, {})

            # Update session
            self.session['auth_id'] = auth_id

            return self.redirect(self.session.pop('next', '/'))

        auth_url = AUTH_URLS[provider][0]

        key = getattr(settings, provider.upper() + '_OAUTH_KEY')
        scope = getattr(settings, provider.upper() + '_OAUTH_SCOPE')

        # Generate a random state parameter to prevent CSRF attacks
        # This is both stored in the session and sent to the authorizing
        # server, relayed back and then checked to make sure it matches
        # up. If not, then the request likely did not originate from
        # this site and it can be ignored.
        csrf_state = hashlib.md5(uuid.uuid4().hex).hexdigest()

        self.session['login_csrf'] = csrf_state

        params = {
            'response_type': 'code',
            'client_id': key,
            'redirect_uri': self.callback_url(provider),
            'state': csrf_state
        }

        if scope:
            params.update(scope=scope)

        target_url = auth_url.format(urlencode(params))
        logging.info('Redirecting user to %s', target_url)

        self.redirect(target_url)
Example #2
0
    def get(self, provider=None):
        """
        Handle login initiation via a known OAuth 2 provider.
        """
        if settings.DEBUG and provider == "dummy":
            # Handle test dev login
            auth_id = 'dummy:test'
            UserPrefs.create_or_update(auth_id, {
                'id': '1234',
                'name': 'Test User',
                'email': '*****@*****.**',
                'avatar': 'http://www.gravatar.com/avatar/55502f40dc8b7c769880b10874abc9d0?s={0}&d=identicon'
            }, {})

            # Update session
            self.session['auth_id'] = auth_id

            return self.redirect(self.session.pop('next', '/'))

        auth_url = AUTH_URLS[provider][0]

        key = getattr(settings, provider.upper() + '_OAUTH_KEY')
        scope = getattr(settings, provider.upper() + '_OAUTH_SCOPE')

        # Generate a random state parameter to prevent CSRF attacks
        # This is both stored in the session and sent to the authorizing
        # server, relayed back and then checked to make sure it matches
        # up. If not, then the request likely did not originate from
        # this site and it can be ignored.
        csrf_state = hashlib.md5(uuid.uuid4().hex).hexdigest()

        self.session['login_csrf'] = csrf_state

        params = {
            'response_type': 'code',
            'client_id': key,
            'redirect_uri': self.callback_url(provider),
            'state': csrf_state
        }

        if scope:
            params.update(scope=scope)

        target_url = auth_url.format(urlencode(params))
        logging.info('Redirecting user to %s', target_url)

        self.redirect(target_url)
Example #3
0
    def get(self, provider):
        # Did we get an error?
        error = self.request.get('error')
        if error:
            raise AuthProviderResponseError(error, provider)

        # At this point the user is successfully logged in, but we need to
        # get an access token in order to call the API which gets user
        # information like id, name, avatar, email, etc. Then we need
        # to actually call that API, and use the response to create a
        # user object within our data store.

        # Get the access code so we can exchange it for a token
        code = self.request.get('code')

        # Get the CSRF state
        state = self.request.get('state')

        if self.session['login_csrf'] != state:
            logging.warning("Login aborted due to possible CSRF!")
            return self.abort()

        # Get the access token using the access code
        key = getattr(settings, provider.upper() + '_OAUTH_KEY')
        secret = getattr(settings, provider.upper() + '_OAUTH_SECRET')

        payload = {
            'code': code,
            'client_id': key,
            'client_secret': secret,
            'redirect_uri': self.callback_url(provider),
            'grant_type': 'authorization_code'
        }

        resp = urlfetch.fetch(
            url=AUTH_URLS[provider][1],
            payload=urlencode(payload),
            method=urlfetch.POST,
            headers={'Content-Type': 'application/x-www-form-urlencoded'}
        )

        if provider in ['google', 'windows_live']:
            auth_info = json.loads(resp.content)
        elif provider in ['facebook']:
            auth_info = dict(urlparse.parse_qsl(resp.content))
        else:
            raise NotImplementedError('Not sure how to parse access token response for ' + provider)

        logging.info(str(auth_info))

        # Use access token to make an API call to get user info
        user_info = getattr(self, '_' + provider + '_user_info')(auth_info)

        # Create or update a user object in the data store
        auth_id = provider + ":" + str(user_info['id'])

        UserPrefs.create_or_update(auth_id, user_info, auth_info)

        # Update session
        self.session['auth_id'] = auth_id

        self.redirect(self.session.pop('next', '/dashboard'))
Example #4
0
    def get(self, provider):
        # Did we get an error?
        error = self.request.get('error')
        if error:
            raise AuthProviderResponseError(error, provider)

        # At this point the user is successfully logged in, but we need to
        # get an access token in order to call the API which gets user
        # information like id, name, avatar, email, etc. Then we need
        # to actually call that API, and use the response to create a
        # user object within our data store.

        # Get the access code so we can exchange it for a token
        code = self.request.get('code')

        # Get the CSRF state
        state = self.request.get('state')

        if self.session['login_csrf'] != state:
            logging.warning("Login aborted due to possible CSRF!")
            return self.abort()

        # Get the access token using the access code
        key = getattr(settings, provider.upper() + '_OAUTH_KEY')
        secret = getattr(settings, provider.upper() + '_OAUTH_SECRET')

        payload = {
            'code': code,
            'client_id': key,
            'client_secret': secret,
            'redirect_uri': self.callback_url(provider),
            'grant_type': 'authorization_code'
        }

        resp = urlfetch.fetch(
            url=AUTH_URLS[provider][1],
            payload=urlencode(payload),
            method=urlfetch.POST,
            headers={'Content-Type': 'application/x-www-form-urlencoded'})

        if provider in ['google', 'windows_live']:
            auth_info = json.loads(resp.content)
        elif provider in ['facebook']:
            auth_info = dict(urlparse.parse_qsl(resp.content))
        else:
            raise NotImplementedError(
                'Not sure how to parse access token response for ' + provider)

        logging.info(str(auth_info))

        # Use access token to make an API call to get user info
        user_info = getattr(self, '_' + provider + '_user_info')(auth_info)

        # Create or update a user object in the data store
        auth_id = provider + ":" + str(user_info['id'])

        UserPrefs.create_or_update(auth_id, user_info, auth_info)

        # Update session
        self.session['auth_id'] = auth_id

        self.redirect(self.session.pop('next', '/dashboard'))