Beispiel #1
0
def api_add_group(api, sess, args):
    http    = args['http_handler']
    request = json.loads(http.request.body)
    name    = request['name']
    parent  = request['parent']
    seed    = request['seed']
    try:
        parent = int(parent)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='parent',
            )
        )

    if (type(seed) is not str or len(seed) != 16) and seed != 'inherit':
        raise ApiArgumentError(lc.get('api_argument_error').format(argument='seed'))
    elif parent == 0 and seed == 'inherit':
        raise InvalidInheritError()

    if name == '':
        raise EmptyGroupNameError()
    if parent != 0:
        read_group(parent)

    group_id = allocate_group_id()

    logger.info('Creating group {} ({})', name, group_id)
    write_group(group_id, {'name': name, 'parent': parent, 'seed': seed})
    http.write(json.dumps({'success': True}))
Beispiel #2
0
    def post(self):
        with locks.global_lock:
            username = self.get_argument('username', None)
            password = self.get_argument('password', None)
            if username is None:
                self.write(
                    render_template('auth_error.html',
                                    error=lc.get('no_username')))
                return
            if password is None:
                self.write(
                    render_template('auth_error.html',
                                    error=lc.get('no_password')))
                return

            try:
                session = auth.authenticate_user(username, password)
            except auth.BaseAuthenticationError as e:
                self.write(
                    render_template('auth_error.html', error=lc.get(e.text)))
                return
            self.set_cookie('session_id',
                            session.id,
                            expires=session.expires_at)
            self.redirect('/')
Beispiel #3
0
 def post(self, *a):
     with locks.global_lock:
         session = auth.load_session(self.get_cookie('session_id'))
         path = self.request.path
         path_parts = list(filter(lambda s: s != '', path.split('/')))
         if len(path_parts) != 2:
             self.write(
                 json.dumps({
                     'success': False,
                     'error_message': lc.get('invalid_api_call')
                 }))
             return
         api_function = path_parts[-1]
         try:
             api.handle(api_function,
                        session=session,
                        args={'http_handler': self})
         except ApiKeyError:
             self.write(
                 json.dumps({
                     'success': False,
                     'error_message': lc.get('no_such_api_function')
                 }))
             return
         except BaseException as e:
             self.write(
                 json.dumps({
                     'success': False,
                     'error_message': lc.get(str(e))
                 }))
             logger.error('Exception occured while serving an API call: {}',
                          repr(e))
             print_exc()
             return
Beispiel #4
0
    def post(self):
        with locks.global_lock:
            session_id = self.get_cookie('session_id')
            session = auth.load_session(session_id)
            if session is None:
                self.redirect('/login')
                return

            old_password = self.get_argument('old_password', None)
            password = self.get_argument('password', None)
            password_c = self.get_argument('password_c', None)
            if old_password is None or old_password == '':
                self.write(
                    render_template(
                        'change_password_error.html',
                        error_message=lc.get('no_old_password'),
                        session=session,
                    ))
                return
            if not auth.verify_password(session.username, old_password):
                self.write(
                    render_template(
                        'change_password_error.html',
                        error_message=lc.get('invalid_old_password'),
                        session=session,
                    ))
                return
            if password is None or password == '':
                self.write(
                    render_template(
                        'change_password_error.html',
                        error_message=lc.get('no_password'),
                        session=session,
                    ))
                return
            if password != password_c:
                self.write(
                    render_template(
                        'change_password_error.html',
                        error_message=lc.get('password_c_failed'),
                        session=session,
                    ))
                return

            auth.update_password(session.username, password)
            self.write(
                render_template('change_password_ok.html', session=session))
Beispiel #5
0
def api_delete_group(api, sess, args):
    http = args['http_handler']
    request = json.loads(http.request.body)
    group_id = request['group_id']

    try:
        group_id = int(group_id)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='group_id',
            )
        )
    logger.info("Deleting group ({})", group_id)
    delete_group(group_id)

    http.write(json.dumps({'success': True}))
Beispiel #6
0
def api_get_task(api, sess, args):
    http = args['http_handler']
    request = json.loads(http.request.body)
    task_id = request['task_id']

    try:
        task_id = int(task_id)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='task_id',
            )
        )
    try:
        task = read_task(task_id)
    except TaskNotFoundError:
        raise Exception(lc.get('task_does_not_exist').format(task_id=task_id))

    http.write(json.dumps({'success': True, 'task': task.to_dict()}))
