def challenge_setup():
    """Set up some sample data to test with.
    
    This is a bit clearer and hopefully more flexible than using fixtures.
    
    """
    challenge_teardown()  # In case other tests didn't clean up
    
    p = Project()
    p.name = 'My Project'
    p.slug = getattr(settings, 'IGNITE_PROJECT_SLUG', 'my-project')
    p.description = 'My super awesome project of awesomeness.'
    p.long_description = 'Did I mention how awesome it was?'
    p.allow_participation = True
    p.save()
    
    c = Challenge()
    c.project = p
    c.title, 'My Challenge'
    c.slug = getattr(settings, 'IGNITE_CHALLENGE_SLUG', 'my-challenge')
    c.summary = 'Are you up to it?'
    c.description = 'This is a challenge of supreme challengingness.'
    c.end_date = datetime.utcnow() + timedelta(days=365)
    c.save()
    
    ph = Phase()
    ph.challenge = c
    ph.name = 'Ideation'
    ph.order = 1
    ph.save()

    cat = Category()
    cat.name = 'Beer'
    cat.slug = 'beer'
    cat.save()
def challenge_setup():
    """Set up some sample data to test with.
    
    This is a bit clearer and hopefully more flexible than using fixtures.
    
    """
    challenge_teardown()  # In case other tests didn't clean up

    p = Project()
    p.name = 'My Project'
    p.slug = getattr(settings, 'IGNITE_PROJECT_SLUG', 'my-project')
    p.description = 'My super awesome project of awesomeness.'
    p.long_description = 'Did I mention how awesome it was?'
    p.allow_participation = True
    p.save()

    c = Challenge()
    c.project = p
    c.title, 'My Challenge'
    c.slug = getattr(settings, 'IGNITE_CHALLENGE_SLUG', 'my-challenge')
    c.summary = 'Are you up to it?'
    c.description = 'This is a challenge of supreme challengingness.'
    c.end_date = datetime.utcnow() + timedelta(days=365)
    c.save()

    ph = Phase()
    ph.challenge = c
    ph.name = 'Ideation'
    ph.order = 1
    ph.save()

    cat = Category()
    cat.name = 'Beer'
    cat.slug = 'beer'
    cat.save()
Example #3
0
def create_challenge(
    title,
    start_date,
    end_date,
    host_team,
    participant_host_team,
    anon_leaderboard=False,
    is_featured=False,
):
    """
    Creates a challenge.
    """
    evaluation_script = open(
        os.path.join(
            settings.BASE_DIR,
            "examples",
            "example1",
            "sample_evaluation_script.zip",
        ),
        "rb",
    )
    queue = "".join(random.choice(string.ascii_letters) for _ in range(75))
    year = datetime.date.today().year
    # add UUID here
    uuid_stamp = uuid.uuid4().hex[0:10]
    slug = "{t}-{y}-{z}".format(t=title, y=year, z=uuid_stamp)
    slug = slug.lower().replace(" ", "-")[:198]
    image_file = ContentFile(get_file_content(CHALLENGE_IMAGE_PATH, "rb"),
                             "logo.png")
    challenge = Challenge(
        title=title,
        short_description=fake.paragraph(),
        description=fake.paragraph(),
        terms_and_conditions=fake.paragraph(),
        submission_guidelines=fake.paragraph(),
        evaluation_details=fake.paragraph(),
        evaluation_script=SimpleUploadedFile(evaluation_script.name,
                                             evaluation_script.read()),
        approved_by_admin=True,
        leaderboard_description=fake.paragraph(),
        creator=host_team,
        published=True,
        enable_forum=True,
        anonymous_leaderboard=anon_leaderboard,
        start_date=start_date,
        end_date=end_date,
        queue=queue,
        featured=is_featured,
        image=image_file,
    )
    challenge.save()

    challenge.slug = slug
    challenge.participant_teams.add(participant_host_team)
    challenge.save()

    print(
        "Challenge created with title: {} creator: {} start_date: {} end_date: {}"
        .format(title, host_team.team_name, start_date, end_date))
    def test_null_start_date(self):
        ch4 = Challenge(title='Challenge 4', external_id=12)
        ch4.save()

        response = self.client.get('/')

        challenge = response.data['challenge']
        self.assertEqual(3, challenge['id'])
    def test_all_ended_one_null(self):
        ch4 = Challenge(title='Challenge 4', external_id=12)
        ch4.save()
        self.timezone_mock.now.return_value = datetime(2020, 10, 1)

        response = self.client.get('/')

        challenge = response.data['challenge']
        self.assertEqual(5, challenge['id'])
    def test_all_ended_one_upcoming(self):
        ch4 = Challenge(title='Challenge 4',
                        external_id=12,
                        start_date=date(2021, 1, 1),
                        end_date=date(2021, 1, 30))
        ch4.save()
        self.timezone_mock.now.return_value = datetime(2020, 10, 1)

        response = self.client.get('/')

        challenge = response.data['challenge']
        self.assertEqual(2, challenge['id'])
    def test_non_final_challenges(self):
        ch = Challenge(title='Challenge Recently Ended', external_id=30, start_date=date(2020, 2, 1), end_date=date(2020, 2, 25))
        ch.save()

        challenges = Challenge.objects.get_non_final()

        eids = set(ch.external_id for ch in challenges)
        # 5, 6: ongoing
        # 12: upcoming
        # 14: no date
        # 30: recendly ended
        self.assertEqual({5, 6, 12, 14, 30}, eids)
