Ejemplo n.º 1
0
def twitter_process(request):
    """Process the Twitter redirect"""
    if 'denied' in request.GET:
        return AuthenticationDenied("User denied authentication")

    settings = request.registry.settings
    request_token = oauth.Token.from_string(request.session['token'])
    verifier = request.GET.get('oauth_verifier')
    if not verifier:
        raise ThirdPartyFailure("Oauth verifier not returned")
    request_token.set_verifier(verifier)

    # Create the consumer and client, make the request
    consumer = oauth.Consumer(settings['velruse.twitter.consumer_key'],
                              settings['velruse.twitter.consumer_secret'])

    client = oauth.Client(consumer, request_token)
    resp, content = client.request(ACCESS_URL, "POST")
    if resp['status'] != '200':
        raise ThirdPartyFailure("Status %s: %s" % (resp['status'], content))
    access_token = dict(parse_qs(content))

    # Setup the normalized contact info
    profile = {}
    profile['accounts'] = [{
        'domain': 'twitter.com',
        'userid': access_token['user_id'][0]
    }]
    profile['displayName'] = access_token['screen_name'][0]

    cred = {
        'oauthAccessToken': access_token['oauth_token'][0],
        'oauthAccessTokenSecret': access_token['oauth_token_secret'][0]
    }
    return TwitterAuthenticationComplete(profile=profile, credentials=cred)
Ejemplo n.º 2
0
def facebook_process(request):
    """Process the facebook redirect"""
    if request.GET.get('state') != request.session.get('state'):
        raise CSRFError(
            "CSRF Validation check failed. Request state %s is "
            "not the same as session state %s" %
            (request.GET.get('state'), request.session.get('state')))
    config = request.registry.settings
    code = request.GET.get('code')
    if not code:
        reason = request.GET.get('error_reason', 'No reason provided.')
        return AuthenticationDenied(reason)

    # Now retrieve the access token with the code
    access_url = flat_url('https://graph.facebook.com/oauth/access_token',
                          client_id=config['velruse.facebook.app_id'],
                          client_secret=config['velruse.facebook.app_secret'],
                          redirect_uri=request.route_url('facebook_process'),
                          code=code)
    r = requests.get(access_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))
    access_token = parse_qs(r.content)['access_token'][0]

    # Retrieve profile data
    graph_url = flat_url('https://graph.facebook.com/me',
                         access_token=access_token)
    r = requests.get(graph_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))
    fb_profile = loads(r.content)
    profile = extract_fb_data(fb_profile)

    cred = {'oauthAccessToken': access_token}
    return FacebookAuthenticationComplete(profile=profile, credentials=cred)
