Exemple #1
0
def get_user_info(login):
    """Get the given user's information from the DB or failing that, github.

    :param login:
        A unicode string representing a username in github.

    :returns:
        A dictionary containing github specific information for the user.
    """
    typecheck(login, unicode)
    rec = gittip.db.fetchone( "SELECT user_info FROM elsewhere "
                              "WHERE platform='github' "
                              "AND user_info->'login' = %s"
                            , (login,)
                             )
    if rec is not None:
        user_info = rec['user_info']
    else:
        url = "https://api.github.com/users/%s"
        user_info = requests.get(url % login, params={
            'client_id': os.environ.get('GITHUB_CLIENT_ID'),
            'client_secret': os.environ.get('GITHUB_CLIENT_SECRET')
        })
        status = user_info.status_code
        content = user_info.text

        # Calculate how much of our ratelimit we have consumed
        remaining = int(user_info.headers['x-ratelimit-remaining'])
        limit = int(user_info.headers['x-ratelimit-limit'])
        # thanks to from __future__ import division this is a float
        percent_remaining = remaining/limit

        log_msg = ''
        log_lvl = None
        # We want anything 50% or over
        if 0.5 <= percent_remaining:
            log_msg = ("{0}% of GitHub's ratelimit has been consumed. {1}"
                       " requests remaining.").format(percent_remaining * 100,
                                                      remaining)
        if 0.5 <= percent_remaining < 0.8:
            log_lvl = logging.WARNING
        elif 0.8 <= percent_remaining < 0.95:
            log_lvl = logging.ERROR
        elif 0.95 <= percent_remaining:
            log_lvl = logging.CRITICAL

        if log_msg and log_lvl:
            log(log_msg, log_lvl)

        if status == 200:
            user_info = json.loads(content)
        elif status == 404:
            raise Response(404,
                           "GitHub identity '{0}' not found.".format(login))
        else:
            log("Github api responded with {0}: {1}".format(status, content),
                level=logging.WARNING)
            raise Response(502, "GitHub lookup failed with %d." % status)

    return user_info
Exemple #2
0
def oauth_dance(website, qs):
    """Given a querystring, return a dict of user_info.

    The querystring should be the querystring that we get from GitHub when
    we send the user to the return value of oauth_url above.

    See also:

        http://developer.github.com/v3/oauth/

    """

    log("Doing an OAuth dance with Github.")

    data = {
        "code": qs["code"].encode("US-ASCII"),
        "client_id": website.github_client_id,
        "client_secret": website.github_client_secret,
    }
    r = requests.post("https://github.com/login/oauth/access_token", data=data)
    assert r.status_code == 200, (r.status_code, r.text)

    back = dict([pair.split("=") for pair in r.text.split("&")])  # XXX
    if "error" in back:
        raise Response(400, back["error"].encode("utf-8"))
    assert back.get("token_type", "") == "bearer", back
    access_token = back["access_token"]

    r = requests.get("https://api.github.com/user", headers={"Authorization": "token %s" % access_token})
    assert r.status_code == 200, (r.status_code, r.text)
    user_info = json.loads(r.text)
    log("Done with OAuth dance with Github for %s (%s)." % (user_info["login"], user_info["id"]))

    return user_info
Exemple #3
0
def oauth_dance(website, qs):
    """Given a querystring, return a dict of user_info.

    The querystring should be the querystring that we get from GitHub when
    we send the user to the return value of oauth_url above.

    See also:

        http://developer.github.com/v3/oauth/

    """

    log("Doing an OAuth dance with Github.")

    if 'error' in qs:
        raise Response(500, str(qs['error']))

    data = { 'code': qs['code'].encode('US-ASCII')
           , 'client_id': website.github_client_id
           , 'client_secret': website.github_client_secret
            }
    r = requests.post("https://github.com/login/oauth/access_token", data=data)
    assert r.status_code == 200, (r.status_code, r.text)

    back = dict([pair.split('=') for pair in r.text.split('&')]) # XXX
    if 'error' in back:
        raise Response(400, back['error'].encode('utf-8'))
    assert back.get('token_type', '') == 'bearer', back
    access_token = back['access_token']

    r = requests.get( "https://api.github.com/user"
                    , headers={'Authorization': 'token %s' % access_token}
                     )
    assert r.status_code == 200, (r.status_code, r.text)
    user_info = json.loads(r.text)
    log("Done with OAuth dance with Github for %s (%s)."
        % (user_info['login'], user_info['id']))

    return user_info