Example #8
0
    def setUp(self):
        super().setUp()
        challenge = Challenge(external_id=10)
        self.challenge = challenge
        challenge.save()

        challenge_page = Mock()
        self.challenge_page = challenge_page
        self.challenge_title = 'My Challenge!'
        self.start_date = date(2019, 10, 20)
        self.end_date = date(2020, 1, 22)
        challenge_page.title = self.challenge_title
        challenge_page.end_date = self.end_date
        challenge_page.start_date = self.start_date
        challenge_page.competitors = []
Example #9
0
def makeChallenges():
    ctf_categories = ['Web', 'Pwn', 'Crypto', 'Reverse', 'Triva', 'Script']
    ctf_challenge_points = [100, 200, 300, 400, 500]

    for category in ctf_categories:
        cat = Category.objects.get(name=category)
        for challenge_points in ctf_challenge_points:
            chal_str = "%s %s" % (category, str(challenge_points))
            chal = Challenge(category=cat,
                             name=chal_str,
                             description="{0} challenge".format(chal_str),
                             points=challenge_points,
                             hidden=True)
            chal.save()
            flag = Flag(value=hashlib.md5('flag'.encode('utf-8')).hexdigest(),
                        challenge=chal)
            flag.save()
Example #10
0
File: schema.py Project: yacf/yacf
    def mutate(self, info, name, description, category, flag, precomputed, hashed, points=0, encoded=False, hidden=False):
        validate_user_is_admin(info.context.user)
        get_category = Category.objects.get(name=category)
        
        newChallenge = Challenge(name=name, description=description, encoded=encoded, points=points, hidden=hidden, category=get_category)
        newChallenge.save()

        if hashed:
            if precomputed:
                flag = Flag(value=flag, challenge=newChallenge)
            else:
                flag = Flag(value=hashlib.sha256(flag.encode('utf-8')).hexdigest(), challenge=newChallenge)
        else:
            flag = Flag(value=flag, challenge=newChallenge)

        flag.save()

        return AddChallenge(code=0)
 def handle(self, *args, **options):
     if len(args) < 1:
         self.stderr.write('Please provide a directory containing the files '+
                           'relative to PROJECT_DIR.')
     
     base_dir = os.path.join(settings.PROJECT_DIR, '..', args[0])
     
     # Go through all of the challenges and compile them. This will update
     # existing challenges and add new ones.
     for slug in os.listdir( os.path.join(base_dir) ):
         try:
             data = ""
             f = open(os.path.join(base_dir, slug))
             data = f.read()
             f.close()
             
             # If the challenge is already there, update it!
             try: c = Challenge.objects.get(slug=slug)
             except: c = Challenge(slug=slug)
             
             c.description = ""
             c.preamble = ""
             c.postamble = ""
             c.autograde = ""
             
             stage = "description"
             for l in data.splitlines():
                 if l.startswith("%% "):
                     l = l[3:].strip()
                     if l.startswith("name:"): c.name = l[5:].strip()
                     elif l.startswith("pattern:"): c.pattern = Pattern.objects.get(name=l[8:].strip())
                     elif l.startswith("autograde:"): c.autograde = l[10:].strip()
                     elif l.startswith("ordering:"): c.ordering = int(l[9:].strip())
                 elif l.startswith("% "):
                     stage = l[2:].strip()
                 elif stage == "description": c.description += l+"\n"
                 elif stage == "preamble": c.preamble += l+"\n"
                 elif stage == "postamble": c.postamble += l+"\n"
             c.save()
             self.stdout.write('Wrote challenge: %s\n'%(slug))
             
         except: self.stderr.write('Skipped challenge: %s\n'%(slug))
     
     self.stdout.write('Successfully compiled challenges!\n')
