Skip to content

Hệ thống phân quyền

Cách LCOJ kiểm tra quyền, cách cấp quyền qua nhóm hoặc trực tiếp trong trang quản trị, và danh sách đầy đủ các quyền tùy chỉnh.

⏱ ~10 phút (cấp quyền) · 👤 Quản trị viên hệ thống · 🔑 Superuser (hoặc staff có quyền auth.change_group / auth.change_user)

Khi nào cần trang này

Dùng trang này khi một người cần làm việc mà tài khoản thường không làm được (ra đề, tổ chức kỳ thi, điều hành bình luận…), hoặc khi ai đó báo "không có quyền" và bạn cần biết thiếu quyền nào. Phần đầu hướng dẫn cấp quyền; phần sau là bảng tra cứu.

LCOJ dùng hệ thống phân quyền của Django: mỗi hành động nhạy cảm (sửa bài, chấm lại, xem kỳ thi riêng tư…) được kiểm tra bằng một quyền (permission) có tên dạng <app>.<codename>, ví dụ judge.edit_own_problem. Trang này liệt kê toàn bộ quyền tùy chỉnh của LCOJ, giải thích mỗi quyền cho phép làm gì và hướng dẫn cấp quyền trong trang quản trị.

Cách phân quyền hoạt động

Khái niệmÝ nghĩa
SuperuserCó mọi quyền, không cần cấp từng quyền. Chỉ dành cho quản trị viên hệ thống.
Staff (is_staff)Cho phép đăng nhập trang quản trị /admin/. Bản thân nó không cho quyền gì thêm; bạn vẫn phải cấp quyền cụ thể.
Quyền của người dùng (User permissions)Quyền gán trực tiếp cho một tài khoản.
Nhóm (Groups)Một tập quyền có tên. Người dùng thuộc nhóm nào sẽ có mọi quyền của nhóm đó.

Quyền thực tế của một người = quyền gán trực tiếp cộng quyền của tất cả các nhóm họ thuộc về. Không có cơ chế "cấm" quyền; muốn thu hồi, hãy gỡ quyền hoặc gỡ người dùng khỏi nhóm.

Nên dùng nhóm

Hãy tạo nhóm theo vai trò (ví dụ "Người ra đề", "Ban tổ chức kỳ thi") rồi thêm người vào nhóm. Khi cần đổi quyền cho cả vai trò, bạn chỉ sửa nhóm một lần.

Cách cấp quyền trong trang quản trị

