예제 #1
0
function processCreateDataBaseRequest($request)
{
    //test if creation is necessary
    if (in_array(DB_PREFIX . "user", Data::getTables())) {
        throwBusinessLogicError(13);
    }
    //read queries from file
    $lines = @file_get_contents("utils/dces-create-db.sql") or throwServerProblem(64);
    //remove # comments
    $lines = preg_replace("/^\\s*#.*\$/m", "", $lines);
    //remove /*! ... */ comments
    $lines = preg_replace('/\\/\\*!\\d+.*\\*\\//', "", $lines);
    //replace PREFIX_ with real prefix
    $lines = preg_replace('/PREFIX_/', DB_PREFIX, $lines);
    //split requests by ;
    $requests = preg_split('/\\s*;\\s*$/m', $lines);
    foreach ($requests as $r) {
        if (trim($r) !== "") {
            Data::submitModificationQuery($r);
        }
    }
    $col_value = array('login' => $request->login, 'password' => $request->password, 'user_data' => serialize(array()), 'contest_id' => 0, 'user_type' => 'SuperAdmin');
    Data::submitModificationQuery(Data::composeInsertQuery('user', $col_value));
    return new AcceptedResponse();
}
예제 #2
0
function processAdjustPluginRequest($request)
{
    $prfx = DB_PREFIX;
    $user_row = RequestUtils::testSession($request->sessionID);
    //authorize
    if ($user_row['user_type'] !== 'SuperAdmin') {
        throwBusinessLogicError(0);
    }
    //test plugin alias
    if (preg_match('/^[\\p{L}0-9 ]+$/', $request->pluginAlias) === 0) {
        throwBusinessLogicError(238);
    }
    $plugin_type = $request->side === 'Client' ? 'client' : 'server';
    //test if there already is such plugin
    $where_clause = sprintf("alias=%s", Data::quote_smart($request->pluginAlias));
    $plugin_row = Data::getRow("SELECT * FROM {$prfx}{$plugin_type}_plugin WHERE {$where_clause}");
    if ($plugin_row) {
        $modify = true;
    } else {
        $modify = false;
    }
    //test all parameters specified
    if (!$modify && is_null($request->description)) {
        $request->description = "";
    }
    if (!$modify && (is_null($request->pluginData) || is_null($request->description))) {
        throwBusinessLogicError(1);
    }
    //TODO test pluginAlias to be secure
    if ($plugin_type === 'client') {
        $ext = '.jar';
    } else {
        $ext = '.php';
    }
    //set file data
    if (!is_null($request->pluginData)) {
        file_put_contents($GLOBALS["dces_dir_{$plugin_type}_plugins"] . '/' . $request->pluginAlias . $ext, $request->pluginData);
    }
    //prepare set plugin description
    $col_value = array();
    if (!is_null($request->description)) {
        $col_value['description'] = $request->description;
    }
    if ($modify) {
        $query = Data::composeUpdateQuery("{$plugin_type}_plugin", $col_value, $where_clause);
    } else {
        $col_value['alias'] = $request->pluginAlias;
        $query = Data::composeInsertQuery("{$plugin_type}_plugin", $col_value);
    }
    Data::submitModificationQuery($query);
    return new AcceptedResponse();
}
예제 #3
0
function processCreateContestRequest($request)
{
    //get user_id or die, if session is invalid
    $user_row = RequestUtils::testSession($request->sessionID);
    //authorize user for this operation
    $user_type = $user_row['user_type'];
    if ($user_type !== 'SuperAdmin') {
        throwBusinessLogicError(0);
    }
    unset($request->contest->contestID);
    RequestUtils::assertContestSettingsIntegrity($request->contest);
    $col_value = array('settings' => serialize($request->contest));
    Data::submitModificationQuery(Data::composeInsertQuery('contest', $col_value));
    Data::execPendingQueries();
    $id = Data::getInsertedID();
    $ccr = new CreateContestResponse();
    $ccr->createdContestID = $id;
    return $ccr;
}
예제 #4
0
function processSubmitSolutionRequest($request)
{
    $prfx = DB_PREFIX;
    //get user_id or die, if session is invalid
    $userRow = RequestUtils::testSession($request->sessionID);
    $user_id = $userRow['id'];
    //authorize user for this operation
    // get contest ID
    $user_type = $userRow['user_type'];
    //get problem row
    $problem_row = Data::getRow(sprintf("SELECT * FROM {$prfx}problem WHERE id=%s", Data::quote_smart($request->problemID)));
    if (!$problem_row) {
        throwBusinessLogicError(4);
    }
    //get contest id of a problem
    $problem_contest_id = $problem_row['contest_id'];
    //test if we have rights to submit solution for the contest
    $contest_id = RequestUtils::getRequestedContest($problem_contest_id, $userRow['contest_id'], $user_type);
    if ($contest_id < 0) {
        throwBusinessLogicError(0);
    }
    //get all settings
    $contest_settings = Data::_unserialize($userRow['settings']);
    //test submission time
    $cur_time = getCurrentContestTime($contest_settings, DateMySQLToPHP($userRow['contest_start']), DateMySQLToPHP($userRow['contest_finish']));
    if ($cur_time['interval'] === 'before') {
        throwBusinessLogicError(19);
    }
    if ($cur_time['interval'] === 'after') {
        throwBusinessLogicError(20);
    }
    $problem_settings = Data::_unserialize($problem_row['contest_settings']);
    //test that not all submission attempts were used
    $hist = Data::getRow(sprintf("SELECT COUNT(*) AS cnt FROM {$prfx}submission_history WHERE (problem_id=%s) AND (user_id=%s)", Data::quote_smart($request->problemID), Data::quote_smart($user_id)));
    if ($hist >= getSetting($contest_settings->problemsDefaultSettings->sendCount, $problem_settings->sendCount)) {
        throwBusinessLogicError(21);
    }
    //save submission result in history
    $cur_php_time = getdate();
    $col_value = array();
    $col_value['problem_id'] = $request->problemID;
    $col_value['user_id'] = $user_id;
    $col_value['submission'] = serialize($request->problemResult);
    $col_value['result'] = null;
    //serialize($check_result);
    $col_value['submission_time'] = DatePHPToMySQL($cur_php_time[0]);
    //TODO implement asynchronous plugin
    //get problem and create plugin
    $problem = new Problem(getProblemFile($request->problemID));
    $plugin_alias = $problem->getServerPlugin();
    require_once getServerPluginFile();
    require_once getServerPluginFile($plugin_alias);
    $plugin = new $plugin_alias($problem);
    //check solution
    $last_result = $plugin->checkSolution(Data::getInsertedID(), $request->problemResult);
    $col_value['result'] = serialize($last_result);
    Data::submitModificationQuery(Data::composeInsertQuery('submission_history', $col_value));
    //get result for result table and store in user
    $all_results = Data::_unserialize($userRow['results']);
    $user_result = ResultUtils::getUserResults($user_id, $request->problemID, getSetting($contest_settings->problemsDefaultSettings->tableResultChoice, $problem_settings->tableResultChoice), getSetting($contest_settings->problemsDefaultSettings->resultTransition, $problem_settings->resultTransition), $plugin, $last_result);
    //update user result for results table
    $all_results[$request->problemID] = $user_result;
    Data::submitModificationQuery(Data::composeUpdateQuery('user', array('results' => serialize($all_results)), 'id=' . Data::quote_smart($user_id)));
    //return submission result
    $res = new AcceptedResponse();
    return $res;
}
예제 #5
0
/**
 * creates queries to change problem set
 * @param $problems new problems
 * @param $contest_id contest id
 * @return array() list of temporary files. NULL if the existing file was used
 */