Example #12
0
    def mutate(self,
               info,
               name,
               description,
               points=0,
               flag="",
               show=False,
               category=None):
        validate_user_is_admin(info.context.user)

        try:
            if category:
                try:
                    category = Category.objects.get(name=category)
                    newChallenge = Challenge(name=name,
                                             description=description,
                                             points=points,
                                             show=show,
                                             category=category)
                    newChallenge.save()
                    flag = Flag(value=hashlib.md5(
                        flag.encode('utf-8')).hexdigest(),
                                challenge=newChallenge)
                    flag.save()
                except:
                    # Category not found
                    message = "failure"
            else:
                newChallenge = Challenge(name=name,
                                         description=description,
                                         points=points,
                                         show=show)
                newChallenge.save()
                flag = Flag(value=flag, challenge=newChallenge)
                flag.save()

            message = "success"
        except:
            message = "failure"

        return AddChallenge(message)
    def setUp(self):
        super().setUp()
        ch4 = Challenge(title='Challenge 4', external_id=12, start_date=date(2020, 6, 1), end_date=date(2020, 6, 30))
        ch5 = Challenge(title='Challenge 5', external_id=13, start_date=date(2018, 1, 1), end_date=date(2018, 1, 30))
        ch6 = Challenge(title='Challenge 6', external_id=14)
        ch4.save()
        ch5.save()
        ch6.save()

        datetime_patch = patch('challenges.views.timezone')
        self.timezone_mock = datetime_patch.start()
        self.timezone_mock.now.return_value = datetime(2020, 2, 25)
        datetime2_patch = patch('challenges.models.challenge.timezone')
        self.timezone2_mock = datetime2_patch.start()
        self.timezone2_mock.now.return_value = datetime(2020, 2, 25)
Example #14
0
    def test_subcategory_max_score_is_updated(self):
        """
        Test if the SubCategory's max score is updated on Challenge creation
        This is done to capture the fact that sometimes we'll have new challenges added or removed and
        it needs to reflex the max score in a subcategory
        """
        c1 = Challenge(name='Sub1', difficulty=5, score=200, description=ChallengeDescFactory(),
                       test_case_count=5, category=self.sub1)
        c2 = Challenge(name='Sub1_2', difficulty=5, score=200, description=ChallengeDescFactory(),
                       test_case_count=5, category=self.sub1)
        c3 = Challenge(name='Sub2', difficulty=5, score=200, description=ChallengeDescFactory(),
                       test_case_count=5, category=self.sub2)
        c1.save(); c2.save(); c3.save()

        self.sub1.refresh_from_db()
        self.sub2.refresh_from_db()
        self.sub3.refresh_from_db()
        self.assertEqual(self.sub1.max_score, 400)
        self.assertEqual(self.sub2.max_score, 200)
        self.assertEqual(self.sub3.max_score, 0)
