Example #1
0
 def validate_duration(self, attrs, source):
     value = attrs[source]
     try:
         expand_time(value)
     except ValueError:
         raise serializers.ValidationError("Invalid duration")
     return attrs
Example #2
0
 def validate_duration(self, attrs, source):
     value = attrs[source]
     try:
         expand_time(value)
     except ValueError:
         raise serializers.ValidationError("Invalid duration")
     return attrs
Example #3
0
    def add_block(self, cidr, who, source, why, duration=None, unblock_at=None,
                  skip_whitelist=False, extend=True, autoscale=False):
        if duration:
            duration = expand_time(duration)

        now = timezone.now()
        if duration and not unblock_at:
            unblock_at = now + datetime.timedelta(seconds=duration)

        with advisory_lock("add_block") as acquired, transaction.atomic():
            b = self.get_block(cidr)
            if b:
                if extend is False or b.unblock_at is None or (unblock_at and unblock_at <= b.unblock_at):
                    logger.info('DUPE IP=%s', cidr)
                    return b
                b.unblock_at = unblock_at
                BlockEntry.objects.filter(block_id=b.id).update(unblock_at=unblock_at)
                logger.info('EXTEND IP=%s time extended UNTIL=%s DURATION=%s', cidr, unblock_at, duration)
                b.save()
                return b

            if duration and autoscale:
                lb = self.get_last_block(cidr)
                if lb and lb.duration:
                    last_duration = lb.duration and lb.duration.total_seconds() or duration
                    scaled_duration = max(duration, self.scale_duration(lb.age.total_seconds(), last_duration))
                    logger.info("Scaled duration from %d to %d", duration, scaled_duration)
                    duration = scaled_duration
                    unblock_at = now + datetime.timedelta(seconds=duration)

            b = Block(cidr=cidr, who=who, source=source, why=why, added=now, unblock_at=unblock_at,
                      skip_whitelist=skip_whitelist)
            b.save()

            # It is possible that a block is added, and then after it expires,
            # but before it is unblocked, a new block is added for that entry.
            # In that case, allow the new block
            # (since we don't know if a backend may have already unblocked the old one)
            # but set the old record as already unblocked.
            # This should prevent a "block,block,unblock" timeline that results in the address
            # ending up not actually blocked.
            pending_unblock_records = BlockEntry.objects.filter(removed__isnull=True, block__cidr=cidr).all()
            for e in pending_unblock_records:
                e.set_unblocked()
                e.save()

        quoted_why = quote(why.encode('ascii', 'ignore'))
        logger.info('BLOCK IP=%s WHO=%s SOURCE=%s WHY=%s UNTIL="%s" DURATION=%s', cidr, who, source, quoted_why,
                    unblock_at, duration)
        return b
Example #4
0
    def test_expand_time(self):
        cases = [
            ('10', 10),
            ('10s', 10),
            ('7m', 7 * 60),
            ('14m', 14 * 60),
            ('4h', 4 * 60 * 60),
            ('22h', 22 * 60 * 60),
            ('3d', 3 * 60 * 60 * 24),
            ('3mo', 3 * 60 * 60 * 24 * 30),
            ('2y', 2 * 60 * 60 * 24 * 365),
        ]

        for text, number in cases:
            self.assertEqual(expand_time(text), number)
Example #5
0
    def test_expand_time(self):
        cases = [
            ('10',      10),
            ('10s',     10),
            ('7m',      7*60),
            ('14m',     14*60),
            ('4h',      4*60*60),
            ('22h',     22*60*60),
            ('3d',      3*60*60*24),
            ('3mo',     3*60*60*24*30),
            ('2y',      2*60*60*24*365),
        ]

        for text, number in cases:
            self.assertEqual(expand_time(text), number)
Example #6
0
    def add_block(self, cidr, who, source, why, duration=None, unblock_at=None, skip_whitelist=False, extend=True, autoscale=False):
        if duration:
            duration = expand_time(duration)

        now = timezone.now()
        if duration and not unblock_at:
            unblock_at = now + datetime.timedelta(seconds=duration)

        with advisory_lock("add_block") as acquired, transaction.atomic():
            b = self.get_block(cidr)
            if b:
                if extend is False or b.unblock_at is None or (unblock_at and unblock_at <= b.unblock_at):
                    logger.info('DUPE IP=%s', cidr)
                    return b
                b.unblock_at = unblock_at
                BlockEntry.objects.filter(block_id=b.id).update(unblock_at=unblock_at)
                logger.info('EXTEND IP=%s time extended UNTIL=%s DURATION=%s', cidr, unblock_at, duration)
                b.save()
                return b

            if duration and autoscale:
                lb = self.get_last_block(cidr)
                if lb and lb.duration:
                    last_duration = lb.duration and lb.duration.total_seconds() or duration
                    scaled_duration = max(duration, self.scale_duration(lb.age.total_seconds(), last_duration))
                    logger.info("Scaled duration from %d to %d", duration, scaled_duration)
                    duration = scaled_duration
                    unblock_at = now + datetime.timedelta(seconds=duration)

            b = Block(cidr=cidr, who=who, source=source, why=why, added=now, unblock_at=unblock_at, skip_whitelist=skip_whitelist)
            b.save()

            #It is possible that a block is added, and then after it expires, but before it is unblocked, a new block is added for that entry.
            #In that case, allow the new block (since we don't know if a backend may have already unblocked the old one)
            #but set the old record as already unblocked.  This should prevent a "block,block,unblock" timeline that results in the address
            #ending up not actually blocked.
            pending_unblock_records = BlockEntry.objects.filter(removed__isnull=True, block__cidr=cidr).all()
            for e in pending_unblock_records:
                e.set_unblocked()
                e.save()

        quoted_why = quote(why.encode('ascii', 'ignore'))
        logger.info('BLOCK IP=%s WHO=%s SOURCE=%s WHY=%s UNTIL="%s" DURATION=%s', cidr, who, source, quoted_why, unblock_at, duration)
        return b
Example #7
0
 def validate_duration(self, value):
     try:
         expand_time(value)
     except ValueError:
         raise serializers.ValidationError("Invalid duration")
     return value
Example #8
0
 def validate_duration(self, value):
     try:
         expand_time(value)
     except ValueError:
         raise serializers.ValidationError("Invalid duration")
     return value