def check_rate_limit(request, username):
    if STAGING:
        return False

    rate_limit = 10
    return (not RateLimit('login:'******'REMOTE_ADDR'], rate_limit).allowed()
            or not RateLimit('login:' + username, rate_limit).allowed())
예제 #2
0
def check_star_rate_limit(request, comment):
    from drawquest.apps.stars.models import get_star_sticker
    # Calculate if this user has exceeded the stickering rate limit.
    prefix = 'user:{}:stick_limit:'.format(request.user.id)
    if not RateLimit(prefix + 'h', 500, 60 * 60).allowed() or not RateLimit(
            prefix + 'd', 1000, 8 * 60 * 60).allowed():
        Metrics.sticker_ratelimit.record(
            request,
            sticker_type=get_star_sticker().type_id,
            comment=comment.id)
        raise ServiceError("Attempting to star too quickly.")
예제 #3
0
def post_quest_comment(request, quest_id, content_id, fact_metadata={},
                       facebook_share=False, facebook_access_token=None,
                       twitter_share=False, twitter_access_token=None, twitter_access_token_secret=None,
                       email_share=False, email_recipients=[],
                       resolve_share_ids=[],
                       uuid=None):
    if not request.user.is_staff and not settings.STAGING:
        prefix = 'user:{}:post_limit:'.format(request.user.id)
        if not RateLimit(prefix+'h', 60, 60*60).allowed() or not RateLimit(prefix+'d', 100, 8*60*60).allowed():
            raise ServiceError("Attempting to post drawings too quickly.")

    _, parent_comment, content, _, _ = validate_and_clean_comment(
        request.user,
        parent_comment=quest_id,
        reply_content=content_id,
    )

    if facebook_share:
        facebook_share = sns_publishing.facebook_share_pre_post(request, facebook_access_token)

    if twitter_share:
        twitter_share = sns_publishing.twitter_share_pre_post(request, twitter_access_token, twitter_access_token_secret)

    comment = QuestComment.create_and_post(request, request.user, content, parent_comment,
                                           uuid=uuid, fact_metadata=fact_metadata, debug_content_id=content_id)

    if facebook_share:
        sns_publishing.facebook_share_post_post(request, facebook_access_token, comment)

    if twitter_share:
        sns_publishing.twitter_share_post_post(request, twitter_access_token, twitter_access_token_secret, comment)

    for share_id in resolve_share_ids:
        share = ShareTrackingUrl.objects.get(id=share_id)

        if share.redirect_url:
            pass #TODO log some error here without failing this request

        share.redirect_url = comment.get_share_page_url()
        share.save()

    if email_share:
        @bgwork.defer
        def defer_email_share():
            sns_publishing.share_comment_by_email(comment, request.user, email_recipients)

    return {
        'comment': comment.details(),
        'balance': economy.balance(request.user),
    }
예제 #4
0
def add_sticker_to_comment(request, comment_id, type_id, epic_message=None):
    """ Stickers a comment. You can be logged in or out. """
    sticker = stickers.get(int(type_id))
    comment = get_object_or_404(models.Comment, pk=comment_id)

    if epic_message and len(epic_message) > knobs.STICKER_MESSAGE_MAX_LENGTH:
        raise ServiceError("Message is too long.")
    elif epic_message and not (sticker.cost and sticker.cost >=
                               knobs.EPIC_STICKER_COST_THRESHOLD):
        raise ServiceError("Messages can only be attached to epic stickers.")

    # Calculate if this user has exceeded the stickering rate limit.
    prefix = 'user:%s:stick_limit:' % request.user.id
    if not RateLimit(prefix + 'h', 600, 60 * 60).allowed() or not RateLimit(
            prefix + 'd', 1000, 8 * 60 * 60).allowed():
        Metrics.sticker_ratelimit.record(request,
                                         sticker_type=sticker.type_id,
                                         comment=comment.id)
        raise ServiceError("Attempting to sticker too quickly.")

    prev_top_sticker = comment.details().top_sticker()
    remaining = _sticker_comment(request,
                                 comment,
                                 sticker.type_id,
                                 epic_message=epic_message)
    Metrics.sticker.record(request,
                           sticker_type=sticker.type_id,
                           comment=comment.id)

    comment_details = comment.details()
    top_sticker = comment_details.top_sticker()

    @bgwork.defer
    def update_stickered_users():
        get_most_stickered_unfollowed_users(request.user).force()

    if prev_top_sticker is None or prev_top_sticker['type_id'] != top_sticker:

        @bgwork.defer
        def update_footer():
            if comment.footer.should_exist():
                comment.footer.call_update_in_new_process()

    return {
        'new_counts': comment_details.sticker_counts,
        'sorted_counts': comment_details.sorted_sticker_counts(),
        'top_sticker': top_sticker,
        'remaining': remaining,
    }
class TestRateLimiting(CanvasTestCase):
    def after_setUp(self):
        self.rl = RateLimit('test', 2, 100)

    def test_rate_limit_allows_one(self):
        self.assertTrue(self.rl.allowed())

    def test_rate_limit_allows_two(self):
        self.assertTrue(self.rl.allowed())
        self.assertTrue(self.rl.allowed())

    def test_rate_disallows_the_third(self):
        self.assertTrue(self.rl.allowed())
        self.assertTrue(self.rl.allowed())
        self.assertFalse(self.rl.allowed())

    def test_rate_limit_restarts_after_time(self):
        with override_service('time', FakeTimeProvider):
            self.assertTrue(self.rl.allowed())
            self.assertTrue(self.rl.allowed())

            Services.time.step(100)

            self.assertTrue(self.rl.allowed())
            self.assertTrue(self.rl.allowed())
            self.assertFalse(self.rl.allowed())