Ejemplo n.º 3
0
    def callback(self, request):
        """Process the weibo redirect"""
        sess_state = request.session.get('state')
        req_state = request.GET.get('state')
        if not sess_state or sess_state != req_state:
            raise CSRFError(
                'CSRF Validation check failed. Request state {req_state} is not '
                'the same as session state {sess_state}'.format(
                    req_state=req_state, sess_state=sess_state))
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error_reason', 'No reason provided.')
            return AuthenticationDenied(reason,
                                        provider_name=self.name,
                                        provider_type=self.type)

        # Now retrieve the access token with the code
        r = requests.post(
            'https://api.weibo.com/oauth2/access_token',
            dict(
                client_id=self.consumer_key,
                client_secret=self.consumer_secret,
                redirect_uri=request.route_url(self.callback_route),
                grant_type='authorization_code',
                code=code,
            ),
        )
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        data = loads(r.content)
        access_token = data['access_token']
        uid = data['uid']

        # Retrieve profile data
        graph_url = flat_url('https://api.weibo.com/2/users/show.json',
                             access_token=access_token,
                             uid=uid)
        r = requests.get(graph_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        data = loads(r.content)

        profile = {
            'accounts': [{
                'domain': 'weibo.com',
                'userid': data['id']
            }],
            'gender': data.get('gender'),
            'displayName': data['screen_name'],
            'preferredUsername': data['name'],
        }

        cred = {'oauthAccessToken': access_token}
        return WeiboAuthenticationComplete(profile=profile,
                                           credentials=cred,
                                           provider_name=self.name,
                                           provider_type=self.type)
Ejemplo n.º 4
0
    def callback(self, request):
        """Process the github redirect"""
        sess_state = request.session.get('state')
        req_state = request.GET.get('state')
        if not sess_state or sess_state != req_state:
            raise CSRFError(
                'CSRF Validation check failed. Request state {req_state} is not '
                'the same as session state {sess_state}'.format(
                    req_state=req_state, sess_state=sess_state))
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error', 'No reason provided.')
            return AuthenticationDenied(reason=reason,
                                        provider_name=self.name,
                                        provider_type=self.type)

        # Now retrieve the access token with the code
        access_url = flat_url(
            '%s://%s/login/oauth/access_token' % (self.protocol, self.domain),
            client_id=self.consumer_key,
            client_secret=self.consumer_secret,
            redirect_uri=request.route_url(self.callback_route),
            code=code)
        r = requests.get(access_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        access_token = parse_qs(r.content)['access_token'][0]

        # Retrieve profile data
        graph_url = flat_url('%s://api.%s/user' % (self.protocol, self.domain),
                             access_token=access_token)
        graph_headers = dict(Accept='application/vnd.github.v3+json')
        r = requests.get(graph_url, headers=graph_headers)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        data = loads(r.content)

        profile = {}
        profile['accounts'] = [{
            'domain': self.domain,
            'username': data['login'],
            'userid': data['id']
        }]

        profile['preferredUsername'] = data['login']
        profile['displayName'] = data.get('name', profile['preferredUsername'])

        # We don't add this to verifiedEmail because ppl can change email
        # addresses without verifying them
        if 'email' in data:
            profile['emails'] = [{'value': data['email']}]

        cred = {'oauthAccessToken': access_token}
        return GithubAuthenticationComplete(profile=profile,
                                            credentials=cred,
                                            provider_name=self.name,
                                            provider_type=self.type)
Ejemplo n.º 5
0
    def callback(self, request):
        """Process the LinkedIn redirect"""
        if 'denied' in request.GET:
            return AuthenticationDenied("User denied authentication",
                                        provider_name=self.name,
                                        provider_type=self.type)

        request_token = oauth.Token.from_string(request.session['token'])
        verifier = request.GET.get('oauth_verifier')
        if not verifier:
            raise ThirdPartyFailure("Oauth verifier not returned")
        request_token.set_verifier(verifier)

        # Create the consumer and client, make the request
        consumer = oauth.Consumer(self.consumer_key, self.consumer_secret)

        client = oauth.Client(consumer, request_token)
        resp, content = client.request(ACCESS_URL, "POST")
        if resp['status'] != '200':
            raise ThirdPartyFailure("Status %s: %s" %
                                    (resp['status'], content))
        access_token = dict(parse_qs(content))

        cred = {
            'oauthAccessToken': access_token['oauth_token'][0],
            'oauthAccessTokenSecret': access_token['oauth_token_secret'][0]
        }

        # Make a request with the data for more user info
        token = oauth.Token(key=cred['oauthAccessToken'],
                            secret=cred['oauthAccessTokenSecret'])
        client = oauth.Client(consumer, token)
        profile_url = 'http://api.linkedin.com/v1/people/~'
        profile_url += ':(first-name,last-name,id,date-of-birth,picture-url)'
        profile_url += '?format=json'
        resp, content = client.request(profile_url)

        if resp['status'] != '200':
            raise ThirdPartyFailure("Status %s: %s" %
                                    (resp['status'], content))
        data = loads(content)

        # Setup the normalized contact info
        profile = {}
        profile['displayName'] = data['firstName'] + data['lastName']
        profile['name'] = {
            'givenName': data['firstName'],
            'familyName': data['lastName'],
            'formatted': '%s %s' % (data['firstName'], data['lastName'])
        }
        profile['accounts'] = [{
            'domain': 'linkedin.com',
            'userid': data['id']
        }]
        return LinkedInAuthenticationComplete(profile=profile,
                                              credentials=cred,
                                              provider_name=self.name,
                                              provider_type=self.type)
Ejemplo n.º 6
0
    def callback(self, request):
        """Process the taobao redirect"""
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error', 'No reason provided.')
            return AuthenticationDenied(reason)

        # Now retrieve the access token with the code
        r = requests.post(
            'https://oauth.taobao.com/token',
            dict(grant_type='authorization_code',
                 client_id=self.consumer_key,
                 client_secret=self.consumer_secret,
                 redirect_uri=request.route_url(self.callback_route),
                 code=code))
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        data = loads(r.content)
        access_token = data['access_token']

        # Retrieve profile data
        params = {
            'method': 'taobao.user.get',
            'timestamp': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()),
            'format': 'json',
            'app_key': self.consumer_key,
            'v': '2.0',
            'sign_method': 'md5',
            'fields': 'user_id,nick',
            'session': access_token
        }
        src = self.consumer_secret\
                + ''.join(["%s%s" % (k, v) for k, v in sorted(params.items())])\
                + self.consumer_secret
        params['sign'] = md5(src).hexdigest().upper()
        get_user_info_url = flat_url('http://gw.api.taobao.com/router/rest',
                                     **params)
        r = requests.get(get_user_info_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        data = loads(r.content)

        username = data['user_get_response']['user']['nick']
        userid = data['user_get_response']['user']['user_id']

        profile = {
            'accounts': [{
                'domain': 'taobao.com',
                'userid': userid
            }],
            'displayName': username,
            'preferredUsername': username,
        }

        cred = {'oauthAccessToken': access_token}
        return TaobaoAuthenticationComplete(profile=profile, credentials=cred)
Ejemplo n.º 7
0
    def callback(self, request):
        """Process the qq redirect"""
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error', 'No reason provided.')
            return AuthenticationDenied(reason,
                                        provider_name=self.name,
                                        provider_type=self.type)

        # Now retrieve the access token with the code
        access_url = flat_url('https://graph.qq.com/oauth2.0/token',
                              client_id=self.consumer_key,
                              client_secret=self.consumer_secret,
                              grant_type='authorization_code',
                              redirect_uri=request.route_url(
                                  self.callback_route),
                              code=code)
        r = requests.get(access_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        access_token = parse_qs(r.content)['access_token'][0]

        # Retrieve profile data
        graph_url = flat_url('https://graph.qq.com/oauth2.0/me',
                             access_token=access_token)
        r = requests.get(graph_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        data = loads(r.content[10:-3])
        openid = data.get('openid', '')

        user_info_url = flat_url('https://graph.qq.com/user/get_user_info',
                                 access_token=access_token,
                                 oauth_consumer_key=self.consumer_key,
                                 openid=openid)
        r = requests.get(user_info_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        data = loads(r.content)

        profile = {
            'accounts': [{
                'domain': 'qq.com',
                'userid': openid
            }],
            'displayName': data['nickname'],
            'preferredUsername': data['nickname'],
        }

        cred = {'oauthAccessToken': access_token}
        return QQAuthenticationComplete(profile=profile,
                                        credentials=cred,
                                        provider_name=self.name,
                                        provider_type=self.type)
Ejemplo n.º 8
0
    def callback(self, request):
        """Process the VK redirect"""
        sess_state = request.session.get('state')
        req_state = request.GET.get('state')
        if not sess_state or sess_state != req_state:
            raise CSRFError(
                'CSRF Validation check failed. Request state {req_state} is not '
                'the same as session state {sess_state}'.format(
                    req_state=req_state, sess_state=sess_state))
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error_description',
                                     'No reason provided.')
            return AuthenticationDenied(reason=reason,
                                        provider_name=self.name,
                                        provider_type=self.type)
        # Now retrieve the access token with the code
        access_url = flat_url(PROVIDER_ACCESS_TOKEN_URL,
                              client_id=self.consumer_key,
                              client_secret=self.consumer_secret,
                              redirect_uri=request.route_url(
                                  self.callback_route),
                              code=code)
        r = requests.get(access_url)
        if r.status_code != 200:
            raise ThirdPartyFailure('Status {status}: {content}'.format(
                status=r.status_code, content=r.content))
        data = json.loads(r.content)
        access_token = data['access_token']

        # Retrieve profile data
        graph_url = flat_url(
            PROVIDER_USER_PROFILE_URL,
            access_token=access_token,
            uids=data['user_id'],
            fields=
            ('first_name,last_name,nickname,domain,sex,bdate,city,country,timezone,'
             'photo,photo_medium,photo_big,photo_rec,has_mobile,mobile_phone,home_phone,'
             'rate,contacts,education'))
        r = requests.get(graph_url)
        if r.status_code != 200:
            raise ThirdPartyFailure('Status {status}: {content}'.format(
                status=r.status_code, content=r.content))
        vk_profile = json.loads(r.content)['response'][0]
        vk_profile['uid'] = data['user_id']
        profile = extract_normalize_vk_data(vk_profile)
        cred = {'oauthAccessToken': access_token}
        return VKAuthenticationComplete(profile=profile,
                                        credentials=cred,
                                        provider_name=self.name,
                                        provider_type=self.type)
Ejemplo n.º 9
0
    def callback(self, request):
        """Process the bitbucket redirect"""
        if 'denied' in request.GET:
            return AuthenticationDenied("User denied authentication",
                                        provider_name=self.name,
                                        provider_type=self.type)

        request_token = oauth.Token.from_string(request.session['token'])
        verifier = request.GET.get('oauth_verifier')
        if not verifier:
            raise ThirdPartyFailure("No oauth_verifier returned")
        request_token.set_verifier(verifier)

        # Create the consumer and client, make the request
        consumer = oauth.Consumer(self.consumer_key, self.consumer_secret)

        client = oauth.Client(consumer, request_token)
        resp, content = client.request(ACCESS_URL, "POST")
        if resp['status'] != '200':
            raise ThirdPartyFailure("Status %s: %s" % (resp['status'], content))
        access_token = dict(parse_qs(content))

        cred = {'oauthAccessToken': access_token['oauth_token'][0],
                'oauthAccessTokenSecret': access_token['oauth_token_secret'][0]}

        # Make a request with the data for more user info
        token = oauth.Token(key=cred['oauthAccessToken'],
                            secret=cred['oauthAccessTokenSecret'])

        client = oauth.Client(consumer, token)
        resp, content = client.request(USER_URL)
        user_data = json.loads(content)
        data = user_data['user']
        # Setup the normalized contact info
        profile = {}
        profile['accounts'] = [{
            'domain':'bitbucket.com',
            'username':data['username']
        }]
        profile['preferredUsername'] = data['username']
        profile['name'] = {
            'formatted': '%s %s' % (data['first_name'], data['last_name']),
            'givenName': data['first_name'],
            'familyName': data['last_name'],
            }
        profile['displayName'] = profile['name']['formatted']
        return BitbucketAuthenticationComplete(profile=profile,
                                               credentials=cred,
                                               provider_name=self.name,
                                               provider_type=self.type)
Ejemplo n.º 10
0
    def process(self, request):
        """Handle incoming redirect from OpenID Provider"""
        log_debug = self.log_debug
        if log_debug:
            log.debug('Handling processing of response from server')

        openid_session = request.session.get('openid_session', None)
        del request.session['openid_session']
        if not openid_session:
            raise ThirdPartyFailure("No OpenID Session has begun.")

        # Setup the consumer and parse the information coming back
        oidconsumer = consumer.Consumer(openid_session, self.openid_store)
        return_to = request.route_url(self.process_url)
        info = oidconsumer.complete(request.params, return_to)

        if info.status in [consumer.FAILURE, consumer.CANCEL]:
            raise AuthenticationDenied("OpenID failure")
        elif info.status == consumer.SUCCESS:
            openid_identity = info.identity_url
            if info.endpoint.canonicalID:
                # If it's an i-name, use the canonicalID as its secure even if
                # the old one is compromised
                openid_identity = info.endpoint.canonicalID

            user_data = extract_openid_data(
                identifier=openid_identity,
                sreg_resp=sreg.SRegResponse.fromSuccessResponse(info),
                ax_resp=ax.FetchResponse.fromSuccessResponse(info),
            )

            user_data['end_point'] = get_came_from(request)
            # Did we get any OAuth info?
            oauth = info.extensionResponse(
                'http://specs.openid.net/extensions/oauth/1.0', False)
            cred = {}
            if oauth and 'request_token' in oauth:
                access_token = self._get_access_token(oauth['request_token'])
                if access_token:
                    cred.update(access_token)

                # See if we need to update our profile data with an OAuth call
                self._update_profile_data(request, user_data, cred)

            # Delete the temporary token data used for the OpenID auth
            return self.AuthenticationComplete(profile=user_data,
                                               credentials=cred)
        else:
            raise ThirdPartyFailure("OpenID failed.")
Ejemplo n.º 11
0
def weibo_process(request):
    """Process the weibo redirect"""
    if request.GET.get('state') != request.session.get('state'):
        raise CSRFError(
            "CSRF Validation check failed. Request state %s is "
            "not the same as session state %s" %
            (request.GET.get('state'), request.session.get('state')))
    config = request.registry.settings
    code = request.GET.get('code')
    if not code:
        reason = request.GET.get('error_reason', 'No reason provided.')
        return AuthenticationDenied(reason)

    # Now retrieve the access token with the code
    r = requests.post(
        'https://api.weibo.com/oauth2/access_token',
        dict(client_id=config['velruse.weibo.app_id'],
             client_secret=config['velruse.weibo.app_secret'],
             redirect_uri=request.route_url('weibo_process'),
             grant_type='authorization_code',
             code=code))
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))
    data = loads(r.content)
    access_token = data['access_token']
    uid = data['uid']

    # Retrieve profile data
    graph_url = flat_url('https://api.weibo.com/2/users/show.json',
                         access_token=access_token,
                         uid=uid)
    r = requests.get(graph_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))
    data = loads(r.content)

    profile = {
        'accounts': [{
            'domain': 'weibo.com',
            'userid': data['id']
        }],
        'gender': data.get('gender'),
        'displayName': data['screen_name'],
        'preferredUsername': data['name'],
    }

    cred = {'oauthAccessToken': access_token}
    return WeiboAuthenticationComplete(profile=profile, credentials=cred)
Ejemplo n.º 12
0
    def login(self, request):
        """Initiate a Twitter login"""
        # Create the consumer and client, make the request
        consumer = oauth.Consumer(self.consumer_key, self.consumer_secret)
        sigmethod = oauth.SignatureMethod_HMAC_SHA1()
        params = {'oauth_callback': request.route_url(self.callback_route)}

        # We go through some shennanigans here to specify a callback url
        oauth_request = oauth.Request.from_consumer_and_token(
            consumer, http_url=REQUEST_URL, parameters=params)
        oauth_request.sign_request(sigmethod, consumer, None)
        r = requests.get(REQUEST_URL, headers=oauth_request.to_header())

        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        request_token = oauth.Token.from_string(r.content)

        request.session['token'] = r.content

        # Send the user to twitter now for authorization
        req_url = 'https://api.twitter.com/oauth/authenticate'
        oauth_request = oauth.Request.from_token_and_callback(
            token=request_token, http_url=req_url)
        return HTTPFound(location=oauth_request.to_url())
Ejemplo n.º 13
0
def linkedin_login(request):
    """Initiate a LinkedIn login"""
    config = request.registry.settings

    # Create the consumer and client, make the request
    consumer = oauth.Consumer(config['velruse.linkedin.consumer_key'],
                              config['velruse.linkedin.consumer_secret'])
    sigmethod = oauth.SignatureMethod_HMAC_SHA1()
    params = {'oauth_callback': request.route_url('linkedin_process')}

    # We go through some shennanigans here to specify a callback url
    oauth_request = oauth.Request.from_consumer_and_token(consumer,
        http_url=REQUEST_URL, parameters=params)
    oauth_request.sign_request(sigmethod, consumer, None)
    r = requests.get(REQUEST_URL, headers=oauth_request.to_header())

    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))
    request_token = oauth.Token.from_string(r.content)

    request.session['token'] = r.content

    # Send the user to linkedin now for authorization
    if asbool(config.get('velruse.linkedin.authorize')):
        req_url = 'https://api.linkedin.com/uas/oauth/authorize'
    else:
        req_url = 'https://api.linkedin.com/uas/oauth/authenticate'
    oauth_request = oauth.Request.from_token_and_callback(
        token=request_token, http_url=req_url)
    return HTTPFound(location=oauth_request.to_url())