Beispiel #7
0
 def get(self):
     with locks.global_lock:
         session_id = self.get_cookie('session_id')
         if auth.load_session(session_id) is None:
             self.write(
                 render_template('auth_error.html',
                                 error=lc.get('logout_no_session')))
             return
         auth.logout(session_id)
         self.clear_cookie('session_id')
         self.redirect('/')
Beispiel #8
0
    def get(self):
        with locks.global_lock:
            session_id = self.get_cookie('session_id')
            session = auth.load_session(session_id)
            if session is None or not session.is_admin:
                self.write(
                    render_template('admin_error.html',
                                    error=lc.get('not_admin')))
                return

            self.write(render_template('admin_new_team.html', session=session))
Beispiel #9
0
 def get(self):
     with locks.global_lock:
         session_id = self.get_cookie('session_id')
         if auth.load_session(session_id) is not None:
             self.redirect('/')
             return
         if not competition.allow_team_self_registration:
             self.write(
                 render_template('reg_error.html',
                                 error=lc.get('registration_disabled')))
             return
         self.write(render_template('register.html'))
Beispiel #10
0
def api_delete_task(api, sess, args):
    http = args['http_handler']
    request = json.loads(http.request.body)
    task_id = request['task_id']

    try:
        task_id = int(task_id)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='task_id',
            )
        )
    try:
        logger.info("Deleting task with id {}", task_id)
        delete_task(task_id)
    except TaskNotFoundError:
        raise Exception(lc.get('task_does_not_exist').format(task_id=task_id))

    http.write(json.dumps({'success': True}))
Beispiel #11
0
def api_access_hint(api, sess, args):
    http = args['http_handler']
    request = json.loads(http.request.body)
    task_id    = request['task_id']
    hint_hexid = request['hint_hexid']
    team_name  = sess.username

    if not competition.is_running() and not sess.is_admin:
        raise Exception(lc.get('competition_is_not_running'))

    try:
        task_id = int(task_id)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='task_id',
            )
        )

    hint = access_hint(task_id=task_id, hint_hexid=hint_hexid, team_name=team_name)
    http.write(json.dumps({'success': True, 'hint': hint}))
Beispiel #12
0
def api_update_group_seed(api, sess, args):
    http     = args['http_handler']
    request  = json.loads(http.request.body)
    group_id = request['group_id']
    seed     = request['new_seed']
    try:
        group_id = int(group_id)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='group_id',
            )
        )
    if (type(seed) is not str or len(seed) != 16) and seed != 'inherit':
        raise ApiArgumentError(lc.get('api_argument_error').format(argument='seed'))
    group = read_group(group_id)
    group['seed'] = seed
    get_group_seed(group)
    write_group(group_id, group)

    http.write(json.dumps({'success': True}))
Beispiel #13
0
def api_submit_flag(api, sess, args):
    http = args['http_handler']
    request = json.loads(http.request.body)
    task_id = request['task_id']
    flag_data = request['flag']

    if not competition.is_running() and not sess.is_admin:
        raise Exception(lc.get('competition_is_not_running'))

    try:
        task_id = int(task_id)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='task_id',
            )
        )

    cteam = team.read_team(sess.username)
    token = task_gen.get_token(sess.username, task_id)

    try:
        task = task_gen.get_generated_task(task_id, token, cteam)
    except TaskNotFoundError:
        raise Exception(lc.get('task_does_not_exist').format(task_id=task_id))

    try:
        correct = bool(task.check_flag(flag_data, team_name=sess.username))
    except TooFrequentSubmissions:
        logger.warning('Too frequent submissions from team {} for task with ID {}', sess.username, task_id)
        http.write(json.dumps({
            'success': False,
            'error_message': lc.get('task_submission_too_frequent').format(
                time=configuration['min_submission_interval']
            )
        }))
        return

    try:
        team.add_submission(
            team_name = sess.username,
            task_id = task_id,
            flag = flag_data,
            is_correct = correct,
            points = task.value if correct else 0,
        )
    except team.TaskAlreadySolved:
        logger.warning('Team {} submitted a flag for already solved task with ID {}', sess.username, task_id)
        http.write(json.dumps({'success': False, 'error_message': lc.get('task_already_solved')}))
        return


    logger.info('Flag submission from team {} for task with ID {} - {}'.format(
        sess.username,
        task_id,
        'correct' if correct else 'wrong'
    ))
    http.write(json.dumps({'success': True, 'flag_correct': correct}))
