From ef3f7b9e7f90d5a1fef1b8da17233f4a51bce97b Mon Sep 17 00:00:00 2001 From: Baoshuo Date: Sat, 12 Nov 2022 07:10:34 +0800 Subject: [PATCH 1/6] feat(web): new user permissions (#10) --- db/app_uoj233.sql | 1 + web/app/controllers/add_contest.php | 2 +- web/app/controllers/blogs.php | 29 +- web/app/controllers/contest_inside.php | 13 +- web/app/controllers/contest_manage.php | 2 +- web/app/controllers/contests.php | 10 +- web/app/controllers/forgot_pw.php | 2 +- web/app/controllers/groups.php | 33 +- web/app/controllers/image_hosting/index.php | 37 +- web/app/controllers/lists.php | 10 +- web/app/controllers/problem.php | 2 +- web/app/controllers/problem_data_manage.php | 6 +- .../controllers/problem_managers_manage.php | 2 +- web/app/controllers/problem_set.php | 8 +- web/app/controllers/problem_solutions.php | 13 +- web/app/controllers/problem_statistics.php | 36 +- web/app/controllers/ranklist.php | 2 +- web/app/controllers/register.php | 2 +- web/app/controllers/reset_pw.php | 2 +- .../controllers/subdomain/blog/aboutme.php | 2 + .../controllers/subdomain/blog/archive.php | 3 +- web/app/controllers/subdomain/blog/blog.php | 16 +- .../controllers/subdomain/blog/blog_write.php | 8 +- web/app/controllers/subdomain/blog/index.php | 3 +- .../subdomain/blog/self_reviews.php | 1 + web/app/controllers/subdomain/blog/slide.php | 2 +- .../subdomain/blog/slide_write.php | 3 + web/app/controllers/super_manage.php | 231 ++++++++- web/app/controllers/user_info.php | 14 +- web/app/controllers/user_info_edit.php | 483 +++++++++++++----- web/app/controllers/user_msg.php | 385 +++++++------- web/app/controllers/user_system_msg.php | 2 +- web/app/libs/uoj-html-lib.php | 62 +-- web/app/libs/uoj-query-lib.php | 76 --- web/app/locale/user/en.php | 1 + web/app/locale/user/zh-cn.php | 1 + web/app/models/HTML.php | 1 + web/app/models/UOJBlog.php | 43 +- web/app/models/UOJContest.php | 43 +- web/app/models/UOJContext.php | 49 +- web/app/models/UOJForm.php | 360 +++++++------ web/app/models/UOJGroup.php | 21 +- web/app/models/UOJList.php | 17 +- web/app/models/UOJMarkdown.php | 2 +- web/app/models/UOJProblem.php | 27 +- web/app/models/UOJSubmission.php | 2 +- web/app/models/UOJSubmissionLikeTrait.php | 22 +- web/app/models/UOJUser.php | 19 + web/app/models/UOJUserBlog.php | 9 +- web/app/route.php | 3 +- web/app/views/blog-preview.php | 130 ++--- web/app/views/user-info.php | 2 +- 52 files changed, 1398 insertions(+), 857 deletions(-) diff --git a/db/app_uoj233.sql b/db/app_uoj233.sql index 02ce760..558f426 100644 --- a/db/app_uoj233.sql +++ b/db/app_uoj233.sql @@ -692,6 +692,7 @@ CREATE TABLE `problems_solutions` ( `problem_id` int NOT NULL, `blog_id` int NOT NULL, PRIMARY KEY (`problem_id`, `blog_id`), + UNIQUE KEY `blog_id` (`blog_id`), KEY `problem_id` (`problem_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; /*!40101 SET character_set_client = @saved_cs_client */; diff --git a/web/app/controllers/add_contest.php b/web/app/controllers/add_contest.php index d5eaa05..72b7776 100644 --- a/web/app/controllers/add_contest.php +++ b/web/app/controllers/add_contest.php @@ -3,7 +3,7 @@ requireLib('bootstrap5'); requirePHPLib('form'); Auth::check() || redirectToLogin(); -isSuperUser(Auth::user()) || UOJResponse::page403(); +UOJContest::userCanCreateContest(Auth::user()) || UOJResponse::page403(); $time_form = new UOJBs4Form('time'); $time_form->addVInput( diff --git a/web/app/controllers/blogs.php b/web/app/controllers/blogs.php index 49839ed..d409d89 100644 --- a/web/app/controllers/blogs.php +++ b/web/app/controllers/blogs.php @@ -21,10 +21,12 @@ Auth::check() || redirectToLogin(); 我的博客首页 - - - 写新博客 - + + + + 写新博客 + + @@ -35,16 +37,16 @@ Auth::check() || redirectToLogin(); echoLongTable( ['id', 'poster', 'title', 'post_time', 'zan', 'is_hidden'], 'blogs', - isSuperUser($myUser) ? "1" : "is_hidden = 0 or poster = '{$myUser['username']}'", + '1', 'order by post_time desc', << - 标题 - 发表者 - 发表日期 - 评价 - -EOD, + + 标题 + 发表者 + 发表日期 + 评价 + + EOD, function ($info) { $blog = new UOJBlog($info); @@ -64,6 +66,9 @@ EOD, 'page_len' => 10, 'div_classes' => ['card', 'my-3', 'table-responsive'], 'table_classes' => ['table', 'uoj-table', 'mb-0'], + 'post_filter' => function ($info) { + return (new UOJBlog($info))->userCanView(Auth::user()); + }, ] ); ?> diff --git a/web/app/controllers/contest_inside.php b/web/app/controllers/contest_inside.php index d9c36cb..3b47fe4 100644 --- a/web/app/controllers/contest_inside.php +++ b/web/app/controllers/contest_inside.php @@ -53,7 +53,7 @@ if ($is_manager) { isset($tabs_info[$cur_tab]) || UOJResponse::page404(); -if (isSuperUser($myUser) || isContestJudger($myUser)) { +if (UOJContest::cur()->userCanStartFinalTest(Auth::user())) { if (CONTEST_PENDING_FINAL_TEST <= $contest['cur_progress']) { $start_test_form = new UOJBs4Form('start_test'); $start_test_form->handle = function () { @@ -113,7 +113,7 @@ if ($cur_tab == 'dashboard') { $post_question = null; } } elseif ($cur_tab == 'backstage') { - if (isSuperUser(Auth::user())) { + if ($is_manager) { $post_notice = new UOJBs4Form('post_notice'); $post_notice->addInput( 'title', @@ -158,7 +158,6 @@ if ($cur_tab == 'dashboard') { $post_notice = null; } - if ($is_manager) { $reply_question = new UOJBs4Form('reply_question'); $reply_question->addHidden( @@ -486,10 +485,8 @@ function echoSelfReviews() { uojIncludeView('contest-reviews', ['contest' => $contest] + UOJContest::cur()->queryResult()); } - -$page_header = HTML::stripTags($contest['name']) . ' - '; ?> - +

@@ -600,7 +597,7 @@ $page_header = HTML::stripTags($contest['name']) . ' - ';
@@ -618,7 +615,7 @@ $page_header = HTML::stripTags($contest['name']) . ' - '; - + 管理 diff --git a/web/app/controllers/contest_manage.php b/web/app/controllers/contest_manage.php index 689dfb2..d31f084 100644 --- a/web/app/controllers/contest_manage.php +++ b/web/app/controllers/contest_manage.php @@ -4,7 +4,7 @@ requirePHPLib('form'); Auth::check() || redirectToLogin(); UOJContest::init(UOJRequest::get('id')) || UOJResponse::page404(); -isSuperUser(Auth::user()) || UOJResponse::page403(); +UOJContest::cur()->userCanManage(Auth::user()) || UOJResponse::page403(); $contest = UOJContest::info(); if (isset($_GET['tab'])) { diff --git a/web/app/controllers/contests.php b/web/app/controllers/contests.php index 1649ce8..757684c 100644 --- a/web/app/controllers/contests.php +++ b/web/app/controllers/contests.php @@ -52,7 +52,7 @@ function echoContest($info) { echo '', '' . $contest->info['start_time_str'] . '', ''; echo '', UOJLocale::get('hours', $last_hour), ''; echo '', '', '', ' ×' . $contest->info['player_num'] . '', ''; - echo '', '
' . ClickZans::getBlock('C', $contest->info['id'], $contest->info['zan']) . '
', ''; + echo HTML::tag('td', [], $contest->getZanBlock()); echo ''; } ?> @@ -64,7 +64,7 @@ function echoContest($info) { - +
@@ -92,6 +92,12 @@ $table_config = [ 'table_classes' => ['table', 'uoj-table', 'mb-0', 'text-center'], ]; +if (!UOJUser::checkPermission(Auth::user(), 'contests.view')) { + $table_config['post_filter'] = function ($info) { + return (new UOJContest($info))->userCanView(Auth::user()); + }; +} + echoLongTable( ['*'], 'contests', diff --git a/web/app/controllers/forgot_pw.php b/web/app/controllers/forgot_pw.php index f0fa505..c50d5d9 100644 --- a/web/app/controllers/forgot_pw.php +++ b/web/app/controllers/forgot_pw.php @@ -7,7 +7,7 @@ if (!validateUsername($username)) { return '用户名不合法'; } - $vdata['user'] = queryUser($username); + $vdata['user'] = UOJUser::query($username); if (!$vdata['user']) { return '该用户不存在'; } diff --git a/web/app/controllers/groups.php b/web/app/controllers/groups.php index e645d0d..200fc7d 100644 --- a/web/app/controllers/groups.php +++ b/web/app/controllers/groups.php @@ -4,11 +4,9 @@ requirePHPLib('form'); requirePHPLib('judger'); requirePHPLib('data'); -if (!Auth::check()) { - redirectToLogin(); -} +Auth::check() || redirectToLogin(); -if (isSuperUser($myUser)) { +if (UOJGroup::userCanCreateGroup(Auth::user())) { $new_group_form = new UOJBs4Form('new_group'); $new_group_form->handle = function () { DB::query("insert into `groups` (title, is_hidden) values ('新小组', 1)"); @@ -33,7 +31,7 @@ if (isSuperUser($myUser)) { -
+
printHTML(); ?>
@@ -45,23 +43,17 @@ if (isSuperUser($myUser)) { $groups_caption = UOJLocale::get('groups'); $users_caption = UOJLocale::get('users count'); $header = << - ID - {$groups_caption} - {$users_caption} - -EOD; - - if (isSuperUser(Auth::user())) { - $cond = "1"; - } else { - $cond = ["is_hidden" => false]; - } + + ID + {$groups_caption} + {$users_caption} + + EOD; echoLongTable( - ['id', 'title', 'is_hidden'], + ['*'], "`groups`", - $cond, + '1', 'order by id asc', $header, function ($group) { @@ -93,6 +85,9 @@ EOD; 'div_classes' => ['card', 'my-3'], 'table_classes' => ['table', 'uoj-table', 'mb-0'], 'head_pagination' => true, + 'post_filter' => function ($info) { + return (new UOJGroup($info))->userCanView(Auth::user()); + } ] ); ?> diff --git a/web/app/controllers/image_hosting/index.php b/web/app/controllers/image_hosting/index.php index 435d962..74a652a 100644 --- a/web/app/controllers/image_hosting/index.php +++ b/web/app/controllers/image_hosting/index.php @@ -6,6 +6,7 @@ requirePHPLib('form'); requireLib('bootstrap5'); Auth::check() || redirectToLogin(); +UOJUser::checkPermission(Auth::user(), 'users.upload_image') || UOJResponse::page403(); $extra = UOJUser::getExtra($user); $limit = $extra['image_hosting']['total_size_limit']; @@ -56,18 +57,18 @@ if ($_POST['image_upload_file_submit'] == 'submit') { throwError('not_a_image'); } - list($width, $height, $type) = $size; - $hash = hash_file("sha256", $_FILES['image_upload_file']['tmp_name']) . Auth::id(); - $scale = ceil($height / 600.0); + list($width, $height, $type) = $size; + $hash = hash_file("sha256", $_FILES['image_upload_file']['tmp_name']) . Auth::id(); + $scale = ceil($height / 600.0); - $watermark_text = UOJConfig::$data['profile']['oj-name-short']; - if (isSuperUser($myUser) && $_POST['watermark'] == 'no_watermark') { - $watermark_text = ""; - $hash .= "__no_watermark"; - } elseif ($_POST['watermark'] == 'site_shortname_and_username') { - $watermark_text .= ' @' . Auth::id(); - $hash .= "__id"; - } + $watermark_text = UOJConfig::$data['profile']['oj-name-short']; + if (isSuperUser(Auth::user()) && $_POST['watermark'] == 'no_watermark') { + $watermark_text = ""; + $hash .= "__no_watermark"; + } elseif ($_POST['watermark'] == 'site_shortname_and_username') { + $watermark_text .= ' @' . Auth::id(); + $hash .= "__id"; + } $existing_image = DB::selectFirst("SELECT * FROM users_images WHERE `hash` = '$hash'"); @@ -96,7 +97,19 @@ if ($_POST['image_upload_file_submit'] == 'submit') { throwError('unknown error'); } - DB::insert("INSERT INTO users_images (`path`, uploader, width, height, upload_time, size, `hash`) VALUES ('$filename', '{$myUser['username']}', $width, $height, now(), {$_FILES["image_upload_file"]["size"]}, '$hash')"); + DB::insert([ + "insert into users_images", + DB::bracketed_fields(["path", "uploader", "width", "height", "upload_time", "size", "hash"]), + "values", DB::tuple([ + $filename, + Auth::id(), + $width, + $height, + DB::now(), + $_FILES["image_upload_file"]["size"], + $hash, + ]), + ]); dieWithJsonData(['status' => 'success', 'path' => $filename]); } elseif ($_POST['image_delete_submit'] == 'submit') { diff --git a/web/app/controllers/lists.php b/web/app/controllers/lists.php index 6694cf4..e1fdf75 100644 --- a/web/app/controllers/lists.php +++ b/web/app/controllers/lists.php @@ -6,17 +6,17 @@ requirePHPLib('judger'); requirePHPLib('data'); Auth::check() || redirectToLogin(); +UOJUser::checkPermission(Auth::user(), 'lists.view') || UOJResponse::page403(); -if (isSuperUser($myUser)) { +if (UOJList::userCanCreateList(Auth::user())) { $new_list_form = new UOJBs4Form('new_list'); $new_list_form->handle = function () { - DB::query("insert into lists (title, is_hidden) values ('未命名题单', 1)"); + DB::insert("insert into lists (title, is_hidden) values ('未命名题单', 1)"); }; $new_list_form->submit_button_config['align'] = 'right'; $new_list_form->submit_button_config['class_str'] = 'btn btn-primary'; $new_list_form->submit_button_config['text'] = UOJLocale::get('problems::add new list'); $new_list_form->submit_button_config['smart_confirm'] = ''; - $new_list_form->runAtServer(); } @@ -92,14 +92,14 @@ $pag = new Paginator([
-

+ -
+
printHTML(); ?>
diff --git a/web/app/controllers/problem.php b/web/app/controllers/problem.php index a4a6517..059cc80 100644 --- a/web/app/controllers/problem.php +++ b/web/app/controllers/problem.php @@ -313,7 +313,7 @@ if (UOJContest::cur()) {
progress() <= CONTEST_IN_PROGRESS) : ?> diff --git a/web/app/controllers/problem_data_manage.php b/web/app/controllers/problem_data_manage.php index 29f34b6..a79cd6e 100644 --- a/web/app/controllers/problem_data_manage.php +++ b/web/app/controllers/problem_data_manage.php @@ -127,7 +127,7 @@ if ($_POST['problem_settings_file_submit'] == 'submit') { $info_form = new UOJBs4Form('info'); $http_host = HTML::escape(UOJContext::httpHost()); -$attachment_url = HTML::url("/download.php?type=attachment&id={$problem['id']}"); +$attachment_url = UOJProblem::cur()->getAttachmentUri(); $info_form->appendHTML( << @@ -140,7 +140,7 @@ $info_form->appendHTML(
EOD ); -$download_url = HTML::url("/download.php?type=problem&id={$problem['id']}"); +$download_url = UOJProblem::cur()->getMainDataUri(); $info_form->appendHTML( << @@ -194,7 +194,7 @@ $esc_extra_config
EOD ); -if (isSuperUser($myUser)) { +if (isSuperUser(Auth::user())) { $info_form->addVInput( 'submission_requirement', 'text', diff --git a/web/app/controllers/problem_managers_manage.php b/web/app/controllers/problem_managers_manage.php index 53f9500..6620d2b 100644 --- a/web/app/controllers/problem_managers_manage.php +++ b/web/app/controllers/problem_managers_manage.php @@ -31,7 +31,7 @@ $managers_form = newAddDelCmdForm( $managers_form->runAtServer(); -if (isSuperUser($myUser)) { +if (isSuperUser(Auth::user())) { $update_uploader_form = new UOJBs4Form('update_uploader'); $update_uploader_form->addInput( 'new_uploader_username', diff --git a/web/app/controllers/problem_set.php b/web/app/controllers/problem_set.php index 7729fae..8822838 100644 --- a/web/app/controllers/problem_set.php +++ b/web/app/controllers/problem_set.php @@ -5,8 +5,9 @@ requirePHPLib('judger'); requirePHPLib('data'); Auth::check() || redirectToLogin(); +UOJUser::checkPermission(Auth::user(), 'problems.view') || UOJResponse::page403(); -if (isSuperUser($myUser) || isProblemManager($myUser) || isProblemUploader($myUser)) { +if (UOJProblem::userCanCreateProblem(Auth::user())) { $default_statement = <<<'EOD' @@ -240,12 +241,11 @@ $pag = new Paginator([
-

- +
printHTML(); ?>
@@ -360,7 +360,7 @@ $pag = new Paginator([
- +
class="form-check-input" id="input-is_hidden">
- pagination() ?> - - + - +