Ejemplo n.º 14
0
    def callback(self, request):
        """Process the google redirect"""
        sess_state = request.session.get('state')
        req_state = request.GET.get('state')
        if not sess_state or sess_state != req_state:
            raise CSRFError(
                'CSRF Validation check failed. Request state {req_state} is not '
                'the same as session state {sess_state}'.format(
                    req_state=req_state,
                    sess_state=sess_state
                )
            )
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error', 'No reason provided.')
            return AuthenticationDenied(reason=reason,
                                        provider_name=self.name,
                                        provider_type=self.type)

        # Now retrieve the access token with the code
        r = requests.post('%s://%s/o/oauth2/token' % (self.protocol, self.domain),
                          data={
                              'client_id': self.consumer_key,
                              'client_secret': self.consumer_secret,
                              'redirect_uri': request.route_url(self.callback_route),
                              'code': code,
                              'grant_type': 'authorization_code'
                          })
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" % (
                r.status_code, r.content))
        token_data = loads(r.content)
        access_token = token_data['access_token']
        refresh_token = token_data.get('refresh_token')

        # Retrieve profile data if scopes allow
        profile = {}
        user_url = flat_url(
                '%s://www.googleapis.com/oauth2/v1/userinfo' % self.protocol,
                access_token=access_token)
        r = requests.get(user_url)

        if r.status_code == 200:
            data = loads(r.content)
            profile['accounts'] = [{
                'domain': self.domain,
                'username': data['email'],
                'userid': data['id']
            }]
            profile['displayName'] = data['name']
            profile['preferredUsername'] = data['email']
            profile['verifiedEmail'] = data['email']
            profile['emails'] = [{'value': data['email']}]

        cred = {'oauthAccessToken': access_token,
                'oauthRefreshToken': refresh_token}
        return Google2AuthenticationComplete(profile=profile,
                                             credentials=cred,
                                             provider_name=self.name,
                                             provider_type=self.type)