Example #15
0
    def mutate(self, info, category, title, points, description, flag, hosted, ports, image_name=None, upload=None):
        user = info.context.user
        # Validate user is admin
        validate_user_is_admin(user)

        # sanitize all the input fields
        validate_flag(flag)
        validate_flag_unique(flag)
        validate_points(points)
        validate_title(title)
        validate_description(description)
        validate_category_exists(category)
        if image_name:
            validate_imageName(image_name)
        if ports:
            validate_ports(ports)
        # if path_prefix:
        #     validate_pathPrefix(path_prefix)
        #     validate_pathPrefix_unique(path_prefix)

        # parse dockerfile for list of ports
        if upload:
            try:
                ports = list()
                for line in upload:
                    line = line.decode('utf-8')
                    start = 'EXPOSE '

                    if (start in line):
                        possible_port = (line[line.find(start)+len(start):])
                        ports.append(possible_port.split())

                # flatten list
                flattened_ports = list(
                    set([val for sublist in ports for val in sublist]))
                print(flattened_ports)

            except Exception as e:
                raise Exception('Error parsing uploaded Dockerfile: ', e)

        challenge_category = Category.objects.get(id=category)

        # Save the challenge flag to the database
        challenge = Challenge(category=challenge_category, title=title, description=description,
                              flag=flag, points=points, hosted=hosted, imageName=image_name, ports=ports)
        challenge.save()

        # set var for pathPrefix and tag
        path_tag = str(challenge.id)
        challenge.pathPrefix = path_tag

        if upload:
            image_name = path_tag + ':latest'

            # build image
            build = d.buildImage(fileobj=upload.file, tag=path_tag)

            # delete already saved challenge if build fails
            if not build:
                chall_id = challenge.id
                try:
                    challenge.delete()
                except:
                    # raise exception if unable to delete already saved challenge requiring manual intervention
                    raise Exception(
                        'Unable to delete challenge ID: %i. Manual deletion necessary.' % (chall_id))

                raise Exception(
                    'Unable to build image.  Reverted challenge creation.')

            challenge.upload = upload
            challenge.imageName = image_name

        challenge.save()

        # Push the realtime data to rethinkdb
        connection = r.connect(host=RDB_HOST, port=RDB_PORT)
        try:
            r.db(CTF_DB).table('challenges').insert({'sid': challenge.id, 'category': challenge.category.id, 'title': title, 'points': points, 'description': description,
                                                     'hosted': hosted, 'imageName': image_name, 'ports': ports, 'pathPrefix': path_tag, 'created': format(challenge.created, 'U')}).run(connection)
        except RqlRuntimeError as e:
            raise Exception(
                'Error adding challenge to realtime database: %s' % (e))
        finally:
            connection.close()

        return AddChallenge(status='Challenge Created')
Example #16
0
def insertRealChallenges():
    connection = r.connect(host=RDB_HOST, port=RDB_PORT)
    try:
        with open('challenges.json') as f:
            data = json.load(f)
            for c in data:
                category = Category.objects.filter(
                    name__icontains=c['category'])
                if c['hosted']:
                    challenge = Challenge(category=category[0],
                                          flag=c['flag'],
                                          points=c['points'],
                                          title=c['title'],
                                          description=c['description'],
                                          hosted=c['hosted'],
                                          fileUpload=c['fileUpload'],
                                          imageName=c['imageName'],
                                          ports=c['ports'],
                                          pathPrefix=c['pathPrefix'])
                else:
                    challenge = Challenge(category=category[0],
                                          flag=c['flag'],
                                          points=c['points'],
                                          title=c['title'],
                                          description=c['description'],
                                          hosted=c['hosted'],
                                          fileUpload=c['fileUpload'])
                challenge.save()

                if c['hosted']:
                    r.db(CTF_DB).table('challenges').insert({
                        'sid':
                        challenge.id,
                        'category':
                        challenge.category.id,
                        'title':
                        c['title'],
                        'points':
                        challenge.points,
                        'description':
                        c['description'],
                        'solved_count':
                        0,
                        'hosted':
                        c['hosted'],
                        'fileUpload':
                        c['fileUpload'],
                        'imageName':
                        c['imageName'],
                        'ports':
                        c['ports'],
                        'pathPrefix':
                        c['pathPrefix'],
                        'created':
                        format(challenge.created, 'U')
                    }).run(connection)
                else:
                    r.db(CTF_DB).table('challenges').insert({
                        'sid':
                        challenge.id,
                        'category':
                        challenge.category.id,
                        'title':
                        c['title'],
                        'points':
                        challenge.points,
                        'description':
                        c['description'],
                        'solved_count':
                        0,
                        'hosted':
                        c['hosted'],
                        'fileUpload':
                        c['fileUpload'],
                        'created':
                        format(challenge.created, 'U')
                    }).run(connection)

    except RqlRuntimeError as e:
        raise Exception('Error adding challenges to realtime database: %s' %
                        (e))
    finally:
        connection.close()