Beispiel #14
0
def api_reparent_group(api, sess, args):
    http     = args['http_handler']
    request  = json.loads(http.request.body)
    group_id = request['group_id']
    new_parent = request['new_parent']
    try:
        new_parent = int(new_parent)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='new_parent',
            )
        )

    if may_reparent_group(group_id, new_parent):
        logger.info('Reparenting group ({}): new parent: ({})', group_id, new_parent)
        reparent_group(group_id, new_parent)
    else:
        logger.warning('Cannot reparent group ({}): new parent: ({})', group_id, new_parent)
        raise GroupReparentError()

    http.write(json.dumps({'success': True}))
Beispiel #15
0
 def handle(self, name, session, args=None):
     if session is None:
         access_level = GUEST
     elif session.is_admin:
         access_level = ADMIN
     else:
         access_level = USER
     try:
         required_access_level, func = self.handlers[name]
     except KeyError:
         raise ApiKeyError(name)
     if access_level < required_access_level:
         raise ApiPermissionError(
             lc.get('api_call_not_allowed').format(api_func=name))
     func(self, session, args)
Beispiel #16
0
def api_rename_group(api, sess, args):
    http     = args['http_handler']
    request  = json.loads(http.request.body)
    group_id = request['group_id']
    new_name = request['new_name']
    try:
        group_id = int(group_id)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='group_id',
            )
        )

    if new_name == '':
        raise EmptyGroupNameError()

    logger.info('Renaming group ({}) to {}', group_id, new_name)
    group = read_group(group_id)
    group['name'] = new_name

    write_group(group_id, group)
    http.write(json.dumps({'success': True}))
Beispiel #17
0
    def post(self):
        with locks.global_lock:
            if not competition.allow_team_self_registration:
                self.write(
                    render_template('reg_error.html',
                                    error=lc.get('registration_disabled')))
            username = self.get_argument('username', None)
            password = self.get_argument('password', None)
            password_c = self.get_argument('password-c', None)
            disp_name = self.get_argument('disp-name', None)
            email = self.get_argument('email', None)

            if username is None or username == '':
                self.write(
                    render_template('reg_error.html',
                                    error=lc.get('no_username')))
                return
            if password is None or password == '':
                self.write(
                    render_template('reg_error.html',
                                    error=lc.get('no_password')))
                return
            if password != password_c:
                self.write(
                    render_template('reg_error.html',
                                    error=lc.get('password_c_failed')))
                return
            if disp_name is None or disp_name == '':
                self.write(
                    render_template('reg_error.html',
                                    error=lc.get('no_disp_name')))
                return
            if username in auth.get_user_list():
                self.write(
                    render_template('reg_error.html',
                                    error=lc.get('user_already_exists')))
                return

            try:
                auth.register_user(username=username,
                                   password=password,
                                   disp_name=disp_name,
                                   email=email)
            except auth.BaseRegistrationError as e:
                self.write(
                    render_template('reg_error.html', error=lc.get(e.text)))
                return
            self.redirect('/')
Beispiel #18
0
 def get(self):
     with locks.global_lock:
         session = auth.load_session(self.get_cookie('session_id'))
         submissions = team.get_all_submissions()
         if session is None or not session.is_admin:
             self.write(
                 render_template('admin_error.html',
                                 error=lc.get('not_admin')))
             return
         self.write(
             render_template(
                 'admin.html',
                 session=session,
                 tasks=list(tasks.get_task_list()),
                 submissions=list(submissions),
                 teams=list(team.get_all_teams()),
                 groups=dict(tasks.get_group_dict()),
                 read_task=tasks.read_task,
                 build_group_path=tasks.build_group_path,
                 task_gen=task_gen,
             ))