Cách 1: Qua nhóm (khuyên dùng)

  1. Vào /admin/auth/group/ (ví dụ https://luyencode.net/admin/auth/group/).
  2. Bấm Thêm để tạo nhóm mới, đặt tên (ví dụ "Người ra đề").
  3. Trong ô Permissions (tiếng Việt: Cho phép), chọn các quyền cần thiết rồi bấm mũi tên để chuyển sang cột đã chọn. Gõ codename (ví dụ edit_own_problem) vào ô lọc để tìm nhanh.
  4. Lưu nhóm.
  5. Vào /admin/auth/user/, mở tài khoản cần cấp, thêm nhóm vào mục Groups (Các nhóm) và lưu.

Cách 2: Cấp trực tiếp cho một người dùng

  1. Vào /admin/auth/user/ và mở tài khoản cần cấp.
  2. Nếu người này cần dùng trang quản trị, bật Staff status (Tình trạng nhân viên).
  3. Trong mục User permissions (Quyền của người sử dụng), chọn các quyền. Mỗi dòng hiển thị dạng judge.edit_own_problem | Edit own problems (app, codename, rồi nhãn).
  4. Lưu.

Kiểm tra kết quả

  • Người được cấp quyền tải lại trang và làm thử thao tác cần quyền (ví dụ mở Sửa đề bài trên bài của mình).
  • Nếu vai trò cần trang quản trị, họ vào được /admin/ và thấy các mục tương ứng.

Nhãn quyền là tiếng Anh

Nhãn quyền được lưu trong cơ sở dữ liệu bằng tiếng Anh, và nhiều nhãn chưa có bản dịch tiếng Việt. Hãy tìm quyền theo codename (cột đầu tiên trong các bảng dưới đây). Nếu nhãn trong cơ sở dữ liệu bị cũ sau khi cập nhật mã nguồn, chạy ./scripts/manage.py update_permissions (xem Lệnh quản lý).

Quyền mặc định của Django

Với mỗi model, Django tự tạo bốn quyền: add_<model>, change_<model>, delete_<model>view_<model> (ví dụ judge.change_problem). Các quyền này chủ yếu quyết định người dùng staff thấy và thao tác được những mục nào trong trang quản trị /admin/. Một số màn hình quản trị còn kiểm tra thêm quyền tùy chỉnh bên dưới; ví dụ để sửa tổ chức trong admin cần judge.change_organization, và phạm vi tổ chức được sửa phụ thuộc vào judge.edit_all_organization.

Danh sách quyền tùy chỉnh

Các quyền được nhóm theo đối tượng mà chúng áp dụng. Cột Nhãn là tên hiển thị trong trang quản trị.

Bài tập (judge · Problem)

CodenameNhãnCho phép
see_private_problemSee hidden problemsXem mọi bài tập, kể cả bài đang ẩn (chưa công khai) và bài riêng của tổ chức.
edit_own_problemEdit own problemsSửa những bài mình là tác giả hoặc curator. Là điều kiện bắt buộc cho edit_public_problemedit_all_problem: thiếu quyền này thì hai quyền kia không có tác dụng. Cũng cần để dùng trang quản trị bài nộp của bài mình.
edit_public_problemEdit all public problemsSửa mọi bài đang công khai và xem/sửa bài nộp của các bài đó.
edit_all_problemEdit all problemsSửa mọi bài tập; xem mọi bài nộp và mọi bài riêng của tổ chức.
create_organization_problemCreate organization problemTạo bài tập riêng trong tổ chức mà mình quản trị.
problem_full_markupEdit problems with full markupBật/tắt chế độ full markup (cho phép HTML không lọc trong đề) và sửa bài đang bật chế độ này.
clone_problemClone problemNhân bản một bài mà mình có quyền sửa.
upload_file_statementUpload file-type statementTải lên đề dạng tệp (PDF).
change_public_visibilityChange is_public fieldĐổi trường công khai (is_public) của bài; dùng các thao tác hàng loạt "công khai / ẩn" trong admin.
change_manually_managedChange is_manually_managed fieldĐổi trường is_manually_managed (dữ liệu test do người quản trị tự quản lý trên máy chấm).
see_organization_problemSee organization-private problemsXem bài riêng của mọi tổ chức, kể cả khi không là thành viên.
import_polygon_packageImport Codeforces Polygon packageNhập bài từ gói Codeforces Polygon.
edit_type_group_all_problemEdit type and group for all problemsSửa dạng bài và nhóm bài của mọi bài tập (không cần quyền sửa bài).

Lời giải (judge · Solution)

CodenameNhãnCho phép
see_private_solutionSee hidden solutionsXem lời giải (editorial) chưa công khai hoặc chưa tới giờ công bố. Người sửa được bài cũng xem được lời giải của bài đó.

Bài nộp (judge · Submission)

CodenameNhãnCho phép
abort_any_submissionAbort any submissionDừng chấm bất kỳ bài nộp nào. Không có quyền này, người dùng chỉ dừng được bài của chính mình (và không dùng được trong chế độ thi chính thức).
rejudge_submissionRejudge the submissionChấm lại bài nộp của những bài mình sửa được (cần kèm edit_own_problem).
rejudge_submission_lotRejudge a lot of submissionsChấm lại hàng loạt: vượt giới hạn DMOJ_SUBMISSIONS_REJUDGE_LIMIT (mặc định 10) bài mỗi lần trong admin, và dùng chức năng chấm lại trên trang quản lý bài nộp của bài tập.
spam_submissionSubmit without limitNộp bài không giới hạn. Người không có quyền này chỉ được có tối đa DMOJ_SUBMISSION_LIMIT (mặc định 2) bài đang chờ chấm cùng lúc.
view_all_submissionView all submissionXem mã nguồn của mọi bài nộp.
resubmit_otherResubmit others' submissionNộp lại (resubmit) bài nộp của người khác.
lock_submissionChange lock status of submissionSửa trường khóa locked_after của bài nộp trong admin.

Kỳ thi (judge · Contest)

CodenameNhãnCho phép
see_private_contestSee private contestsXem mọi kỳ thi, kể cả kỳ thi ẩn, riêng tư hoặc riêng của tổ chức.
edit_own_contestEdit own contestsSửa những kỳ thi mình là tác giả hoặc curator; cần để mở trang sửa kỳ thi trong admin.
edit_all_contestEdit all contestsXem và sửa mọi kỳ thi.
clone_contestClone contestNhân bản kỳ thi mà mình sửa được.
moss_contestMOSS contestChạy MOSS (kiểm tra đạo code) cho kỳ thi. Tab MOSS luôn hiện với người có quyền này, nhưng chỉ chạy được khi đã đặt MOSS_API_KEY hợp lệ; nếu chưa có khóa, lệnh chạy MOSS sẽ thất bại.
contest_ratingRate contestsBật tính rating cho kỳ thi (các trường is_rated, rate_all, rate_exclude) và chạy tính lại rating trong admin.
contest_access_codeContest access codesĐặt mã truy cập (access_code) cho kỳ thi.
create_private_contestCreate private contestsĐặt kỳ thi riêng tư hoặc riêng của tổ chức (các trường is_private, private_contestants, is_organization_private, organization); tạo kỳ thi trong tổ chức mình quản trị.
change_contest_visibilityChange contest visibilityCông khai (is_visible) kỳ thi bất kỳ. Người chỉ có create_private_contest chỉ được công khai kỳ thi riêng tư/riêng của tổ chức.
contest_problem_labelEdit contest problem label scriptSửa script đặt nhãn bài trong kỳ thi (problem_label_script).
lock_contestChange lock status of contestKhóa kỳ thi (locked_after) và dùng thao tác khóa/mở khóa hàng loạt trong admin.

Cách chọn thể thức và cấu hình kỳ thi: xem Thể thức kỳ thi.

Tổ chức (judge · Organization)

CodenameNhãnCho phép
organization_adminAdminister organizationsTrong admin: sửa danh sách quản trị viên, is_open, slots, tín dụng chấm (paid_credit, hạn mức miễn phí hằng tháng) của tổ chức.
edit_all_organizationEdit all organizationsSửa mọi tổ chức (không cần là quản trị viên tổ chức); tự tham gia cả các tổ chức đóng hoặc không công khai trong danh sách.
change_open_organizationChange is_open fieldKhông có tác dụng riêng: trường is_open trong admin do quyền organization_admin điều khiển, nên hãy cấp organization_admin thay cho quyền này.
spam_organizationCreate organization without limitTạo tổ chức vượt giới hạn VNOJ_ORGANIZATION_ADMIN_LIMIT (mặc định 3 tổ chức mà một người làm quản trị). Xem lưu ý bên dưới.

spam_organization chỉ có tác dụng với superuser

Hiện chỉ superuser mới vượt được giới hạn tạo tổ chức. Cấp quyền này cho người dùng thường sẽ không giúp họ vượt giới hạn.

Người dùng (judge · Profile)

CodenameNhãnCho phép
test_siteShows in-progress development stuffCờ "Bật các tính năng đang thử nghiệm". Mọi người dùng đều tự bật/tắt được trong trang sửa hồ sơ; hiện chưa có tính năng nào dùng cờ này.
totpEdit TOTP settingsXem và sửa khóa TOTP, mã dự phòng (xác thực hai lớp) của người dùng trong admin.
can_upload_imageCan upload image directly to server via martorTải ảnh lên máy chủ từ trình soạn thảo Markdown. Người dùng staff luôn được phép.
high_problem_timelimitCan set high problem timelimitĐặt giới hạn thời gian của bài vượt VNOJ_PROBLEM_TIMELIMIT_LIMIT (mặc định 5 giây).
long_contest_durationCan set long contest durationĐặt thời lượng kỳ thi vượt VNOJ_CONTEST_DURATION_LIMIT (mặc định 14 ngày).
create_mass_testcasesCan create unlimitted number of testcases for a problemTạo nhiều test hơn VNOJ_TESTCASE_HARD_LIMIT (mặc định 100) cho một bài; không bị cảnh báo khi vượt VNOJ_TESTCASE_SOFT_LIMIT (mặc định 50).
ban_userBan usersKhóa (ban) tài khoản người dùng. Không ban được chính mình hoặc superuser.

Bài đăng blog (judge · BlogPost)

CodenameNhãnCho phép
edit_all_postEdit all postsSửa mọi bài đăng; xem mọi bài đăng của tổ chức kể cả bài chưa công bố.
edit_organization_postEdit organization postsTạo bài đăng trong tổ chức mà mình quản trị.
mark_global_postMark post as globalĐánh dấu bài đăng tổ chức là "toàn cục" (hiện ở trang chủ).
pin_postPin postGhim bài đăng (trường sticky).
manage_magazine_postManage magazine blog postsSửa thẻ, tác giả và tóm tắt của bài đăng trong biểu mẫu soạn bài.

Bình luận (judge · Comment, CommentLock)

CodenameNhãnCho phép
view_all_user_commentView all comments by a userXem trang tất cả bình luận của một người dùng và ẩn hàng loạt các bình luận đó.
override_comment_lockOverride comment lockVẫn bình luận được trên trang đã bị khóa bình luận.

Quiz (quiz · QuizQuestion)

CodenameNhãnCho phép
edit_own_quizEdit own quizzes and questionsSoạn câu hỏi và bài kiểm tra của mình; xem ngân hàng câu hỏi công khai.
edit_all_quizEdit all quizzes and questionsXem và sửa mọi câu hỏi và bài kiểm tra.

Chi tiết: xem Soạn quiz.

Rút gọn liên kết (urlshortener)

Ứng dụng rút gọn liên kết không khai báo quyền tùy chỉnh mà dùng bốn quyền mặc định của Django: urlshortener.view_urlshortener, add_urlshortener, change_urlshortenerdelete_urlshortener. Chi tiết: xem Rút gọn liên kết.

Các vai trò gợi ý

Đây là điểm khởi đầu, hãy điều chỉnh theo nhu cầu. Nhớ bật Staff status nếu vai trò cần dùng trang quản trị.

Vai tròQuyền gợi ý
Người ra đềedit_own_problem, clone_problem, rejudge_submission, upload_file_statement, can_upload_image
Người ra đề cấp caoNhư trên, thêm edit_public_problem hoặc edit_all_problem, see_private_problem, change_public_visibility, rejudge_submission_lot, import_polygon_package
Ban tổ chức kỳ thiedit_own_contest, clone_contest, contest_access_code, create_private_contest, moss_contest, contest_problem_label
Điều hành viên (moderator)edit_all_post, pin_post, override_comment_lock, view_all_user_comment, ban_user
Giáo viên soạn quizedit_own_quiz

Cấp quyền cẩn thận

  • problem_full_markup cho phép chèn HTML không lọc vào đề bài; chỉ cấp cho người thật sự tin cậy.
  • edit_all_problem, edit_all_contest, view_all_submission cho phép xem dữ liệu kỳ thi và mã nguồn của mọi người.
  • Định kỳ rà soát quyền của các nhóm và người dùng, gỡ quyền của người không còn tham gia.

Sự cố thường gặp

Triệu chứngCách khắc phục
Không vào được /admin/ dù đã có quyềnBật Staff status cho tài khoản.
edit_all_problem nhưng vẫn không sửa được bàiCấp thêm edit_own_problem; thiếu quyền này thì edit_public_problemedit_all_problem không có tác dụng.
Không tìm thấy quyền trong danh sáchTìm theo codename thay vì nhãn. Nếu nhãn cũ, chạy ./scripts/manage.py update_permissions.
Cấp spam_organization nhưng người dùng vẫn bị giới hạn số tổ chứcQuyền này hiện chỉ có tác dụng với superuser (xem cảnh báo ở mục Tổ chức).
Chấm lại hàng loạt bị giới hạn 10 bàiCấp thêm rejudge_submission_lot.

Tiếp theo