Example #17
0
def insertChallengeBoard():
    i = 1
    # Push test challenges to rethinkdb database
    connection = r.connect(host=RDB_HOST, port=RDB_PORT)
    try:
        for category in Category.objects.all():
            # Save the challenge flag to the database
            challenge_50 = Challenge(category=category,
                                     flag="flag{0}".format(i),
                                     points=50,
                                     title='Test Title',
                                     description='Test Description',
                                     hosted=True,
                                     fileUpload=False,
                                     imageName='tutum/hello-world:latest',
                                     ports='80',
                                     pathPrefix="path{0}".format(i))
            challenge_50.save()
            i += 1

            # Save the challenge flag to the database
            challenge_100 = Challenge(category=category,
                                      flag="flag{0}".format(i),
                                      points=100,
                                      title='Test Title',
                                      description='Test Description',
                                      hosted=True,
                                      fileUpload=False,
                                      imageName='tutum/hello-world:latest',
                                      ports='80',
                                      pathPrefix="path{0}".format(i))
            challenge_100.save()
            i += 1

            # Save the challenge flag to the database
            challenge_200 = Challenge(category=category,
                                      flag="flag{0}".format(i),
                                      points=200,
                                      title='Test Title',
                                      description='Test Description',
                                      hosted=True,
                                      fileUpload=False,
                                      imageName='tutum/hello-world:latest',
                                      ports='80',
                                      pathPrefix="path{0}".format(i))
            challenge_200.save()
            i += 1

            # Save the challenge flag to the database
            challenge_300 = Challenge(category=category,
                                      flag="flag{0}".format(i),
                                      points=300,
                                      title='Test Title',
                                      description='Test Description',
                                      hosted=False,
                                      fileUpload=True)
            challenge_300.save()
            i += 1

            # Save the challenge flag to the database
            challenge_400 = Challenge(category=category,
                                      flag="flag{0}".format(i),
                                      points=400,
                                      title='Test Title',
                                      description='Test Description',
                                      hosted=False,
                                      fileUpload=False)
            challenge_400.save()
            i += 1

            # Save the challenge flag to the database
            challenge_500 = Challenge(category=category,
                                      flag="flag{0}".format(i),
                                      points=500,
                                      title='Test Title',
                                      description='Test Description',
                                      hosted=False,
                                      fileUpload=False)
            challenge_500.save()
            i += 1

            r.db(CTF_DB).table('challenges').insert({
                'sid':
                challenge_50.id,
                'category':
                challenge_50.category.id,
                'title':
                'Test Title',
                'points':
                challenge_50.points,
                'description':
                'Test Description',
                'solved_count':
                0,
                'hosted':
                True,
                'fileUpload':
                False,
                'imageName':
                'tutum/hello-world:latest',
                'ports':
                '80',
                'pathPrefix':
                challenge_50.pathPrefix,
                'created':
                format(challenge_50.created, 'U')
            }).run(connection)
            r.db(CTF_DB).table('challenges').insert({
                'sid':
                challenge_100.id,
                'category':
                challenge_100.category.id,
                'title':
                'Test Title',
                'points':
                challenge_100.points,
                'description':
                'Test Description',
                'solved_count':
                0,
                'hosted':
                True,
                'fileUpload':
                False,
                'imageName':
                'tutum/hello-world:latest',
                'ports':
                '80',
                'pathPrefix':
                challenge_100.pathPrefix,
                'created':
                format(challenge_100.created, 'U')
            }).run(connection)
            r.db(CTF_DB).table('challenges').insert({
                'sid':
                challenge_200.id,
                'category':
                challenge_200.category.id,
                'title':
                'Test Title',
                'points':
                challenge_200.points,
                'description':
                'Test Description',
                'solved_count':
                0,
                'hosted':
                True,
                'fileUpload':
                False,
                'imageName':
                'tutum/hello-world:latest',
                'ports':
                '80',
                'pathPrefix':
                challenge_200.pathPrefix,
                'created':
                format(challenge_200.created, 'U')
            }).run(connection)
            r.db(CTF_DB).table('challenges').insert({
                'sid':
                challenge_300.id,
                'category':
                challenge_300.category.id,
                'title':
                'Test Title',
                'points':
                challenge_300.points,
                'description':
                'Test Description',
                'solved_count':
                0,
                'hosted':
                False,
                'fileUpload':
                True,
                'created':
                format(challenge_300.created, 'U')
            }).run(connection)
            r.db(CTF_DB).table('challenges').insert({
                'sid':
                challenge_400.id,
                'category':
                challenge_400.category.id,
                'title':
                'Test Title',
                'points':
                challenge_400.points,
                'description':
                'Test Description',
                'solved_count':
                0,
                'hosted':
                False,
                'fileUpload':
                False,
                'created':
                format(challenge_400.created, 'U')
            }).run(connection)
            r.db(CTF_DB).table('challenges').insert({
                'sid':
                challenge_500.id,
                'category':
                challenge_500.category.id,
                'title':
                'Test Title',
                'points':
                challenge_500.points,
                'description':
                'Test Description',
                'solved_count':
                0,
                'hosted':
                False,
                'fileUpload':
                False,
                'created':
                format(challenge_500.created, 'U')
            }).run(connection)

    except RqlRuntimeError as e:
        raise Exception('Error adding challenges to realtime database: %s' %
                        (e))
    finally:
        connection.close()