Ejemplo n.º 15
0
def renren_process(request):
    """Process the renren redirect"""
    config = request.registry.settings
    code = request.GET.get('code')
    if not code:
        reason = request.GET.get('error', 'No reason provided.')
        return AuthenticationDenied(reason)

    access_url = flat_url('https://graph.renren.com/oauth/token',
                          client_id=config['velruse.renren.app_id'],
                          client_secret=config['velruse.renren.app_secret'],
                          grant_type='authorization_code',
                          redirect_uri=request.route_url('renren_process'),
                          code=code)

    r = requests.get(access_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))
    data = loads(r.content)
    access_token = data['access_token']
    profile = {
        'accounts': [{
            'domain': 'renren.com',
            'userid': data['user']['id']
        }],
        'displayName': data['user']['name'],
        'preferredUsername': data['user']['name'],
    }

    cred = {'oauthAccessToken': access_token}

    return RenrenAuthenticationComplete(profile=profile, credentials=cred)
Ejemplo n.º 16
0
def bitbucket_login(request):
    """Initiate a bitbucket login"""
    config = request.registry.settings

    # Create the consumer and client, make the request
    consumer = oauth.Consumer(config['velruse.bitbucket.consumer_key'],
                              config['velruse.bitbucket.consumer_secret'])
    params = {'oauth_callback': request.route_url('bitbucket_process')}

    # We go through some shennanigans here to specify a callback url
    oauth_request = oauth.Request.from_consumer_and_token(consumer,
                                                          http_url=REQUEST_URL,
                                                          parameters=params)
    oauth_request.sign_request(SIGMETHOD, consumer, None)
    r = requests.get(REQUEST_URL, headers=oauth_request.to_header())

    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))
    request_token = oauth.Token.from_string(r.content)

    request.session['token'] = r.content

    # Send the user to bitbucket now for authorization
    # there doesnt seem to be separate url for this on BB
    if asbool(config.get('velruse.bitbucket.authorize')):
        req_url = 'https://bitbucket.org/api/1.0/oauth/authenticate/'
    else:
        req_url = 'https://bitbucket.org/api/1.0/oauth/authenticate/'
    oauth_request = oauth.Request.from_token_and_callback(token=request_token,
                                                          http_url=req_url)
    return HTTPFound(location=oauth_request.to_url())