Beispiel #19
0
    def post(self):
        with locks.global_lock:
            session_id = self.get_cookie('session_id')
            session = auth.load_session(session_id)
            if session is None:
                self.redirect('/login')
                return

            disp_name = self.get_argument('disp_name', None)
            email = self.get_argument('email', None)
            if disp_name is None or disp_name == '':
                self.write(
                    render_template(
                        'edit_team_info_error.html',
                        error_message=lc.get('no_disp_name'),
                        session=session,
                    ))
                return
            tm = team.read_team(session.username)
            tm.full_name = disp_name
            tm.email = email if email != '' else None
            team.write_team(tm)
            self.write(
                render_template('edit_team_info_ok.html', session=session))
Beispiel #20
0
    def post(self):
        with locks.global_lock:
            session_id = self.get_cookie('session_id')
            session = auth.load_session(session_id)
            if session is None or not session.is_admin:
                self.write(
                    render_template('admin_error.html',
                                    error=lc.get('not_admin')))
                return
            username = self.get_argument('username', None)
            password = self.get_argument('password', None)
            password_c = self.get_argument('password-c', None)
            disp_name = self.get_argument('disp-name', None)
            email = self.get_argument('email', None)
            is_admin = self.get_argument('is_admin', None)

            if is_admin is not None and is_admin not in ['on', 'off']:
                self.write(
                    render_template(
                        'reg_error.html',
                        error=lc.get('api_invalid_data_type').format(
                            param='is_admin',
                            expected=lc.get('bool'),
                        )))
                return
            if is_admin == 'on':
                is_admin = True
            else:
                is_admin = False

            if username is None or username == '':
                self.write(
                    render_template('reg_error.html',
                                    error=lc.get('no_username')))
                return
            if password is None or password == '':
                self.write(
                    render_template('reg_error.html',
                                    error=lc.get('no_password')))
                return
            if disp_name is None or disp_name == '':
                self.write(
                    render_template('reg_error.html',
                                    error=lc.get('no_disp_name')))
                return
            if password != password_c:
                self.write(
                    render_template('reg_error.html',
                                    error=lc.get('password_c_failed')))
                return
            if username in auth.get_user_list():
                self.write(
                    render_template('reg_error.html',
                                    error=lc.get('user_already_exists')))
                return

            try:
                auth.register_user(
                    username=username,
                    password=password,
                    disp_name=disp_name,
                    email=email,
                    is_admin=is_admin,
                )
            except auth.BaseRegistrationError as e:
                self.write(
                    render_template('reg_error.html', error=lc.get(e.text)))
                return
            self.redirect('/admin')
Beispiel #21
0
def api_add_or_update_task(api, sess, args):
    http = args['http_handler']
    request = json.loads(http.request.body)
    task_id = request['task_id']
    text    = request['text']
    title   = request['title']
    value   = request['value']
    labels  = request['labels']
    flags   = request['flags']
    group   = request['group']
    order   = request['order']
    seed    = request['seed']
    hints   = request['hints']

    if task_id is None or task_id == '':
        task_id = allocate_task_id()

    try:
        task_id = int(task_id)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='task_id',
            )
        )

    try:
        value = int(value)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='value',
            )
        )

    try:
        group = int(group)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='group',
            )
        )

    try:
        order = int(order)
    except (ValueError, TypeError) as e:
        raise Exception(
            lc.get('api_invalid_data_type').format(
                expected=lc.get('int'),
                param='order',
            )
        )

    if (type(seed) is not str or len(seed) != 16) and seed != 'inherit':
        raise Exception(
            lc.get('api_argument_error').format(
                argument='seed',
            )
        )

    if title == '':
        raise EmptyTaskNameError()

    if task_exists(task_id):
        logger.info('Modifying task {}', task_id)
        task = read_task(task_id)
        task.text = text
        task.title = title
        task.value = value
        task.labels = labels
        task.flags = flags
        task.group = group
        task.order = order
        task.seed = seed
        task.hints = hints
        task.validate()
        write_task(task)
    else:
        logger.info('Creating task {}', task_id)
        try:
            task = Task(
                task_id,
                {
                    'title':  title,
                    'text':   text,
                    'value':  value,
                    'labels': labels,
                    'flags':  flags,
                    'group':  group,
                    'order':  order,
                    'seed':   seed,
                    'hints':  hints,
                }
            )
            task.validate()
        except KeyError as e:
            raise ApiArgumentError(lc.get('api_argument_error').format(argument=str(e)))
        write_task(task)
    http.write(json.dumps({'success': True}))