Example #18
0
File: builder.py Project: yacf/yacf
        cap.save()

    for cat in data['board']['categories']:
        print(cat['name'])

        ca = Category(name=cat['name'], description=cat['description'])
        ca.save()
        '''
            Challenge create. 
            Required: Category, Name, Description, Points, Flag 
        '''
        for challenge in cat['challenges']:
            print(" |--", challenge['name'])

            if challenge['name'] and challenge['description'] and challenge[
                    'points'] and challenge['flag']:
                chal = Challenge(category=ca,
                                 name=challenge['name'],
                                 description=challenge['description'],
                                 points=challenge['points'],
                                 hidden=False)
                chal.save()
                flag_v = compute_flag(challenge['flag'])
                flag = Flag(value=flag_v,
                            hashed=challenge['flag']['hashed'],
                            challenge=chal)
                flag.save()
            else:
                print("Failed", challenge)
                exit()
Example #19
0
    def setUp(self):
        self.ch1_start = date(2020, 2, 1)
        self.ch1_end = date(2020, 3, 15)
        ch0 = Challenge(title='Challenge 0',
                        external_id=4,
                        start_date=date(2019, 11, 20),
                        end_date=date(2019, 11, 25))
        ch1 = Challenge(title='Challenge 1',
                        external_id=5,
                        start_date=self.ch1_start,
                        end_date=self.ch1_end)
        ch2 = Challenge(title='Challenge 2',
                        external_id=6,
                        start_date=date(2020, 2, 10),
                        end_date=date(2020, 2, 29))
        ch3 = Challenge(title='Challenge 3',
                        external_id=2,
                        start_date=date(2019, 6, 1),
                        end_date=date(2019, 6, 30))
        ch0.save()
        ch1.save()
        ch2.save()
        ch3.save()
        t1 = Team(name='Team A', challenge=ch1)
        t2 = Team(name='Team B', challenge=ch1)
        t3 = Team(name='Team C', challenge=ch2)
        t1.save()
        t2.save()
        t3.save()
        comp1 = Competitor(external_id=10, name='Competitor 1')
        comp2 = Competitor(external_id=20, name='Competitor 2')
        comp3 = Competitor(external_id=25,
                           name='Competitor 3',
                           display_name='Competitor C')
        comp4 = Competitor(external_id=26, name='Competitor 4')
        comp5 = Competitor(external_id=27, name='Competitor 5')
        comp6 = Competitor(external_id=28, name='Competitor 6')
        comp7 = Competitor(external_id=29, name='Competitor 7')
        comp1.save()
        comp2.save()
        comp3.save()
        comp4.save()
        comp5.save()
        comp6.save()
        comp7.save()
        comp1.teams.add(t1)
        comp3.teams.add(t1)
        comp4.teams.add(t1)
        comp5.teams.add(t3)
        comp6.teams.add(t2)
        comp7.teams.add(t2)
        comp1.save()
        comp3.save()
        comp4.save()
        comp5.save()
        comp6.save()
        comp7.save()

        comp1_stats = Stats(calories=1001, competitor=comp1, challenge=ch1)
        comp2_stats = Stats(calories=500, competitor=comp3, challenge=ch1)
        comp5_stats = Stats(calories=2000, competitor=comp5, challenge=ch2)
        comp6_stats = Stats(calories=100, competitor=comp6, challenge=ch1)
        comp7_stats = Stats(calories=20, competitor=comp7, challenge=ch1)
        comp1_stats.save()
        comp2_stats.save()
        comp5_stats.save()
        comp6_stats.save()
        comp7_stats.save()