Ejemplo n.º 17
0
    def callback(self, request):
        """Process the github redirect"""
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error', 'No reason provided.')
            return AuthenticationDenied(reason)

        # Now retrieve the access token with the code
        access_url = flat_url(
            'https://github.com/login/oauth/access_token',
            client_id=self.consumer_key,
            client_secret=self.consumer_secret,
            redirect_uri=request.route_url(self.callback_route),
            code=code)
        r = requests.get(access_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" % (
                r.status_code, r.content))
        access_token = parse_qs(r.content)['access_token'][0]

        # Retrieve profile data
        graph_url = flat_url('https://github.com/api/v2/json/user/show',
                             access_token=access_token)
        r = requests.get(graph_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" % (
                r.status_code, r.content))
        data = loads(r.content)['user']

        profile = {}
        profile['accounts'] = [{
            'domain':'github.com',
            'username':data['login'],
            'userid':data['id']
        }]
        profile['displayName'] = data['name']
        profile['preferredUsername'] = data['login']

        # We don't add this to verifiedEmail because ppl can change email
        # addresses without verifying them
        if 'email' in data:
            profile['emails'] = [{'value':data['email']}]

        cred = {'oauthAccessToken': access_token}
        return GithubAuthenticationComplete(profile=profile,
                                            credentials=cred)
Ejemplo n.º 18
0
    def login(self, request):
        log_debug = self.log_debug
        if log_debug:
            log.debug('Handling OpenID login')

        # Load default parameters that all Auth Responders take
        openid_url = request.params.get('openid_identifier')

        # Let inherited consumers alter the openid identifier if desired
        openid_url = self._lookup_identifier(request, openid_url)

        if not openid_url:
            log.error('Velruse: no openid_url')
            raise MissingParameter('No openid_identifier was found')

        openid_session = {}
        oidconsumer = consumer.Consumer(openid_session, self.openid_store)

        try:
            if log_debug:
                log.debug('About to try OpenID begin')
            authrequest = oidconsumer.begin(openid_url)
        except consumer.DiscoveryFailure:
            if log_debug:
                log.debug('OpenID begin DiscoveryFailure')
            raise

        if authrequest is None:
            if log_debug:
                log.debug('OpenID begin returned empty')
            raise ThirdPartyFailure("OpenID begin returned nothing")

        if log_debug:
            log.debug('Updating authrequest')

        # Update the authrequest
        self._update_authrequest(request, authrequest)

        return_to = request.route_url(self.process_url)

        # OpenID 2.0 lets Providers request POST instead of redirect, this
        # checks for such a request.
        if authrequest.shouldSendRedirect():
            if log_debug:
                log.debug('About to initiate OpenID redirect')
            redirect_url = authrequest.redirectURL(realm=self.realm,
                                                   return_to=return_to,
                                                   immediate=False)
            request.session['openid_session'] = openid_session
            return HTTPFound(location=redirect_url)
        else:
            if log_debug:
                log.debug('About to initiate OpenID POST')
            html = authrequest.htmlMarkup(
                realm=self.realm, return_to=return_to, immediate=False)
            request.session['openid_session'] = openid_session
            return Response(body=html)
