diff --git a/web/app/controllers/blog_show.php b/web/app/controllers/blog_show.php index 9b1918e..641e624 100644 --- a/web/app/controllers/blog_show.php +++ b/web/app/controllers/blog_show.php @@ -11,5 +11,5 @@ become404Page(); } - redirectTo(HTML::blog_url($blog['poster'], '/post/'.$_GET['id'])); + redirectTo(HTML::blog_url($blog['poster'], '/post/'.$_GET['id'] . ($_GET['sub'] ?: ''))); ?> diff --git a/web/app/controllers/super_manage.php b/web/app/controllers/super_manage.php index d1e9956..11186ab 100644 --- a/web/app/controllers/super_manage.php +++ b/web/app/controllers/super_manage.php @@ -1,867 +1,1169 @@ ;window.location = window.location.origin + window.location.pathname + (window.location.search.length ? window.location.search + "&" : "?") + "_=" + (+new Date()) + window.location.hash;'); + + if (!Auth::check()) { + redirectToLogin(); + } + if (!isSuperUser($myUser)) { become403Page(); } - $register_form = new UOJForm('register'); - $register_form->submit_button_config['align'] = 'compressed'; - $register_form->addInput('new_username', 'text', '用户名', '', - function ($new_username) { - if (!validateUsername($new_username)) { - return '用户名不合法'; - } - if (queryUser($new_username)) { - return '该用户已存在'; - } - return ''; - }, - null - ); - $register_form->addInput('new_password', 'password', '密码', '', - function ($new_password) { - return ''; - }, - null - ); - $register_form->addInput('new_realname', 'text', '真实姓名', '', - function ($new_realname) { - return ''; - }, - null - ); - $register_form->addInput('new_school', 'text', '学校名称', '', - function ($new_school) { - return ''; - }, - null - ); - $register_form->handle = function() { - $new_username = $_POST['new_username']; - $new_password = $_POST['new_password']; - $new_realname = DB::escape($_POST['new_realname']); - $new_school = DB::escape($_POST['new_school']); - $new_password = hash_hmac('md5', $new_password, getPasswordClientSalt()); - $new_password = getPasswordToStore($new_password, $new_username); - $svn_pw = uojRandString(10); + $cur_tab = isset($_GET['tab']) ? $_GET['tab'] : 'index'; - DB::query("insert into user_info (username, realname, school, password, svn_password, register_time, usergroup) values ('$new_username', '$new_realname', '$new_school', '$new_password', '$svn_pw', now(), 'U')"); - }; - $register_form->runAtServer(); - - $change_password_form = new UOJForm('change_password'); - $change_password_form->submit_button_config['align'] = 'compressed'; - $change_password_form->addInput('p_username', 'text', '用户名', '', - function ($p_username) { - if (!validateUsername($p_username)) { - return '用户名不合法'; - } - if (!queryUser($p_username)) { - return '用户不存在'; - } - return ''; - }, - null - ); - $change_password_form->addInput('p_password', 'password', '密码', '', - function ($p_password) { - return ''; - }, - null - ); - $change_password_form->handle = function() { - $p_username = $_POST['p_username']; - $p_password = $_POST['p_password']; - $p_password = hash_hmac('md5', $p_password, getPasswordClientSalt()); - $p_password = getPasswordToStore($p_password, $p_username); - - DB::query("update user_info set password = '$p_password' where username = '$p_username'"); - }; - $change_password_form->runAtServer(); - - $change_realname_form = new UOJForm('change_realname'); - $change_realname_form->submit_button_config['align'] = 'compressed'; - $change_realname_form->addInput('r_username', 'text', '用户名', '', - function ($r_username) { - if (!validateUsername($r_username)) { - return '用户名不合法'; - } - if (!queryUser($r_username)) { - return '用户不存在'; - } - return ''; - }, - null - ); - $change_realname_form->addInput('r_realname', 'text', '真实姓名', '', - function ($r_realname) { - return ''; - }, - null - ); - $change_realname_form->handle = function() { - $r_username = $_POST['r_username']; - $r_realname = DB::escape($_POST['r_realname']); - - DB::query("update user_info set realname = '$r_realname' where username = '$r_username'"); - }; - $change_realname_form->runAtServer(); - - $change_school_form = new UOJForm('change_school'); - $change_school_form->submit_button_config['align'] = 'compressed'; - $change_school_form->addInput('s_username', 'text', '用户名', '', - function ($s_username) { - if (!validateUsername($s_username)) { - return '用户名不合法'; - } - if (!queryUser($s_username)) { - return '用户不存在'; - } - return ''; - }, - null - ); - $change_school_form->addInput('s_school', 'text', '学校名称', '', - function ($s_school) { - return ''; - }, - null - ); - $change_school_form->handle = function() { - $s_username = $_POST['s_username']; - $s_school = DB::escape($_POST['s_school']); - - DB::query("update user_info set school = '$s_school' where username = '$s_username'"); - }; - $change_school_form->runAtServer(); - - $user_form = new UOJForm('user'); - $user_form->submit_button_config['align'] = 'compressed'; - $user_form->addInput('username', 'text', '用户名', '', - function ($username) { - if (!validateUsername($username)) { - return '用户名不合法'; - } - if (!queryUser($username)) { - return '用户不存在'; - } - return ''; - }, - null - ); - $options = array( - 'banneduser' => '设为封禁用户', - 'normaluser' => '设为普通用户', - 'superuser' => '设为超级用户' - ); - $user_form->addSelect('op_type', $options, '操作类型', ''); - $user_form->handle = function() { - global $user_form; - - $username = $_POST['username']; - switch ($_POST['op_type']) { - case 'banneduser': - DB::update("update user_info set usergroup = 'B' where username = '{$username}'"); - DB::update("update user_info set usertype = 'banned' where username = '{$username}'"); - break; - case 'normaluser': - DB::update("update user_info set usergroup = 'U' where username = '{$username}'"); - DB::update("update user_info set usertype = 'student' where username = '{$username}'"); - break; - case 'superuser': - DB::update("update user_info set usergroup = 'S' where username = '{$username}'"); - DB::update("update user_info set usertype = 'student' where username = '{$username}'"); - break; - } - }; - $user_form->runAtServer(); - - $usertype_form = new UOJForm('usertype'); - $user_form->submit_button_config['align'] = 'compressed'; - $usertype_form->addInput('usertype_username', 'text', '用户名', '', - function ($username) { - if (!validateUsername($username)) { - return '用户名不合法'; - } - if (!queryUser($username)) { - return '用户不存在'; - } - return ''; - }, - null - ); - $usertype_options = array( - 'student' => '学生', - 'teacher' => '老师', - 'problem_uploader' => '题目上传者', - 'problem_manager' => '题目管理员', - 'contest_judger' => '比赛评测员', - 'contest_only' => '仅比赛参加者', - ); - $usertype_form->addSelect('usertype_type', $usertype_options, '角色', ''); - $usertype_form->addSelect('usertype_op', array('add' => '添加', 'remove' => '移除'), '操作', ''); - $usertype_form->handle = function() { - global $usertype_form; - - $username = $_POST['usertype_username']; - $user = queryUser($username); - switch ($_POST['usertype_type']) { - case 'teacher': - if ($_POST['usertype_op'] === 'add') { - $user = addUserType($user, 'teacher'); - $user = removeUserType($user, 'student'); - } else { - $user = removeUserType($user, 'teacher'); - $user = addUserType($user, 'student'); - } - break; - case 'problem_manager': - if ($_POST['usertype_op'] === 'add') { - $user = addUserType($user, 'problem_manager'); - $user = removeUserType($user, 'problem_uploader'); - } else { - $user = removeUserType($user, 'problem_manager'); - } - break; - case 'student': - case 'problem_uploader': - case 'contest_judger': - case 'contest_only': - $user = $_POST['usertype_op'] === 'add' - ? addUserType($user, $_POST['usertype_type']) - : removeUserType($user, $_POST['usertype_type']); - break; - } - - DB::update("update user_info set usertype = '{$user['usertype']}' where username = '{$username}'"); - }; - $usertype_form->runAtServer(); + $tabs_info = [ + 'index' => [ + 'name' => '首页管理', + 'url' => "/super_manage/index", + ], + 'users' => [ + 'name' => '用户管理', + 'url' => "/super_manage/users", + ], + 'submissions' => [ + 'name' => '提交记录', + 'url' => "/super_manage/submissions", + ], + 'custom_test' => [ + 'name' => '自定义测试', + 'url' => "/super_manage/custom_test", + ], + 'judger' => [ + 'name' => '评测机管理', + 'url' => "/super_manage/judger", + ], + 'image_hosting' => [ + 'name' => '图床管理', + 'url' => "/super_manage/image_hosting", + ], + ]; - $blog_link_index = new UOJForm('blog_link_index'); - $blog_link_index->addInput('blog_id2', 'text', '博客ID', '', - function ($x) { - if (!validateUInt($x)) { - return 'ID不合法'; + if (!isset($tabs_info[$cur_tab])) { + become404Page(); + } + + if ($cur_tab == 'index') { + // ========== 公告 ========== + if (isset($_POST['submit-delete_announcement']) && $_POST['submit-delete_announcement'] == 'delete_announcement') { + crsf_defend(); + + $blog_id = $_POST['blog_id']; + + if (!validateUInt($blog_id)) { + die('' . SCRIPT_REFRESH_AS_GET); } - if (!queryBlog($x)) { - return '博客不存在'; - } - return ''; - }, - null - ); - $blog_link_index->addInput('blog_level', 'text', '置顶级别(删除不用填)', '0', - function ($x) { - if (!validateUInt($x)) { - return '数字不合法'; - } - if ($x > 3) { - return '该级别不存在'; - } - return ''; - }, - null - ); - $options = array( - 'add' => '添加', - 'del' => '删除' - ); - $blog_link_index->addSelect('op-type2', $options, '操作类型', ''); - $blog_link_index->handle = function() { - $blog_id = $_POST['blog_id2']; - $blog_level = $_POST['blog_level']; - if ($_POST['op-type2'] == 'add') { + + DB::delete("DELETE FROM important_blogs WHERE blog_id = {$blog_id}"); + + die('' . SCRIPT_REFRESH_AS_GET); + } + + $announcements = DB::selectAll("SELECT blogs.id as id, blogs.title as title, blogs.poster as poster, user_info.realname as realname, blogs.post_time as post_time, important_blogs.level as level, blogs.is_hidden as is_hidden FROM important_blogs INNER JOIN blogs ON important_blogs.blog_id = blogs.id INNER JOIN user_info ON blogs.poster = user_info.username ORDER BY level DESC, important_blogs.blog_id DESC"); + + $add_announcement_form = new UOJForm('add_announcement'); + $add_announcement_form->addInput('blog_id', 'text', '博客 ID', '', + function($id, &$vdata) { + if (!validateUInt($id)) { + return '博客 ID 无效'; + } + + if (!queryBlog($id)) { + return '博客不存在'; + } + + $vdata['blog_id'] = $id; + + return ''; + }, + null + ); + $add_announcement_form->addInput('blog_level', 'text', '置顶级别', '0', + function ($x, &$vdata) { + if (!validateUInt($x)) { + return '数字不合法'; + } + + if ($x > 3) { + return '该级别不存在'; + } + + $vdata['level'] = $x; + + return ''; + }, + null + ); + $add_announcement_form->handle = function(&$vdata) { + $blog_id = $vdata['blog_id']; + $blog_level = $vdata['level']; + if (DB::selectFirst("select * from important_blogs where blog_id = {$blog_id}")) { DB::update("update important_blogs set level = {$blog_level} where blog_id = {$blog_id}"); } else { DB::insert("insert into important_blogs (blog_id, level) values ({$blog_id}, {$blog_level})"); } + }; + $add_announcement_form->submit_button_config['align'] = 'compressed'; + $add_announcement_form->submit_button_config['text'] = '提交'; + $add_announcement_form->succ_href = '/super_manage/index#announcements'; + $add_announcement_form->runAtServer(); + + // ========== 倒计时 ========== + if (isset($_POST['submit-delete_countdown']) && $_POST['submit-delete_countdown'] == 'delete_countdown') { + crsf_defend(); + + $countdown_id = $_POST['countdown_id']; + + if (!validateUInt($countdown_id)) { + die('' . SCRIPT_REFRESH_AS_GET); + } + + DB::delete("DELETE FROM countdowns WHERE id = {$countdown_id}"); + + die('' . SCRIPT_REFRESH_AS_GET); } - if ($_POST['op-type2'] == 'del') { - DB::delete("delete from important_blogs where blog_id = {$blog_id}"); + + $countdowns = DB::selectAll("SELECT id, title, endtime FROM countdowns ORDER BY endtime ASC"); + + $add_countdown_form = new UOJForm('add_countdown'); + $add_countdown_form->addInput('countdown_title', 'text', '标题', '', + function($title, &$vdata) { + if ($title == '') { + return '标题不能为空'; + } + + $vdata['title'] = $title; + + return ''; + }, + null + ); + $add_countdown_form->addInput('countdown_endtime', 'text', '结束时间', date("Y-m-d H:i:s"), + function($endtime, &$vdata) { + try { + $vdata['endtime'] = new DateTime($endtime); + } catch (Exception $e) { + return '无效时间格式'; + } + + return ''; + }, + null + ); + $add_countdown_form->handle = function(&$vdata) { + $esc_title = DB::escape($vdata['title']); + $esc_endtime = DB::escape($vdata['endtime']->format('Y-m-d H:i:s')); + + DB::insert("INSERT INTO countdowns (title, endtime) VALUES ('{$esc_title}', '{$esc_endtime}')"); + }; + $add_countdown_form->submit_button_config['align'] = 'compressed'; + $add_countdown_form->submit_button_config['text'] = '添加'; + $add_countdown_form->succ_href = '/super_manage/index#countdowns'; + $add_countdown_form->runAtServer(); + + // ========== 常用链接 ========== + if (isset($_POST['submit-delete_link']) && $_POST['submit-delete_link'] == 'delete_link') { + crsf_defend(); + + $item_id = $_POST['item_id']; + + if (!validateUInt($item_id)) { + die('' . SCRIPT_REFRESH_AS_GET); + } + + DB::delete("DELETE FROM links WHERE id = {$item_id}"); + + die('' . SCRIPT_REFRESH_AS_GET); } - }; - $blog_link_index->runAtServer(); - - $blog_deleter = new UOJForm('blog_deleter'); - $blog_deleter->addInput('blog_del_id', 'text', '博客ID', '', - function ($x) { - if (!validateUInt($x)) { - return 'ID不合法'; - } - if (!queryBlog($x)) { - return '博客不存在'; - } - return ''; - }, - null - ); - $blog_deleter->handle = function() { - deleteBlog($_POST['blog_del_id']); - }; - $blog_deleter->runAtServer(); - $countdown_adder = new UOJForm('new_countdown'); - $countdown_adder->submit_button_config['align'] = 'compressed'; - $countdown_adder->addInput('new_countdown_title', 'text', '标题', '', - function ($new_countdown_title) { - return ''; - }, - null - ); - $countdown_adder->addInput('new_countdown_endtime', 'text', '截止日期', date("Y-m-d H:i:s"), - function($str, &$vdata) { - try { - $vdata['new_countdown_endtime'] = new DateTime($str); - } catch (Exception $e) { - return '无效时间格式'; - } - return ''; - }, - null - ); - $countdown_adder->handle = function() { - $new_countdown_title = $_POST['new_countdown_title']; - $new_countdown_endtime = $_POST['new_countdown_endtime']; - $esc_countdown_title = DB::escape($new_countdown_title); + $links = DB::selectAll("SELECT `id`, `title`, `url`, `level` FROM `friend_links` ORDER BY `level` DESC, `id` ASC"); - DB::query("insert into countdowns (title, endtime) values ('$esc_countdown_title', '$new_countdown_endtime')"); - }; - $countdown_adder->runAtServer(); + $add_link_form = new UOJForm('add_link'); + $add_link_form->addInput('link_title', 'text', '标题', '', + function($title, &$vdata) { + if ($title == '') { + return '标题不能为空'; + } - $countdown_deleter = new UOJForm('delete_countdown'); - $countdown_deleter->submit_button_config['align'] = 'compressed'; - $countdown_deleter->addInput('delete_countdown_id', 'text', 'ID', '', - function ($x) { - if (!validateUInt($x)) { - return 'ID不合法'; - } + $vdata['title'] = $title; - if (!DB::selectFirst("select * from countdowns where id = $x")) { - return '倒计时不存在'; - } + return ''; + }, + null + ); + $add_link_form->addInput('link_url', 'text', '链接', '', + function($url, &$vdata) { + if (!validateURL($url)) { + return '链接不合法'; + } - return ''; - }, - null - ); - $countdown_deleter->handle = function() { - $delete_countdown_id = $_POST['delete_countdown_id']; + $vdata['url'] = $url; - DB::query("delete from countdowns where id = $delete_countdown_id"); - }; - $countdown_deleter->runAtServer(); + return ''; + }, + null + ); + $add_link_form->addInput('link_level', 'text', '权重', '10', + function($level, &$vdata) { + if (!validateUInt($level)) { + return '数字不合法'; + } - $countdowns_header_row = << - ID - 标题 - 时间 - -EOD; - $countdowns_print_row = function($row) { - echo << - {$row['id']} - {$row['title']} - {$row['endtime']} - -EOD; - }; + $vdata['level'] = $level; + + return ''; + }, + null + ); + $add_link_form->handle = function(&$vdata) { + $esc_title = DB::escape($vdata['title']); + $esc_url = DB::escape($vdata['url']); + $level = $vdata['level']; + + DB::insert("INSERT INTO friend_links (title, url, level) VALUES ('{$esc_title}', '{$esc_url}', {$level})"); + }; + $add_link_form->submit_button_config['align'] = 'compressed'; + $add_link_form->submit_button_config['text'] = '添加'; + $add_link_form->succ_href = '/super_manage/index#links'; + $add_link_form->runAtServer(); + } elseif ($cur_tab == 'users') { + $user_list_cond = []; - $friend_link_adder = new UOJForm('new_friend_link'); - $friend_link_adder->submit_button_config['align'] = 'compressed'; - $friend_link_adder->addInput('new_friend_link_title', 'text', '名称', '', - function ($str) { - return ''; - }, - null - ); - $friend_link_adder->addInput('new_friend_link_url', 'text', '链接', '', - function($str) { - if (!validateURL($str)) { - return '链接不合法'; - } - - return ''; - }, - null - ); - $friend_link_adder->addInput('new_friend_link_level', 'text', '权重', '10', - function($str) { - if (!validateUInt($str)) { - return '权重必须是数字'; - } - - return ''; - }, - null - ); - $friend_link_adder->handle = function() { - $new_friend_link_title = $_POST['new_friend_link_title']; - $new_friend_link_url = $_POST['new_friend_link_url']; - $new_friend_link_level = $_POST['new_friend_link_level']; - $esc_new_friend_link_title = DB::escape($new_friend_link_title); - $esc_new_friend_link_url = DB::escape($new_friend_link_url); - - DB::query("insert into friend_links (title, url, level) values ('$esc_new_friend_link_title', '$esc_new_friend_link_url', $new_friend_link_level)"); - }; - $friend_link_adder->runAtServer(); - - $friend_link_deleter = new UOJForm('delete_friend_link'); - $friend_link_deleter->submit_button_config['align'] = 'compressed'; - $friend_link_deleter->addInput('delete_friend_link_id', 'text', 'ID', '', - function ($id) { - if (!validateUInt($id)) { - return 'ID不合法'; - } - - if (!DB::selectFirst("select * from friend_links where id = $id")) { - return 'ID不存在'; - } - - return ''; - }, - null - ); - $friend_link_deleter->handle = function() { - $delete_friend_link_id = $_POST['delete_friend_link_id']; - - DB::query("delete from friend_links where id = $delete_friend_link_id"); - }; - $friend_link_deleter->runAtServer(); - - $friend_links_header_row = << - ID - 名称 - 链接 - 置顶等级 - -EOD; - $friend_links_print_row = function($row) { - echo << - {$row['id']} - {$row['title']} - {$row['url']} - {$row['level']} - -EOD; - }; - - $contest_submissions_deleter = new UOJForm('contest_submissions'); - $contest_submissions_deleter->addInput('contest_id', 'text', '比赛ID', '', - function ($x) { - if (!validateUInt($x)) { - return 'ID不合法'; - } - if (!queryContest($x)) { - return '博客不存在'; - } - return ''; - }, - null - ); - $contest_submissions_deleter->handle = function() { - $contest = queryContest($_POST['contest_id']); - genMoreContestInfo($contest); - - $contest_problems = DB::selectAll("select problem_id from contests_problems where contest_id = {$contest['id']}"); - foreach ($contest_problems as $problem) { - $submissions = DB::selectAll("select * from submissions where problem_id = {$problem['problem_id']} and submit_time < '{$contest['start_time_str']}'"); - foreach ($submissions as $submission) { - $content = json_decode($submission['content'], true); - unlink(UOJContext::storagePath().$content['file_name']); - DB::delete("delete from submissions where id = {$submission['id']}"); - updateBestACSubmissions($submission['submitter'], $submission['problem_id']); - } - } - }; - $contest_submissions_deleter->runAtServer(); - - $custom_test_deleter = new UOJForm('custom_test_deleter'); - $custom_test_deleter->addInput('last', 'text', '删除末尾记录', '5', - function ($x, &$vdata) { - if (!validateUInt($x)) { - return '不合法'; - } - $vdata['last'] = $x; - return ''; - }, - null - ); - $custom_test_deleter->handle = function(&$vdata) { - $all = DB::selectAll("select * from custom_test_submissions order by id asc limit {$vdata['last']}"); - foreach ($all as $submission) { - $content = json_decode($submission['content'], true); - unlink(UOJContext::storagePath().$content['file_name']); - } - DB::delete("delete from custom_test_submissions order by id asc limit {$vdata['last']}"); - }; - $custom_test_deleter->runAtServer(); - - $judger_adder = new UOJForm('judger_adder'); - $judger_adder->addInput('judger_adder_name', 'text', '评测机名称', '', - function ($x, &$vdata) { - if (!validateUsername($x)) { - return '不合法'; - } - if (DB::selectCount("select count(*) from judger_info where judger_name='$x'")!=0) { - return '不合法'; - } - $vdata['name'] = $x; - return ''; - }, - null - ); - $judger_adder->handle = function(&$vdata) { - $password=uojRandString(32); - DB::insert("insert into judger_info (judger_name,password) values('{$vdata['name']}','{$password}')"); - }; - $judger_adder->runAtServer(); - - $judger_deleter = new UOJForm('judger_deleter'); - $judger_deleter->addInput('judger_deleter_name', 'text', '评测机名称', '', - function ($x, &$vdata) { - if (!validateUsername($x)) { - return '不合法'; - } - if (DB::selectCount("select count(*) from judger_info where judger_name='$x'")!=1) { - return '不合法'; - } - $vdata['name'] = $x; - return ''; - }, - null - ); - $judger_deleter->handle = function(&$vdata) { - DB::delete("delete from judger_info where judger_name='{$vdata['name']}'"); - }; - $judger_deleter->runAtServer(); - - $judgerlist_cols = array('judger_name', 'password'); - $judgerlist_config = array(); - $judgerlist_header_row = << - 评测机名称 - 密码 - -EOD; - $judgerlist_print_row = function($row) { - echo << - {$row['judger_name']} - {$row['password']} - -EOD; - }; - - $userlist_cols = array('username', 'school', 'usergroup', 'usertype', 'register_time'); - $userlist_config = array('page_len' => 20, - 'table_classes' => array('table', 'table-bordered', 'table-hover', 'table-striped')); - $userlist_header_row = << - 用户名 - 学校 - 用户类别 - 注册时间 - -EOD; - - $cur_tab = isset($_GET['tab']) ? $_GET['tab'] : 'users'; - - $user_list_cond = array(); - if ($cur_tab === 'users') { if (isset($_GET['username']) && $_GET['username'] != "") { $user_list_cond[] = "username like '%" . DB::escape($_GET['username']) . "%'"; } if (isset($_GET['usergroup']) && $_GET['usergroup'] != "") { $user_list_cond[] = "usergroup = '" . DB::escape($_GET['usergroup']) . "'"; } - } - if ($user_list_cond) { - $user_list_cond = join($user_list_cond, ' and '); - } else { - $user_list_cond = '1'; - } - - $userlist_print_row = function($row) { - $hislink = getUserLink($row['username']); - echo << - ${hislink} - {$row['school']} - {$row['usergroup']}, {$row['usertype']} - {$row['register_time']} - -EOD; - }; - - $image_hosting_cols = ['*']; - $image_hosting_config = ['page_len' => 20, 'table_classes' => ['table', 'table-bordered', 'table-hover', 'table-striped']]; - $image_hosting_header_row = << - ID - 上传者 - 预览 - 文件大小 - 上传时间 - -EOD; - $image_hosting_print_row = function($row) { - $user_link = getUserLink($row['uploader']); - if ($row['size'] < 1024 * 512) { - $size = strval(round($row['size'] * 1.0 / 1024, 1)) . ' KB'; - } else { - $size = strval(round($row['size'] * 1.0 / 1024 / 1024, 1)) . ' MB'; + if (isset($_GET['usertype']) && $_GET['usertype'] != "") { + $user_list_cond[] = "usertype like '%" . DB::escape($_GET['usertype']) . "%'"; } - echo << - {$row['id']} - $user_link - - $size - {$row['upload_time']} - -EOD; - }; + if ($user_list_cond) { + $user_list_cond = join($user_list_cond, ' and '); + } else { + $user_list_cond = '1'; + } - $image_deleter = new UOJForm('image_deleter'); - $image_deleter->submit_button_config['align'] = 'compressed'; - $image_deleter->submit_button_config['text'] = '删除'; - $image_deleter->submit_button_config['class_str'] = 'btn btn-danger'; - $image_deleter->addInput('image_deleter_id', 'text', '图片 ID', '', - function ($x, &$vdata) { - if (!validateUInt($x)) { - return 'ID 不合法'; - } - if (!DB::selectCount("select count(*) from users_images where id = $x")) { - return '图片不存在'; - } - $vdata['id'] = $x; - return ''; - }, - null - ); - $image_deleter->handle = function(&$vdata) { - $id = $vdata['id']; - $result = DB::selectFirst("SELECT * from users_images WHERE id = $id"); - unlink(UOJContext::storagePath().$result['path']); - DB::delete("DELETE FROM users_images WHERE id = $id"); - }; - $image_deleter->runAtServer(); + $register_form = new UOJForm('register'); + $register_form->addVInput('new_username', 'text', '用户名', '', + function ($username, &$vdata) { + if (!validateUsername($username)) { + return '用户名不合法'; + } - $change_user_image_total_size_limit_form = new UOJForm('change_user_image_total_size_limit'); - $change_user_image_total_size_limit_form->submit_button_config['align'] = 'compressed'; - $change_user_image_total_size_limit_form->addInput('change_user_image_total_size_limit_username', 'text', '用户名', '', - function ($x, &$vdata) { - if (!validateUsername($x)) { - return '用户名不合法'; - } - if (!queryUser($x)) { - return '用户不存在'; - } - $vdata['username'] = $x; - return ''; - }, - null - ); - $change_user_image_total_size_limit_form->addInput('change_user_image_total_size_limit_limit', 'text', '存储限制(单位:Byte)', '104857600', - function ($x, &$vdata) { - if (!validateUInt($x, 10)) { - return '限制不合法'; - } - if (intval($x) > 2147483648) { - return '限制不能大于 2 GB'; - } - $vdata['limit'] = $x; - return ''; - }, - null - ); - $change_user_image_total_size_limit_form->handle = function(&$vdata) { - DB::update("UPDATE user_info SET images_size_limit = {$vdata['limit']} WHERE username = '{$vdata['username']}'"); - }; - $change_user_image_total_size_limit_form->runAtServer(); + if (queryUser($username)) { + return '该用户已存在'; + } - $tabs_info = array( - 'users' => array( - 'name' => '用户管理', - 'url' => "/super-manage/users" - ), - 'blogs' => array( - 'name' => '博客管理', - 'url' => "/super-manage/blogs" - ), - 'index' => array( - 'name' => '首页管理', - 'url' => '/super-manage/index' - ), - 'submissions' => array( - 'name' => '提交记录', - 'url' => "/super-manage/submissions" - ), - 'custom-test' => array( - 'name' => '自定义测试', - 'url' => '/super-manage/custom-test' - ), - 'judger' => array( - 'name' => '评测机管理', - 'url' => '/super-manage/judger' - ), - 'image_hosting' => array( - 'name' => '图床管理', - 'url' => '/super-manage/image_hosting' - ) - ); + $vdata['username'] = $username; + + return ''; + }, + null + ); + $register_form->addVInput('new_password', 'password', '密码', '', + function ($password, &$vdata) { + $vdata['password'] = $password; + + return ''; + }, + 'validatePassword' + ); + $register_form->addVInput('new_email', 'text', '电子邮件(选填)', '', + function ($email, &$vdata) { + if ($email && !validateEmail($email)) { + return '邮件地址不合法'; + } + + $vdata['email'] = $email; + + return ''; + }, + null + ); + $register_form->addVInput('new_realname', 'text', '真实姓名(选填)', '', + function ($realname, &$vdata) { + $vdata['realname'] = $realname; + + return ''; + }, + null + ); + $register_form->addVInput('new_school', 'text', '学校名称(选填)', '', + function ($school, &$vdata) { + $vdata['school'] = $school; + + return ''; + }, + null + ); + $register_form->handle = function(&$vdata) { + $username = $vdata['username']; + $realname = DB::escape($vdata['realname']); + $school = DB::escape($vdata['school']); + $email = DB::escape($vdata['email']); + $password = hash_hmac('md5', $vdata['password'], getPasswordClientSalt()); + $password = getPasswordToStore($password, $username); + $svn_password = uojRandString(10); - if (!isset($tabs_info[$cur_tab])) { - become404Page(); + DB::query("insert into user_info (username, realname, email, school, password, svn_password, register_time, usergroup) values ('$username', '$realname', '$email', '$school', '$password', '$svn_password', now(), 'U')"); + + header('Content-Type: application/json'); + die(json_encode(['status' => 'success', 'message' => ''])); + }; + $register_form->setAjaxSubmit(<<runAtServer(); + + $change_password_form = new UOJForm('change_password'); + $change_password_form->addVInput('p_username', 'text', '用户名', '', + function ($username, &$vdata) { + if (!validateUsername($username)) { + return '用户名不合法'; + } + + if (!queryUser($username)) { + return '用户不存在'; + } + + $vdata['username'] = $username; + + return ''; + }, + null + ); + $change_password_form->addVInput('p_password', 'password', '密码', '', + function ($password, &$vdata) { + $vdata['password'] = $password; + + return ''; + }, + 'validatePassword' + ); + $change_password_form->handle = function(&$vdata) { + $esc_username = DB::escape($vdata['username']); + $password = hash_hmac('md5', $vdata['password'], getPasswordClientSalt()); + $esc_password = DB::escape(getPasswordToStore($password, $vdata['username'])); + + DB::query("update user_info set password = '$esc_password' where username = '$esc_username'"); + + header('Content-Type: application/json'); + die(json_encode(['status' => 'success', 'message' => '用户 ' . $vdata['username'] . ' 的密码已经被成功重置。'])); + }; + $change_password_form->submit_button_config['margin_class'] = 'mt-3'; + $change_password_form->submit_button_config['text'] = '重置'; + $change_password_form->setAjaxSubmit(<<runAtServer(); + + $change_usergroup_form = new UOJForm('change_usergroup'); + $change_usergroup_form->addVInput('username', 'text', '用户名', '', + function ($username, &$vdata) { + if (!validateUsername($username)) { + return '用户名不合法'; + } + + if (!queryUser($username)) { + return '用户不存在'; + } + + $vdata['username'] = $username; + + return ''; + }, + null + ); + $change_usergroup_form->addVSelect('op_type', [ + 'banneduser' => '设为封禁用户', + 'normaluser' => '设为普通用户', + 'superuser' => '设为超级用户', + ], '操作类型', ''); + $change_usergroup_form->handle = function($vdata) { + $username = $vdata['username']; + $usergroup = ''; + + switch ($_POST['op_type']) { + case 'banneduser': + DB::update("update user_info set usergroup = 'B', usertype = 'banned' where username = '{$username}'"); + $usergroup = '被封禁的用户'; + break; + case 'normaluser': + DB::update("update user_info set usergroup = 'U', usertype = 'student' where username = '{$username}'"); + $usergroup = '普通用户'; + break; + case 'superuser': + DB::update("update user_info set usergroup = 'S', usertype = 'student' where username = '{$username}'"); + $usergroup = '超级用户'; + break; + } + + header('Content-Type: application/json'); + die(json_encode(['status' => 'success', 'message' => '用户 ' . $username . ' 现在是 ' . $usergroup . '。'])); + }; + $change_usergroup_form->setAjaxSubmit(<<runAtServer(); + } elseif ($cur_tab == 'submissions') { + } elseif ($cur_tab == 'custom_test') { + requireLib('hljs'); + + $submissions_pag = new Paginator([ + 'col_names' => ['*'], + 'table_name' => 'custom_test_submissions', + 'cond' => '1', + 'tail' => 'order by id desc', + 'page_len' => 10 + ]); + + $custom_test_deleter = new UOJForm('custom_test_deleter'); + $custom_test_deleter->addInput('last', 'text', '删除末尾记录', '5', + function ($x, &$vdata) { + if (!validateUInt($x)) { + return '不合法'; + } + $vdata['last'] = $x; + return ''; + }, + null + ); + $custom_test_deleter->handle = function(&$vdata) { + $all = DB::selectAll("select * from custom_test_submissions order by id asc limit {$vdata['last']}"); + foreach ($all as $submission) { + $content = json_decode($submission['content'], true); + unlink(UOJContext::storagePath().$content['file_name']); + } + DB::delete("delete from custom_test_submissions order by id asc limit {$vdata['last']}"); + }; + $custom_test_deleter->submit_button_config['align'] = 'compressed'; + $custom_test_deleter->runAtServer(); + } elseif ($cur_tab == 'judger') { + $judger_adder = new UOJForm('judger_adder'); + $judger_adder->addInput('judger_adder_name', 'text', '评测机名称', '', + function ($x, &$vdata) { + if (!validateUsername($x)) { + return '不合法'; + } + if (DB::selectCount("select count(*) from judger_info where judger_name='$x'")!=0) { + return '不合法'; + } + $vdata['name'] = $x; + return ''; + }, + null + ); + $judger_adder->handle = function(&$vdata) { + $password = uojRandString(32); + DB::insert("insert into judger_info (judger_name,password) values('{$vdata['name']}','{$password}')"); + }; + $judger_adder->submit_button_config['align'] = 'compressed'; + $judger_adder->runAtServer(); + + $judger_deleter = new UOJForm('judger_deleter'); + $judger_deleter->addInput('judger_deleter_name', 'text', '评测机名称', '', + function ($x, &$vdata) { + if (!validateUsername($x)) { + return '不合法'; + } + if (DB::selectCount("select count(*) from judger_info where judger_name='$x'")!=1) { + return '不合法'; + } + $vdata['name'] = $x; + return ''; + }, + null + ); + $judger_deleter->handle = function(&$vdata) { + DB::delete("delete from judger_info where judger_name='{$vdata['name']}'"); + }; + $judger_deleter->submit_button_config['align'] = 'compressed'; + $judger_deleter->runAtServer(); + } elseif ($cur_tab == 'image_hosting') { + if (isset($_POST['submit-delete_image']) && $_POST['submit-delete_image'] == 'delete_image') { + crsf_defend(); + + $image_id = $_POST['image_id']; + + if (!validateUInt($image_id)) { + die('' . SCRIPT_REFRESH_AS_GET); + } + + if (!($image = DB::selectFirst("SELECT * from users_images where id = $image_id"))) { + die('' . SCRIPT_REFRESH_AS_GET); + } + + unlink(UOJContext::storagePath().$result['path']); + DB::delete("DELETE FROM users_images WHERE id = $image_id"); + + die('' . SCRIPT_REFRESH_AS_GET); + } + + + $change_user_image_total_size_limit_form = new UOJForm('change_user_image_total_size_limit'); + $change_user_image_total_size_limit_form->submit_button_config['align'] = 'compressed'; + $change_user_image_total_size_limit_form->addInput('change_user_image_total_size_limit_username', 'text', '用户名', '', + function ($x, &$vdata) { + if (!validateUsername($x)) { + return '用户名不合法'; + } + + if (!queryUser($x)) { + return '用户不存在'; + } + + $vdata['username'] = $x; + + return ''; + }, + null + ); + $change_user_image_total_size_limit_form->addInput('change_user_image_total_size_limit_limit', 'text', '存储限制(单位:Byte)', '104857600', + function ($x, &$vdata) { + if (!validateUInt($x, 10)) { + return '限制不合法'; + } + + if (intval($x) > 2147483648) { + return '限制不能大于 2 GB'; + } + + $vdata['limit'] = $x; + + return ''; + }, + null + ); + + $change_user_image_total_size_limit_form->handle = function(&$vdata) { + DB::update("UPDATE user_info SET images_size_limit = {$vdata['limit']} WHERE username = '{$vdata['username']}'"); + }; + + $change_user_image_total_size_limit_form->runAtServer(); } ?> - - -
-
- -
- -
- -

