Beispiel #1
0
    def api_error_handler(self, response, is_user_session, domain):
        response_text = response.text  # for Sentry
        status = response.status_code
        if status == 404:
            raise Response(404, response_text)
        if status == 401 and is_user_session:
            # https://tools.ietf.org/html/rfc5849#section-3.2
            raise TokenExpiredError
        if status == 429 and is_user_session:
            limit, remaining, reset = self.get_ratelimit_headers(response)

            def msg(_, to_age):
                if remaining == 0 and reset:
                    return _(
                        "You've consumed your quota of requests, you can try again in {0}.",
                        to_age(reset))
                else:
                    return _(
                        "You're making requests too fast, please try again later."
                    )

            raise LazyResponse(status, msg)
        if status != 200:
            logger.error('{} responded with {}:\n{}'.format(
                domain, status, response_text))
            msg = lambda _: _("{0} returned an error, please try again later.",
                              domain)
            raise LazyResponse(502, msg)
Beispiel #2
0
    def api_error_handler(self, response, is_user_session):
        status = response.status_code
        if status == 404:
            raise Response(404, response.text)
        if status == 429 and is_user_session:
            limit, remaining, reset = self.get_ratelimit_headers(response)

            def msg(_, to_age):
                if remaining == 0 and reset:
                    return _(
                        "You've consumed your quota of requests, you can try again in {0}.",
                        to_age(reset))
                else:
                    return _(
                        "You're making requests too fast, please try again later."
                    )

            raise LazyResponse(status, msg)
        if status != 200:
            log('{} api responded with {}:\n{}'.format(self.name, status,
                                                       response.text),
                level=logging.ERROR)
            msg = lambda _: _("{0} returned an error, please try again later.",
                              self.display_name)
            raise LazyResponse(502, msg)
Beispiel #3
0
    def api_get(self, path, sess=None, **kw):
        """
        Given a `path` (e.g. /users/foo), this function sends a GET request to
        the platform's API (e.g. https://api.github.com/users/foo).

        The response is returned, after checking its status code and ratelimit
        headers.
        """
        url = self.api_url + path
        is_user_session = bool(sess)
        if not sess:
            sess = self.get_auth_session()
            if self.name == 'github':
                url += '?' if '?' not in url else '&'
                url += 'client_id=%s&client_secret=%s' % (self.api_key,
                                                          self.api_secret)
        response = sess.get(url, **kw)

        limit, remaining, reset = self.get_ratelimit_headers(response)
        if not is_user_session:
            self.log_ratelimit_headers(limit, remaining, reset)

        # Check response status
        status = response.status_code
        if status == 401 and isinstance(self, PlatformOAuth1):
            # https://tools.ietf.org/html/rfc5849#section-3.2
            if is_user_session:
                raise TokenExpiredError
            raise Response(500)
        if status == 404:
            raise Response(404, response.text)
        if status == 429 and is_user_session:

            def msg(_, to_age):
                if remaining == 0 and reset:
                    return _(
                        "You've consumed your quota of requests, you can try again in {0}.",
                        to_age(reset))
                else:
                    return _(
                        "You're making requests too fast, please try again later."
                    )

            raise LazyResponse(status, msg)
        if status != 200:
            log('{} api responded with {}:\n{}'.format(self.name, status,
                                                       response.text),
                level=logging.ERROR)
            msg = lambda _: _("{0} returned an error, please try again later.",
                              self.display_name)
            raise LazyResponse(502, msg)

        return response
Beispiel #4
0
 def register_app(self, domain):
     data = {
         'client_name': self.app_name,
         'redirect_uris': self.callback_url.format(domain=domain),
         'scopes': 'read',
         'website': self.app_url,
     }
     r = requests.post('https://%s/api/v1/apps' % domain,
                       data,
                       timeout=self.api_timeout)
     status = r.status_code
     try:
         o = r.json()
         c_id, c_secret = o['client_id'], o['client_secret']
     except (KeyError, ValueError):
         c_id, c_secret = None, None
     if status != 200 or not c_id or not c_secret:
         logger.error('{} responded with {}:\n{}'.format(
             domain, status, r.text))
         msg = lambda _: _(
             "Is {0} really a {1} server? It is currently not acting like one.",
             domain,
             self.display_name,
         )
         raise LazyResponse(502, msg)
     return c_id, c_secret
Beispiel #5
0
def _record_transfer_result(db, t_id, status):
    with db.get_cursor() as c:
        tipper, tippee, amount = c.one(
            """
            UPDATE transfers
               SET status = %s
             WHERE id = %s
         RETURNING tipper, tippee, amount
        """, (status, t_id))
        if status == 'succeeded':
            balance = c.one(
                """

                UPDATE participants
                   SET balance = balance + %(amount)s
                 WHERE id = %(tippee)s;

                UPDATE participants
                   SET balance = balance - %(amount)s
                 WHERE id = %(tipper)s
                   AND balance - %(amount)s >= 0
             RETURNING balance;

            """, locals())
            if balance is None:
                raise NegativeBalance
            bundles = c.all(
                """
                LOCK TABLE cash_bundles IN EXCLUSIVE MODE;
                SELECT *
                  FROM cash_bundles
                 WHERE owner = %s
              ORDER BY ts
            """, (tipper, ))
            x = amount
            for b in bundles:
                if x >= b.amount:
                    c.run(
                        """
                        UPDATE cash_bundles
                           SET owner = %s
                         WHERE id = %s
                    """, (tippee, b.id))
                    x -= b.amount
                    if x == 0:
                        break
                else:
                    c.run(
                        """
                        UPDATE cash_bundles
                           SET amount = (amount - %s)
                         WHERE id = %s;

                        INSERT INTO cash_bundles
                                    (owner, origin, amount, ts)
                             VALUES (%s, %s, %s, %s);
                    """, (x, b.id, tippee, b.origin, x, b.ts))
                    break
            return balance
    raise LazyResponse(
        500, lambda _: _("Transfering the money failed, please try again."))