Ejemplo n.º 19
0
    def callback(self, request):
        """Process the Yandex redirect"""
        sess_state = request.session.get('state')
        req_state = request.GET.get('state')
        if not sess_state or sess_state != req_state:
            raise CSRFError(
                'CSRF Validation check failed. Request state {req_state} is not '
                'the same as session state {sess_state}'.format(
                    req_state=req_state, sess_state=sess_state))
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error', 'No reason provided.')
            return AuthenticationDenied(reason=reason,
                                        provider_name=self.name,
                                        provider_type=self.type)
        # Now retrieve the access token with the code
        token_params = {
            'grant_type': 'authorization_code',
            'code': code,
            'client_id': self.consumer_key,
            'client_secret': self.consumer_secret,
        }
        r = requests.post(PROVIDER_ACCESS_TOKEN_URL, token_params)
        if r.status_code != 200:
            raise ThirdPartyFailure('Status {status}: {content}'.format(
                status=r.status_code, content=r.content))
        data = json.loads(r.content)
        access_token = data['access_token']

        # Retrieve profile data
        profile_url = flat_url(PROVIDER_USER_PROFILE_URL,
                               format='json',
                               oauth_token=access_token)
        r = requests.get(profile_url)
        if r.status_code != 200:
            raise ThirdPartyFailure('Status {status}: {content}'.format(
                status=r.status_code, content=r.content))
        profile = json.loads(r.content)
        profile = extract_normalize_yandex_data(profile)
        cred = {'oauthAccessToken': access_token}
        return YandexAuthenticationComplete(profile=profile,
                                            credentials=cred,
                                            provider_name=self.name,
                                            provider_type=self.type)
Ejemplo n.º 20
0
    def callback(self, request):
        """Process the facebook redirect"""
        sess_state = request.session.get('state')
        req_state = request.GET.get('state')
        if not sess_state or sess_state != req_state:
            raise CSRFError(
                'CSRF Validation check failed. Request state {req_state} is not '
                'the same as session state {sess_state}'.format(
                    req_state=req_state, sess_state=sess_state))
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error_reason', 'No reason provided.')
            return AuthenticationDenied(reason=reason,
                                        provider_name=self.name,
                                        provider_type=self.type)

        # Now retrieve the access token with the code
        access_url = flat_url('https://graph.facebook.com/oauth/access_token',
                              client_id=self.consumer_key,
                              client_secret=self.consumer_secret,
                              redirect_uri=request.route_url(
                                  self.callback_route),
                              code=code)
        r = requests.get(access_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        access_token = parse_qs(r.content)['access_token'][0]

        # Retrieve profile data
        graph_url = flat_url('https://graph.facebook.com/me',
                             access_token=access_token)
        r = requests.get(graph_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        fb_profile = loads(r.content)
        profile = extract_fb_data(fb_profile)

        cred = {'oauthAccessToken': access_token}
        return FacebookAuthenticationComplete(profile=profile,
                                              credentials=cred,
                                              provider_name=self.name,
                                              provider_type=self.type)
Ejemplo n.º 21
0
    def callback(self, request):
        """Process the Live redirect"""
        if 'error' in request.GET:
            raise ThirdPartyFailure(
                request.GET.get('error_description', 'No reason provided.'))
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error_reason', 'No reason provided.')
            return AuthenticationDenied(reason,
                                        provider_name=self.name,
                                        provider_type=self.type)

        # Now retrieve the access token with the code
        access_url = flat_url('https://oauth.live.com/token',
                              client_id=self.consumer_key,
                              client_secret=self.consumer_secret,
                              redirect_uri=request.route_url(
                                  self.callback_route),
                              grant_type="authorization_code",
                              code=code)
        r = requests.get(access_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        data = loads(r.content)
        access_token = data['access_token']

        # Retrieve profile data
        graph_url = flat_url('https://apis.live.net/v5.0/me',
                             access_token=access_token)
        r = requests.get(graph_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        live_profile = loads(r.content)
        profile = extract_live_data(live_profile)

        cred = {'oauthAccessToken': access_token}
        if 'refresh_token' in data:
            cred['oauthRefreshToken'] = data['refresh_token']
        return LiveAuthenticationComplete(profile=profile,
                                          credentials=cred,
                                          provider_name=self.name,
                                          provider_type=self.type)
Ejemplo n.º 22
0
    def callback(self, request):
        """Process the douban redirect"""
        if 'denied' in request.GET:
            return AuthenticationDenied("User denied authentication",
                                        provider_name=self.name,
                                        provider_type=self.type)

        request_token = oauth.Token.from_string(request.session['token'])

        # Create the consumer and client, make the request
        consumer = oauth.Consumer(self.consumer_key, self.consumer_secret)
        client = oauth.Client(consumer, request_token)
        resp, content = client.request(ACCESS_URL)
        if resp['status'] != '200':
            raise ThirdPartyFailure("Status %s: %s" %
                                    (resp['status'], content))

        access_token = dict(parse_qs(content))
        cred = {
            'oauthAccessToken': access_token['oauth_token'][0],
            'oauthAccessTokenSecret': access_token['oauth_token_secret'][0]
        }

        douban_user_id = access_token['douban_user_id'][0]
        token = oauth.Token(key=cred['oauthAccessToken'],
                            secret=cred['oauthAccessTokenSecret'])

        client = oauth.Client(consumer, token)
        resp, content = client.request(USER_URL)

        user_data = json.loads(content)
        # Setup the normalized contact info
        profile = {
            'accounts': [{
                'domain': 'douban.com',
                'userid': douban_user_id
            }],
            'displayName': user_data['title']['$t'],
            'preferredUsername': user_data['title']['$t'],
        }
        return DoubanAuthenticationComplete(profile=profile,
                                            credentials=cred,
                                            provider_name=self.name,
                                            provider_type=self.type)
Ejemplo n.º 23
0
    def callback(self, request):
        """Process the alfresco redirect"""
        sess_state = request.session.get('state')
        req_state = request.GET.get('state')
        if not sess_state or sess_state != req_state:
            raise CSRFError(
                'CSRF Validation check failed. Request state {req_state} is not '
                'the same as session state {sess_state}'.format(
                    req_state=req_state, sess_state=sess_state))
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error', 'No reason provided.')
            return AuthenticationDenied(reason=reason,
                                        provider_name=self.name,
                                        provider_type=self.type)

        # Now retrieve the access token with the code
        access_url = flat_url('%s://%s/auth/oauth/versions/2/token' %
                              (self.protocol, self.domain))
        payload = {}
        payload['client_id'] = self.consumer_key,
        payload['client_secret'] = self.consumer_secret,
        payload['redirect_uri'] = request.route_url(self.callback_route),
        payload['code'] = code
        payload['grant_type'] = 'authorization_code'
        r = requests.post(access_url, data=payload)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))

        profile = {}
        profile['accounts'] = [{
            'domain': self.domain,
        }]

        cred = {
            'access_token': r.json()['access_token'],
            'refresh_token': r.json()['refresh_token']
        }

        return AlfrescoAuthenticationComplete(profile=profile,
                                              credentials=cred,
                                              provider_name=self.name,
                                              provider_type=self.type)
Ejemplo n.º 24
0
    def callback(self, request):
        """Process the renren redirect"""
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error', 'No reason provided.')
            return AuthenticationDenied(reason,
                                        provider_name=self.name,
                                        provider_type=self.type)

        access_url = flat_url('https://graph.renren.com/oauth/token',
                              client_id=self.consumer_key,
                              client_secret=self.consumer_secret,
                              grant_type='authorization_code',
                              redirect_uri=request.route_url(
                                  self.callback_route),
                              code=code)

        r = requests.get(access_url)
        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        data = loads(r.content)
        access_token = data['access_token']
        profile = {
            'accounts': [
                {
                    'domain': 'renren.com',
                    'userid': data['user']['id']
                },
            ],
            'displayName': data['user']['name'],
            'preferredUsername': data['user']['name'],
        }

        cred = {'oauthAccessToken': access_token}

        return RenrenAuthenticationComplete(profile=profile,
                                            credentials=cred,
                                            provider_name=self.name,
                                            provider_type=self.type)
Ejemplo n.º 25
0
def twitter_login(request):
    """Initiate a Twitter login"""
    settings = request.registry.settings

    # Create the consumer and client, make the request
    consumer = oauth.Consumer(settings['velruse.twitter.consumer_key'],
                              settings['velruse.twitter.consumer_secret'])
    came_from = get_came_from(request)
    redirect_uri = request.route_url('twitter_process')
    if came_from:
        qs = urlencode({'end_point': came_from})
        if not '?' in redirect_uri:
            redirect_uri += '?'
        redirect_uri += qs
    sigmethod = oauth.SignatureMethod_HMAC_SHA1()
    params = {'oauth_callback': redirect_uri}

    # We go through some shennanigans here to specify a callback url
    oauth_request = oauth.Request.from_consumer_and_token(consumer,
                                                          http_url=REQUEST_URL,
                                                          parameters=params)
    oauth_request.sign_request(sigmethod, consumer, None)
    r = requests.get(REQUEST_URL, headers=oauth_request.to_header())

    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))
    request_token = oauth.Token.from_string(r.content)

    request.session['token'] = r.content

    # Send the user to twitter now for authorization
    if asbool(settings.get('velruse.twitter.authorize')):
        req_url = 'https://api.twitter.com/oauth/authorize'
    else:
        req_url = 'https://api.twitter.com/oauth/authenticate'
    oauth_request = oauth.Request.from_token_and_callback(token=request_token,
                                                          http_url=req_url)
    return HTTPFound(location=oauth_request.to_url())