添加新用户

- printHTML(); ?> -

修改用户密码

- printHTML(); ?> -

用户类别设置

-

在此处更新用户所属类别后会自动重置用户权限。

- printHTML(); ?> -

用户权限管理

- printHTML(); ?> -

修改用户真实姓名

- printHTML(); ?> -

修改用户学校名称

- printHTML(); ?> -

用户名单

-
-
-
- -
- -
-
-
- -
- -
-
-
-
- - -
-

添加到公告

- printHTML(); ?> -
- -
-

删除博客

- printHTML(); ?> -
- -
-

倒计时

- -
添加倒计时
- printHTML(); ?> -
删除倒计时
- printHTML(); ?> -

友情链接

- -
添加友情链接
- printHTML(); ?> -
删除友情链接
- printHTML(); ?> + + +

+ +

+ + +
+ +
+ +
+ $tab): ?> + + + + +
+ +
+ + + +
+ +
+
+ +
+
+
+ +
+
+ + + +
添加/修改公告
+ printHTML(); ?>
- -
-

删除赛前提交记录

- printHTML(); ?> + + +
+
+ + + +
添加倒计时
+ printHTML(); ?>
-
-

测评失败的提交记录

- ''), $myUser); ?> + + + - - printHTML() ?> - array('*'), - 'table_name' => 'custom_test_submissions', - 'cond' => '1', - 'tail' => 'order by id asc', - 'page_len' => 5 - )); - foreach ($submissions_pag->get() as $submission) { - $problem = queryProblemBrief($submission['problem_id']); - $submission_result = json_decode($submission['result'], true); - echo '
'; - echo '
id
'; - echo '
', "#{$submission['id']}", '
'; - echo '
problem_id
'; - echo '
', "#{$submission['problem_id']}", '
'; - echo '
submit time
'; - echo '
', $submission['submit_time'], '
'; - echo '
submitter
'; - echo '
', $submission['submitter'], '
'; - echo '
judge_time
'; - echo '
', $submission['judge_time'], '
'; - echo '
'; - echoSubmissionContent($submission, getProblemCustomTestRequirement($problem)); - echoCustomTestSubmissionDetails($submission_result['details'], "submission-{$submission['id']}-details"); - } - ?> - pagination() ?> - -
-

添加评测机

- printHTML(); ?> -
-
-

删除评测机

- printHTML(); ?> -
-

评测机列表

- - -

图床管理

- -
-

删除图片

- printHTML() ?> -
-
-

修改用户存储上限

- printHTML() ?> -
- +
+ + + +
+
+ +
+
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ + 用户名 + 学校 + 用户类别 + 权限 + 注册时间 + 操作 + +EOD, + function($row) { + echo ''; + echo '', '', $row['username'], '', ''; + echo '', HTML::escape($row['school']), ''; + echo ''; + switch ($row['usergroup']) { + case 'S': + echo UOJLocale::get('user::super user'); + break; + case 'B': + echo UOJLocale::get('user::banned user'); + break; + default: + echo UOJLocale::get('user::normal user'); + break; + } + echo ''; + echo ''; + foreach (explode(',', $row['usertype']) as $idx => $type) { + if ($idx) { + echo ', '; + } + echo UOJLocale::get('user::' . str_replace('_', ' ', $type)) ?: HTML::escape($type); + } + echo ''; + echo '', $row['register_time'], ''; + echo '', '编辑', ''; + echo ''; + }, + [ + 'page_len' => 20, + 'div_classes' => ['table-responsive'], + 'table_classes' => ['table', 'align-middle'], + ], + ); + ?> +
+
+ +
+
+ printHTML() ?> +
+
+
注意事项
+
    +
  • 用户名推荐格式为年级 + 姓名全拼,如 2022 级的张三同学可以设置为 2022zhangsan。对于外校学生,推荐格式为学校名称缩写 + 姓名拼音首字母,如山大附中的赵锦熙同学可以设置为 sdfzzjx)。
  • +
  • 请提醒用户及时修改初始密码,以免账号被盗导致教学资源流出。请勿设置过于简单的初始密码。
  • +
  • 我们推荐在创建账号时输入号主的电子邮件地址以便后期发生忘记密码等情况时进行验证。
  • +
  • 创建账号后可以在「修改个人信息」页面中的「特权」选项卡为用户分配权限。特别地,如果该用户是外校学生,那么您可能需要将其设置为「仅比赛参加者」以禁止其查看已参与比赛以外的题目。
  • +