예제 #6
0
class TestRateLimiting(CanvasTestCase):
    def after_setUp(self):
        self.rl = RateLimit('test', 2, 100)

    def test_rate_limit_allows_one(self):
        self.assertTrue(self.rl.allowed())

    def test_rate_limit_allows_two(self):
        self.assertTrue(self.rl.allowed())
        self.assertTrue(self.rl.allowed())

    def test_rate_disallows_the_third(self):
        self.assertTrue(self.rl.allowed())
        self.assertTrue(self.rl.allowed())
        self.assertFalse(self.rl.allowed())

    def test_rate_limit_restarts_after_time(self):
        with override_service('time', FakeTimeProvider):
            self.assertTrue(self.rl.allowed())
            self.assertTrue(self.rl.allowed())

            Services.time.step(100)

            self.assertTrue(self.rl.allowed())
            self.assertTrue(self.rl.allowed())
            self.assertFalse(self.rl.allowed())
예제 #7
0
파일: api.py 프로젝트: eiritana/canvas
def post_quest_comment(request,
                       quest_id,
                       content_id,
                       fact_metadata={},
                       facebook_share=False,
                       facebook_access_token=None):
    # Rate-limit?
    if not request.user.is_staff:
        prefix = 'user:{}:post_limit:'.format(request.user.id)
        if not RateLimit(prefix + 'h', 60, 60 * 60).allowed() or not RateLimit(
                prefix + 'd', 100, 8 * 60 * 60).allowed():
            raise ServiceError("Attempting to post drawings too quickly.")

    _, parent_comment, content, _, _, _ = validate_and_clean_comment(
        request.user,
        parent_comment=quest_id,
        reply_content=content_id,
    )

    if facebook_share:
        if not facebook_access_token:
            raise ServiceError(
                "Can't share to your timeline if you haven't signed into Facebook yet."
            )

        associate_facebook_account(request.user, facebook_access_token)

    comment = QuestComment.create_and_post(request,
                                           request.user,
                                           content,
                                           parent_comment,
                                           fact_metadata=fact_metadata)

    if facebook_share:
        complete_quest(request.user,
                       comment,
                       facebook_access_token,
                       request=request)

    return {
        'comment': comment.details(),
        'balance': economy.balance(request.user),
    }
 def after_setUp(self):
     self.rl = RateLimit('test', 2, 100)
예제 #9
0
def create_quest(request,
                 title,
                 content_id=None,
                 invite_followees=False,
                 facebook_share=False,
                 facebook_access_token=None,
                 twitter_share=False,
                 twitter_access_token=None,
                 twitter_access_token_secret=None,
                 email_share=False,
                 email_recipients=[],
                 resolve_share_ids=[]):
    if not request.user.is_staff and not settings.STAGING:
        prefix = 'user:{}:create_quest_limit:'.format(request.user.id)
        if not RateLimit(prefix + 'h', 60, 60 * 60).allowed() or not RateLimit(
                prefix + 'd', 100, 8 * 60 * 60).allowed():
            raise ServiceError("Attempting to create quests too quickly.")

    _, _, content, _, title = validate_and_clean_comment(
        request.user,
        parent_comment=None,
        reply_content=content_id,
        title=title,
    )

    if facebook_share:
        facebook_share = sns_publishing.facebook_share_pre_post(
            request, facebook_access_token)

    if twitter_share:
        twitter_share = sns_publishing.twitter_share_pre_post(
            request, twitter_access_token, twitter_access_token_secret)

    quest = Quest.create_and_post(request,
                                  request.user,
                                  title,
                                  content=content,
                                  ugq=True)

    models.autocurate_for_flag_words(quest)

    if invite_followees:
        quest.invited_users.invite(request.user,
                                   request.user.followers(),
                                   ignore_errors=True)

    if facebook_share:
        sns_publishing.facebook_share_post_post(request, facebook_access_token,
                                                quest)

    if twitter_share:
        sns_publishing.twitter_share_post_post(request, twitter_access_token,
                                               twitter_access_token_secret,
                                               quest)

    for share_id in resolve_share_ids:
        share = ShareTrackingUrl.objects.get(id=share_id)

        if share.redirect_url:
            pass  #TODO log some error here without failing this request

        share.redirect_url = quest.get_share_page_url()
        share.save()

    if email_share:

        @bgwork.defer
        def defer_email_share():
            sns_publishing.share_quest_by_email(quest, request.user,
                                                email_recipients)

    @bgwork.defer
    def alert_followers():
        for follower_id in request.user.redis.new_followers.zrange(0, -1):
            RealtimeChannel('user:{}:rt_tab_badges'.format(follower_id),
                            1).publish({'tab_badge_update': 'draw'})

    return {
        'quest': quest.details(),
    }
예제 #10
0
파일: api.py 프로젝트: eiritana/canvas
 def allowed(key, val):
     if request.user.is_staff:
         return True
     freq, timespan = val
     return RateLimit(prefix+key, freq, timespan).allowed()
예제 #11
0
 def after_setUp(self):
     self.rl = RateLimit('test', 2, 100)
예제 #12
0
def check_rate_limit(request):
    return RateLimit('apicall:' + request.META['REMOTE_ADDR'], knobs.PUBLIC_API_RATE_LIMIT).allowed()