Ejemplo n.º 26
0
    def login(self, request):
        """Initiate a douban login"""
        consumer = oauth.Consumer(self.consumer_key, self.consumer_secret)

        oauth_request = oauth.Request.from_consumer_and_token(
            consumer, http_url=REQUEST_URL)
        oauth_request.sign_request(SIGMETHOD, consumer, None)
        r = requests.get(REQUEST_URL, headers=oauth_request.to_header())

        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" %
                                    (r.status_code, r.content))
        request_token = oauth.Token.from_string(r.content)

        request.session['token'] = r.content

        # Send the user to douban now for authorization
        req_url = 'http://www.douban.com/service/auth/authorize'
        oauth_request = oauth.Request.from_token_and_callback(
            token=request_token,
            callback=request.route_url(self.callback_route),
            http_url=req_url)
        return HTTPFound(location=oauth_request.to_url())
Ejemplo n.º 27
0
    def login(self, request):
        """Initiate a bitbucket login"""
        # Create the consumer and client, make the request
        consumer = oauth.Consumer(self.consumer_key, self.consumer_secret)
        params = {'oauth_callback': request.route_url(self.callback_route)}

        # We go through some shennanigans here to specify a callback url
        oauth_request = oauth.Request.from_consumer_and_token(consumer,
            http_url=REQUEST_URL, parameters=params)
        oauth_request.sign_request(SIGMETHOD, consumer, None)
        r = requests.get(REQUEST_URL, headers=oauth_request.to_header())

        if r.status_code != 200:
            raise ThirdPartyFailure("Status %s: %s" % (
                r.status_code, r.content))
        request_token = oauth.Token.from_string(r.content)

        request.session['token'] = r.content

        req_url = 'https://bitbucket.org/api/1.0/oauth/authenticate/'
        oauth_request = oauth.Request.from_token_and_callback(
            token=request_token, http_url=req_url)
        return HTTPFound(location=oauth_request.to_url())