Exemple #4
0
def oauth_dance(website, qs):
    """Given a querystring, return a dict of user_info.

    The querystring should be the querystring that we get from GitHub when
    we send the user to the return value of oauth_url above.

    See also:

        http://developer.github.com/v3/oauth/

    """

    log("Doing an OAuth dance with Github.")

    data = { 'code': qs['code'].encode('US-ASCII')
           , 'client_id': website.github_client_id
           , 'client_secret': website.github_client_secret
            }
    r = requests.post("https://github.com/login/oauth/access_token", data=data)
    assert r.status_code == 200, (r.status_code, r.text)

    back = dict([pair.split('=') for pair in r.text.split('&')]) # XXX
    if 'error' in back:
        raise Response(400, back['error'].encode('utf-8'))
    assert back.get('token_type', '') == 'bearer', back
    access_token = back['access_token']

    r = requests.get( "https://api.github.com/user"
                    , headers={'Authorization': 'token %s' % access_token}
                     )
    assert r.status_code == 200, (r.status_code, r.text)
    user_info = json.loads(r.text)
    log("Done with OAuth dance with Github for %s (%s)."
        % (user_info['login'], user_info['id']))

    return user_info
Exemple #5
0
def get_user_info(login):
    """Get the given user's information from the DB or failing that, github.

    :param login:
        A unicode string representing a username in github.

    :returns:
        A dictionary containing github specific information for the user.
    """
    typecheck(login, (unicode, UnicodeWithParams))
    rec = gittip.db.one( "SELECT user_info FROM elsewhere "
                         "WHERE platform='github' "
                         "AND user_info->'login' = %s"
                       , (login,)
                        )

    if rec is not None:
        user_info = rec
    else:
        url = "https://api.github.com/users/%s"
        user_info = requests.get(url % login, params={
            'client_id': os.environ.get('GITHUB_CLIENT_ID'),
            'client_secret': os.environ.get('GITHUB_CLIENT_SECRET')
        })
        status = user_info.status_code
        content = user_info.text

        # Calculate how much of our ratelimit we have consumed
        remaining = int(user_info.headers['x-ratelimit-remaining'])
        limit = int(user_info.headers['x-ratelimit-limit'])
        # thanks to from __future__ import division this is a float
        percent_remaining = remaining/limit

        log_msg = ''
        log_lvl = None
        # We want anything 50% or over
        if 0.5 <= percent_remaining:
            log_msg = ("{0}% of GitHub's ratelimit has been consumed. {1}"
                       " requests remaining.").format(percent_remaining * 100,
                                                      remaining)
        if 0.5 <= percent_remaining < 0.8:
            log_lvl = logging.WARNING
        elif 0.8 <= percent_remaining < 0.95:
            log_lvl = logging.ERROR
        elif 0.95 <= percent_remaining:
            log_lvl = logging.CRITICAL

        if log_msg and log_lvl:
            log(log_msg, log_lvl)

        if status == 200:
            user_info = json.loads(content)
        elif status == 404:
            raise Response(404,
                           "GitHub identity '{0}' not found.".format(login))
        else:
            log("Github api responded with {0}: {1}".format(status, content),
                level=logging.WARNING)
            raise Response(502, "GitHub lookup failed with %d." % status)

    return user_info