function queriesToAdjustProblems($problems, $contest_id)
{
    $prfx = DB_PREFIX;
    $changed_probs = array();
    //problems that will be changed by request
    $temp_probs = array();
    //find all contest problems
    $prob2settings = array();
    $res = Data::getRows(sprintf("SELECT * FROM {$prfx}problem WHERE contest_id=%s", Data::quote_smart($contest_id)));
    while ($row = Data::getNextRow($res)) {
        $prob2settings[$row['id']] = Data::_unserialize($row['contest_settings']);
    }
    $contest_pos = 1;
    foreach ($problems as $p) {
        $col_value = array();
        //new problem must have 1) data 2) settings
        //set contest id
        $col_value['contest_id'] = $contest_id;
        $col_value['contest_pos'] = $contest_pos++;
        if ($p->id != -1 && !isset($prob2settings[$p->id])) {
            throwBusinessLogicError(4);
        }
        //find problem file or make temporary if a new problem was sent
        if ($p->problem) {
            $problem_file = getTemporaryProblemFile();
            @file_put_contents($problem_file, $p->problem) or throwServerProblem(200, 'failed to write problem file: ' . $problem_file);
            $temp_probs[] = $problem_file;
        } else {
            if ($p->id < 0) {
                throwBusinessLogicError(1);
            }
            $problem_file = getProblemFile($p->id);
            $temp_probs[] = NULL;
        }
        $problem = new Problem($problem_file);
        //get server plugin
        //TODO improve security here
        $plugin_alias = $problem->getServerPlugin();
        require_once getServerPluginFile($plugin_alias);
        $plugin = new $plugin_alias($problem);
        //TODO consider calling updaters here instead of manual insertion of values
        //TODO recheck all values if new plugin specified
        $col_value['checker_columns'] = serialize($plugin->getColumnNames());
        $col_value['result_columns'] = serialize(array());
        //copy per contest settings
        if ($p->settings) {
            if ($p->id != -1) {
                $new_settings = $prob2settings[$p->id];
                copyValues($p->settings, $new_settings);
            } else {
                $new_settings = $p->settings;
            }
            $col_value['contest_settings'] = serialize($new_settings);
        } else {
            if ($p->id < 0) {
                throwBusinessLogicError(1);
            }
        }
        //query depends on whether we add or change a problem
        if ($p->id == -1) {
            Data::submitModificationQuery(Data::composeInsertQuery('problem', $col_value));
        } else {
            Data::submitModificationQuery(Data::composeUpdateQuery('problem', $col_value, "id='{$p->id}'"));
            $changed_probs[$p->id] = 1;
        }
    }
    //delete extra problems
    foreach (array_keys($prob2settings) as $id) {
        if (!isset($changed_probs[$id])) {
            Data::submitModificationQuery("DELETE FROM {$prfx}problem WHERE id='{$id}'");
        }
    }
    return $temp_probs;
}
예제 #6
0
function processRegisterToContestRequest($request)
{
    $prfx = DB_PREFIX;
    //get user_id or die, if session is invalid
    if (is_null($request->sessionID)) {
        if (!is_numeric($request->contestID)) {
            throwBusinessLogicError(14);
        }
        $contest_id = (int) $request->contestID;
        $request_user_type = '__Anonymous';
    } else {
        $userRow = RequestUtils::testSession($request->sessionID);
        $request_user_id = $userRow['id'];
        $request_user_type = $userRow['user_type'];
        $contest_id = RequestUtils::getRequestedContest($request->contestID, $userRow['contest_id'], $request_user_type);
        //make possible for superadmin to register users of zero-contest
        if ($request_user_type == 'SuperAdmin' && ($request->contestID == 0 || $request->contestID == -1)) {
            $contest_id = 0;
        }
        if ($contest_id == -1) {
            throwBusinessLogicError(0);
        }
    }
    //test permissions
    if ($contest_id != 0) {
        $contest_row = Data::getRow(sprintf("SELECT * FROM {$prfx}contest WHERE id=%s", Data::quote_smart($contest_id))) or throwBusinessLogicError(14);
        //test if this contest gets users only by admins
        $contest_settings = @unserialize($contest_row['settings']);
        if ($contest_settings->registrationType === 'ByAdmins') {
            if ($request_user_type !== "ContestAdmin" && $request_user_type !== "SuperAdmin") {
                throwBusinessLogicError(0);
            }
        }
    } else {
        if ($request_user_type !== "ContestAdmin") {
            throwBusinessLogicError(0);
        }
    }
    //get user from request
    $u = $request->user;
    //test that superadmins are registered only for 0 contest
    if ($u->userType === 'SuperAdmin' && $contest_id != 0) {
        throwBusinessLogicError(18);
    }
    //test that there is no user with the same login in this contest
    if (Data::hasRows(sprintf("SELECT * FROM {$prfx}user WHERE contest_id=%s AND login=%s", Data::quote_smart($contest_id), Data::quote_smart($u->login)))) {
        throwBusinessLogicError(14);
    }
    //not participants may be added only by admins
    if ($u->userType !== "Participant") {
        if ($request_user_type !== "ContestAdmin" && $request_user_type !== "SuperAdmin") {
            throwBusinessLogicError(0);
        }
    }
    //add user finally
    $col_value = array();
    $col_value['login'] = $u->login;
    $col_value['password'] = $u->password;
    $col_value['user_data'] = @serialize($u->dataValue);
    $col_value['contest_id'] = $contest_id;
    $col_value['user_type'] = $u->userType;
    $col_value['results'] = @serialize(array());
    if (strlen($u->login) == 0) {
        throwBusinessLogicError(22);
    }
    if (week_password($u->password)) {
        throwBusinessLogicError(23);
    }
    Data::submitModificationQuery(Data::composeInsertQuery('user', $col_value));
    return new AcceptedResponse();
}