Ejemplo n.º 28
0
    def callback(self, request):
        session_state = request.session.pop('velruse.state', None)
        request_state = request.GET.get('state')
        if not session_state or session_state != request_state:
            raise CSRFError()

        code = request.GET.get('code')
        if not code:
            return AuthenticationDenied(
                reason='unknown',  # TODO
                provider_name=self.name,
                provider_type=self.type)

        token_url = flat_url(
            'https://nid.naver.com/oauth2.0/token', **{
                'grant_type': 'authorization_code',
                'client_id': self.consumer_key,
                'client_secret': self.consumer_secret,
                'redirect_uri': request.route_url(self.callback_route),
                'code': code,
                'state': request_state,
            })
        r = requests.get(
            token_url,
            headers={
                'x-naver-client-id': self.consumer_key,
                'x-naver-client-secret': self.consumer_secret,
            },
        )

        if r.status_code != 200:
            raise ThirdPartyFailure('Status {}: {}'.format(
                r.status_code, r.content))

        token_data = r.json()
        if 'access_token' not in token_data:
            error = token_data['error']
            error_description = token_data['error_description']
            raise ThirdPartyFailure('{}: {}'.format(error, error_description))
        access_token = token_data['access_token']

        r = requests.get('https://openapi.naver.com/v1/nid/me',
                         headers={
                             'Authorization': 'Bearer {}'.format(access_token),
                         })
        if r.status_code != 200:
            raise ThirdPartyFailure('Status {}: {}'.format(
                r.status_code, r.content))

        result = r.json()
        logger.debug('result: %r', result)

        code = result['resultcode']
        message = result['message']
        if code != '00':
            raise ThirdPartyFailure('Fetching profile failed: {} {}'.format(
                code, message))

        profile = result['response']

        return NaverAuthenticationComplete(profile=profile,
                                           credentials=token_data,
                                           provider_name=self.name,
                                           provider_type=self.type)
Ejemplo n.º 29
0
def lastfm_process(request):
    """Process the LastFM redirect"""
    if 'error' in request.GET:
        raise ThirdPartyFailure(
            request.GET.get('error_description', 'No reason provided.'))
    config = request.registry.settings
    api_key = config['velruse.lastfm.api_key']
    token = request.GET.get('token')
    if not token:
        reason = request.GET.get('error_reason', 'No reason provided.')
        return AuthenticationDenied(reason)

    # Now establish a session with the token
    params = {'method': 'auth.getSession', 'api_key': api_key, 'token': token}
    signed_params = sign_call(params, config['velruse.lastfm.secret'])
    session_url = flat_url(API_BASE, format='json', **signed_params)
    r = requests.get(session_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))
    data = loads(r.content)

    session = data['session']
    cred = {'sessionKey': session['key']}

    # Fetch the user data
    user_url = flat_url(API_BASE,
                        format='json',
                        method='user.getInfo',
                        user=session['name'],
                        api_key=api_key)
    r = requests.get(user_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))
    data = loads(r.content)['user']
    profile = {
        'displayName':
        data['name'],
        'gender':
        'male' if data['gender'] == 'm' else 'female',
        'name': {
            'formatted': data.get('realname'),
        },
        'urls': {
            'type': 'profile',
            'value': data.get('url')
        },
        'photos': [],
        'accounts': [{
            'domain': 'last.fm',
            'username': session['name'],
            'userid': data['id']
        }]
    }
    images = {}
    for img in data.get('image', []):
        images[img['size']] = img['#text']
    if 'medium' in images:
        profile['photos'].append({
            'type': 'thumbnail',
            'value': images['medium']
        })
    larger = images.get('extralarge', images.get('large'))
    if larger:
        profile['photos'].append({'type': '', 'value': larger})
    return LastFMAuthenticationComplete(profile=profile, credentials=cred)
Ejemplo n.º 30
0
    def callback(self, request):
        """Process the MailRu redirect"""
        state = request.session.get('state')
        if not state or state != request.GET.get('state'):
            raise CSRFError(
                'CSRF Validation check failed. Request state {req_state} is not '
                'the same as session state {sess_state}'.format(
                    req_state=request.GET.get('state'),
                    sess_state=request.session.get('state')))
        code = request.GET.get('code')
        if not code:
            reason = request.GET.get('error', 'No reason provided.')
            return AuthenticationDenied(reason=reason,
                                        provider_name=self.name,
                                        provider_type=self.type)
        # Now retrieve the access token with the code
        access_params = dict(
            grant_type='authorization_code',
            code=code,
            client_id=self.consumer_key,
            client_secret=self.consumer_secret,
            redirect_uri=request.route_url(self.callback_route),
        )
        r = requests.post(PROVIDER_ACCESS_TOKEN_URL, access_params)
        if r.status_code != 200:
            raise ThirdPartyFailure('Status {status}: {content}'.format(
                status=r.status_code, content=r.content))
        data = json.loads(r.content)
        access_token = data['access_token']

        # Retrieve profile data.

        # Mail.ru API requires a special parameter 'sig' which must be composed
        # by the following sequence
        signature = hashlib.md5(
            'app_id={client_id}'
            'method={method}'
            'secure=1'
            'session_key={access_token}'
            '{secret_key}'.format(
                client_id=self.consumer_key,
                method=PROVIDER_USER_PROFILE_API_METHOD,
                access_token=access_token,
                secret_key=self.consumer_secret)).hexdigest()

        # Read more about the following params on
        # http://api.mail.ru/docs/guides/restapi/#params
        profile_url = flat_url(PROVIDER_USER_PROFILE_URL,
                               method=PROVIDER_USER_PROFILE_API_METHOD,
                               app_id=self.consumer_key,
                               sig=signature,
                               session_key=access_token,
                               secure=1)
        r = requests.get(profile_url)
        if r.status_code != 200:
            raise ThirdPartyFailure('Status {status}: {content}'.format(
                status=r.status_code, content=r.content))
        profile = json.loads(r.content)[0]
        profile = extract_normalize_mailru_data(profile)
        cred = {'oauthAccessToken': access_token}
        return MailRuAuthenticationComplete(profile=profile,
                                            credentials=cred,
                                            provider_name=self.name,
                                            provider_type=self.type)