+
+
+
+
+ +
+
+ printHTML() ?> +
+
+
注意事项
+
    +
  • 在为用户重置密码前请核对对方身份以免被骗。
  • +
  • 请勿设置过于简单的密码。
  • +
  • 请提醒用户在登录后及时修改初始密码。
  • +
+
+
+
+
+ +
+
+ printHTML() ?> +
+
+
注意事项
+
    +
  • 用户被封禁后将不能再次登录系统。
  • +
  • 将当前用户移除权限后将无法再次访问本页面。
  • +
  • 在修改用户类别前请仔细核对用户名以免产生不必要的麻烦。
  • +
+
+
+
+
+
+
+ + + +

测评失败的提交记录

+ '', + 'table_config' => [ + 'div_classes' => ['card', 'mb-3', 'table-responsive'], + 'table_classes' => ['table', 'uoj-table', 'mb-0', 'text-center'] + ] + ], + $myUser +); + ?> + +
+ + + + + + + + + + + + get() as $submission): ?> + + + + + + + + + + + + + isEmpty()): ?> + + + + + +
ID题目 ID提交者提交时间测评时间
##
+ + +
+ +
+
+ pagination() ?> + +
+
+
删除末尾的 n 条记录
+ printHTML() ?> +
+
+ +

评测机列表