Example #20
0
def bulk_update(request: HttpRequest):
    try:
        challenges_data = json.loads(request.body.decode())
        challenges = challenges_data["challenges"]
    except Exception:
        logger.exception("Couldn't load json")
        return JsonResponse({"message": "Couldn't load json data"}, status=400)

    try:
        assert isinstance(challenges, list)
        assert len(challenges) > 0 and isinstance(challenges[0], dict)
    except AssertionError:
        logger.exception(
            "Expected a list of dict, representing the challenges")
        return JsonResponse(
            {
                "message":
                "Expected a list of dict, representing the challenges"
            },
            status=400)

    try:
        challenge_slugs = {chal["slug"] for chal in challenges}
        assert len(challenge_slugs) == len(challenges)
    except (KeyError, AssertionError):
        return JsonResponse(
            {
                "message":
                "`slug` should be present and unique in all challenges"
            },
            status=400)

    expected_data = """Challenges should be of this form (following documentation may not be up to date): {
              "difficulty": 0-4 (0 easier, 4 harder),
              "name": "bla bla" (len<50),
              "slug": "bla-bla" (extracted from name, identifies the challenge),
              "description": "Fun story in html",
              "category": Any of: "MIC", "WEB", "PPC", "FOR", "REV", "PWN", "CRY", "NET",
              "flag": "INSA{the flag}" (len<=255),
              "static_url": null OR "url of the static files for the chal",
              "company_logo_url": null OR "the URL of the company who wrote the chal, if any",
              "nb_points_override": integer, if greater then -3, it will override the automagic points calculus 
            }"""

    for chal in challenges:
        try:
            difficulty = chal["difficulty"]
            name = chal["name"]
            slug = chal["slug"]
            description = chal["description"]
            category = chal["category"]
            flag = sha256(chal["flag"].encode('utf-8')).hexdigest()
            static_url = chal["static_url"]
            company_logo_url = chal["company_logo_url"]
            nb_points_override = chal["nb_points_override"]
        except KeyError:
            logger.exception("Wrong challenge format")
            return JsonResponse({"message": expected_data}, status=400)

        try:
            try:
                chal = Challenge.all_objects.get(slug=slug)
                chal.difficulty = difficulty
                chal.name = name
                chal.description = description
                chal.category = category
                chal.flag = flag
                chal.static_url = static_url
                chal.company_logo_url = company_logo_url
                chal.nb_points_override = nb_points_override
                chal.full_clean()
                chal.save()
            except ObjectDoesNotExist:
                chal = Challenge(difficulty=difficulty,
                                 name=name,
                                 slug=slug,
                                 description=description,
                                 category=category,
                                 flag=flag,
                                 static_url=static_url,
                                 company_logo_url=company_logo_url,
                                 nb_points_override=nb_points_override)
                chal.full_clean()
                chal.save()
        except ValidationError as e:
            logger.exception("Wrong challenge format")
            return JsonResponse(
                {
                    "message":
                    "Challenge `{}` doesn't have the right form: {}.\n{}".
                    format(name, e, expected_data)
                },
                status=400)
        except Exception as e:
            logger.exception("Exception creating the challenge")
            return JsonResponse(
                {
                    "message":
                    "Error while updating {}, please check the serverlogs. err: {}"
                    "\nFor reference: {}".format(name, e, expected_data)
                },
                status=500)

    Challenge.all_objects.exclude(slug__in=challenge_slugs).delete()
    return JsonResponse({"message": "OK"}, status=200)