+ + 评测机名称 + 密码 + IP + +EOD, + function($row) { + echo << + {$row['judger_name']} + {$row['password']} + {$row['ip']} + +EOD; + }, + [ + 'page_len' => 10, + 'div_classes' => ['card', 'mb-3', 'table-responsive'], + 'table_classes' => ['table', 'uoj-table', 'mb-0'], + ] + ); ?> + +
+
+
添加评测机
+ printHTML(); ?> +
删除评测机
+ printHTML(); ?> +
+
+ + + 上传者 + 预览 + 文件大小 + 上传时间 + 操作 + +EOD, + function($row) { + $user_link = getUserLink($row['uploader']); + if ($row['size'] < 1024 * 512) { + $size = strval(round($row['size'] * 1.0 / 1024, 1)) . ' KB'; + } else { + $size = strval(round($row['size'] * 1.0 / 1024 / 1024, 1)) . ' MB'; + } + $token = crsf_token(); + + echo << + $user_link + + $size + {$row['upload_time']} + +
+ + + +
+ + +EOD; + }, + [ + 'page_len' => 20, + 'div_classes' => ['card', 'mb-3', 'table-responsive'], + 'table_classes' => ['table', 'uoj-table', 'mb-0'], + ] + ); ?> +
+
+
修改用户图床空间上限
+ printHTML() ?> +
+
+ +
+ +
+ diff --git a/web/app/controllers/user_info_edit.php b/web/app/controllers/user_info_edit.php index dbd9f49..f475885 100644 --- a/web/app/controllers/user_info_edit.php +++ b/web/app/controllers/user_info_edit.php @@ -341,7 +341,7 @@ EOD);
@@ -410,6 +410,20 @@ EOD);
+
+ + + + + + + + + + + + +
EOD; @@ -197,7 +197,7 @@ EOD;
- +
EOD; @@ -210,7 +210,7 @@ EOD;
- +
EOD; $this->add($name, $html, $validator_php, $validator_js, $no_val); @@ -270,7 +270,7 @@ EOD;
- +
EOD; $this->add($name, $html, $validator_php, $validator_js); @@ -333,7 +333,7 @@ EOD
- +