From 1db044c38d9c89aaf518307b94cfcc7671451aca Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Mon, 1 Jan 2024 01:05:43 -0800 Subject: [PATCH] allow customization of admin course ID --- conf/site.conf.dist | 10 ++++++++++ lib/Mojolicious/WeBWorK.pm | 3 ++- lib/WeBWorK.pm | 2 +- lib/WeBWorK/Authz.pm | 2 +- lib/WeBWorK/ContentGenerator/CourseAdmin.pm | 5 +++-- lib/WeBWorK/Utils/CourseManagement.pm | 6 +++--- lib/WeBWorK/Utils/Routes.pm | 6 ++++-- lib/WebworkWebservice/CourseActions.pm | 3 ++- templates/ContentGenerator/Base/admin_links.html.ep | 3 ++- templates/ContentGenerator/Base/links.html.ep | 4 ++-- templates/ContentGenerator/CourseAdmin.html.ep | 2 +- .../CourseAdmin/add_course_form.html.ep | 2 +- .../CourseAdmin/archive_course_confirm.html.ep | 2 +- templates/ContentGenerator/Home.html.ep | 5 +++-- .../Instructor/FileManager/refresh.html.ep | 2 +- 15 files changed, 37 insertions(+), 20 deletions(-) diff --git a/conf/site.conf.dist b/conf/site.conf.dist index 0a05fcfa7d..4d806d2376 100644 --- a/conf/site.conf.dist +++ b/conf/site.conf.dist @@ -68,6 +68,16 @@ $server_root_url = ''; # Be sure to use single quotes for the address or the @ sign will be interpreted as an array. $webwork_server_admin_email = ''; +# The follwing is the name of the admin course where admin level users can log +# in and create courses, delete courses, and more. It is 'admin' by default but +# you may want to change to something that cannot be guessed for security reasons. +# While installing WeBWorK, leave this as 'admin'. Once everything is running well, +# use the 'admin' course to create a new course to serve as the admin course. You +# may need to copy all archives from the 'admin' course into this new course. Then +# change $admin_course_id to the ID of the new course and restart webwork2. You may +# then also want to archive and delete the original 'admin' course. +$admin_course_id = 'admin'; + # password strings (or any other string allowing special characters) should be specified inside single quotes # otherwise a string such as "someone@nowhere" will interpolate the contents of the array @nowhere -- which is probably # empty, but still not what you want. Similar things happen with % and $ diff --git a/lib/Mojolicious/WeBWorK.pm b/lib/Mojolicious/WeBWorK.pm index 5eff7a429d..c3c495f02f 100644 --- a/lib/Mojolicious/WeBWorK.pm +++ b/lib/Mojolicious/WeBWorK.pm @@ -248,7 +248,8 @@ sub startup ($app) { $cg_r->get('/')->to('Home#go')->name('root'); # The course admin route is set up here because of its special stash value. - $cg_r->any('/admin')->to('CourseAdmin#go', courseID => 'admin')->name('course_admin'); + $cg_r->any("/$ce->{admin_course_id}")->to('CourseAdmin#go', courseID => $ce->{admin_course_id}) + ->name('course_admin'); setup_content_generator_routes($cg_r); diff --git a/lib/WeBWorK.pm b/lib/WeBWorK.pm index dd4f12e1a2..24b7ba37e2 100644 --- a/lib/WeBWorK.pm +++ b/lib/WeBWorK.pm @@ -197,7 +197,7 @@ async sub dispatch ($c) { return (0, 'This course does not exist.') unless (-e $ce->{courseDirs}{root} - || -e "$ce->{webwork_courses_dir}/admin/archives/$routeCaptures{courseID}.tar.gz"); + || -e "$ce->{webwork_courses_dir}/$ce->{admin_course_id}}/archives/$routeCaptures{courseID}.tar.gz"); return (0, 'This course has been archived and closed.') unless -e $ce->{courseDirs}{root}; debug("...we can create a database object...\n"); diff --git a/lib/WeBWorK/Authz.pm b/lib/WeBWorK/Authz.pm index c1c6bc9dff..5ad39fa83e 100644 --- a/lib/WeBWorK/Authz.pm +++ b/lib/WeBWorK/Authz.pm @@ -263,7 +263,7 @@ sub hasPermissions { # Elevate all permissions greater than a student in the admin course to the # create_and_delete_courses level. This way a user either has access to all # or only student level permissions tools in the admin course. - if (defined($ce->{courseName}) && $ce->{courseName} eq 'admin') { + if (defined($ce->{courseName}) && $ce->{courseName} eq $ce->{admin_course_id}) { my $admin_permlevel = $userRoles->{ $permissionLevels->{create_and_delete_courses} }; $role_permlevel = $admin_permlevel if $role_permlevel > $userRoles->{student} && $role_permlevel < $admin_permlevel; diff --git a/lib/WeBWorK/ContentGenerator/CourseAdmin.pm b/lib/WeBWorK/ContentGenerator/CourseAdmin.pm index b589101971..ec01ca7c87 100644 --- a/lib/WeBWorK/ContentGenerator/CourseAdmin.pm +++ b/lib/WeBWorK/ContentGenerator/CourseAdmin.pm @@ -322,7 +322,8 @@ sub do_add_course ($c) { for my $userID ($db->listUsers) { if ($userID eq $add_initial_userID) { $c->addbadmessage($c->maketext( - 'User "[_1]" will not be copied from admin course as it is the initial instructor.', $userID + 'User "[_1]" will not be copied from [_2] course as it is the initial instructor.', $userID, + $ce->{admin_course_id} )); next; } @@ -1264,7 +1265,7 @@ sub do_unarchive_course ($c) { unarchiveCourse( newCourseID => $new_courseID, oldCourseID => $unarchive_courseID =~ s/\.tar\.gz$//r, - archivePath => "$ce->{webworkDirs}{courses}/admin/archives/$unarchive_courseID", + archivePath => "$ce->{webworkDirs}{courses}/$ce->{admin_course_id}/archives/$unarchive_courseID", ce => $ce, ); diff --git a/lib/WeBWorK/Utils/CourseManagement.pm b/lib/WeBWorK/Utils/CourseManagement.pm index b8a18a2c2b..9be0f79179 100644 --- a/lib/WeBWorK/Utils/CourseManagement.pm +++ b/lib/WeBWorK/Utils/CourseManagement.pm @@ -132,7 +132,7 @@ Lists the courses which have been archived (end in .tar.gz). sub listArchivedCourses { my ($ce) = @_; - my $archivesDir = "$ce->{webworkDirs}{courses}/admin/archives"; + my $archivesDir = "$ce->{webworkDirs}{courses}/$ce->{admin_course_id}/archives"; surePathToFile($ce->{webworkDirs}{courses}, "$archivesDir/test"); # Ensure archives directory exists. return grep {m/\.tar\.gz$/} readDirectory($archivesDir); } @@ -754,7 +754,7 @@ sub archiveCourse { # tmp_archive_path is used as the target of the tar.gz operation. # After this is done the final tar.gz file is moved either to the admin course archives directory - # course/admin/archives or the supplied archive_path option if it is present. + # course/$ce->{admin_course_id}/archives or the supplied archive_path option if it is present. # This prevents us from tarring a directory to which we have just added a file # see bug #2022 -- for error messages on some operating systems my $uuidStub = create_uuid_as_string(); @@ -765,7 +765,7 @@ sub archiveCourse { if (defined $options{archive_path} && $options{archive_path} =~ /\S/) { $archive_path = $options{archive_path}; } else { - $archive_path = "$ce->{webworkDirs}{courses}/admin/archives/$courseID.tar.gz"; + $archive_path = "$ce->{webworkDirs}{courses}/$ce->{admin_course_id}/archives/$courseID.tar.gz"; surePathToFile($ce->{webworkDirs}{courses}, $archive_path); } diff --git a/lib/WeBWorK/Utils/Routes.pm b/lib/WeBWorK/Utils/Routes.pm index acddc7608f..7e83906980 100644 --- a/lib/WeBWorK/Utils/Routes.pm +++ b/lib/WeBWorK/Utils/Routes.pm @@ -26,7 +26,7 @@ PLEASE FOR THE LOVE OF GOD UPDATE THIS IF YOU CHANGE THE ROUTES BELOW!!! root / - course_admin /admin -> logout, options, instructor_tools + course_admin /$admin_course_id -> logout, options, instructor_tools render_rpc /render_rpc instructor_rpc /instructor_rpc @@ -158,7 +158,9 @@ my %routeParameters = ( course_admin => { title => x('Course Administration'), module => 'CourseAdmin', - path => '/admin' + path => '/$ce->{admin_course_id}' + #path => '/admin-dev' + #path => '/$admin_course_id' }, render_rpc => { diff --git a/lib/WebworkWebservice/CourseActions.pm b/lib/WebworkWebservice/CourseActions.pm index 3616e23b73..9590a2e205 100644 --- a/lib/WebworkWebservice/CourseActions.pm +++ b/lib/WebworkWebservice/CourseActions.pm @@ -40,7 +40,8 @@ sub createCourse { die "Course actions disabled by configuration.\n" unless $admin_ce->{webservices}{enableCourseActions}; # Only users from the admin course with appropriate permissions are allowed to create a course. - die "Course creation allowed only for admin course users.\n" unless $admin_ce->{courseName} eq 'admin'; + die "Course creation allowed only for admin course users.\n" + unless $admin_ce->{courseName} eq $admin_ce->{admin_course_id}; die "Course ID cannot exceed $admin_ce->{maxCourseIdLength} characters.\n" if length($params->{name}) > $admin_ce->{maxCourseIdLength}; diff --git a/templates/ContentGenerator/Base/admin_links.html.ep b/templates/ContentGenerator/Base/admin_links.html.ep index 0739df6bb2..c09957c57a 100644 --- a/templates/ContentGenerator/Base/admin_links.html.ep +++ b/templates/ContentGenerator/Base/admin_links.html.ep @@ -2,11 +2,12 @@
  • % if ($authz->hasPermissions($userID, 'create_and_delete_courses')) { + % my $admin_pattern = qr/$ce->{admin_course_id}$/; % for ( diff --git a/templates/ContentGenerator/Base/links.html.ep b/templates/ContentGenerator/Base/links.html.ep index 3f5c5005b4..a58ac49296 100644 --- a/templates/ContentGenerator/Base/links.html.ep +++ b/templates/ContentGenerator/Base/links.html.ep @@ -1,6 +1,6 @@ % use WeBWorK::Utils qw(jitar_id_to_seq); % -% if ($ce->{courseName} eq 'admin') { +% if ($ce->{courseName} eq $ce->{admin_course_id}) { <%= include 'ContentGenerator/Base/admin_links' =%> % next; % } @@ -77,7 +77,7 @@ % } % - % unless ($restricted_navigation || $courseID eq 'admin') { + % unless ($restricted_navigation || $courseID eq $ce->{admin_course_id}) { % } % diff --git a/templates/ContentGenerator/CourseAdmin.html.ep b/templates/ContentGenerator/CourseAdmin.html.ep index 633e21de7d..2d78f2462e 100644 --- a/templates/ContentGenerator/CourseAdmin.html.ep +++ b/templates/ContentGenerator/CourseAdmin.html.ep @@ -53,7 +53,7 @@ % my @courseIDs = listCourses($ce);
      % for (sort { lc($a) cmp lc($b) } listCourses($ce)) { - % next if $_ eq 'admin' || $_ eq 'modelCourse'; + % next if $_ eq 'modelCourse';
    1. <%= link_to $_ => 'set_list' => { courseID => $_ } =%>
    2. % }
    diff --git a/templates/ContentGenerator/CourseAdmin/add_course_form.html.ep b/templates/ContentGenerator/CourseAdmin/add_course_form.html.ep index a6ab1fa728..26fc768979 100644 --- a/templates/ContentGenerator/CourseAdmin/add_course_form.html.ep +++ b/templates/ContentGenerator/CourseAdmin/add_course_form.html.ep @@ -106,7 +106,7 @@ <%= maketext('To copy the templates and html folders from an existing course, select the course below.') =%>
    - % my @existingCourses = sort { lc($a) cmp lc($b) } grep { $_ ne stash('courseID') } listCourses($ce); + % my @existingCourses = sort { lc($a) cmp lc($b) } listCourses($ce); % unshift(@existingCourses, sort { lc($a) cmp lc($b) } @{ $ce->{modelCoursesForCopy} }); % <%= label_for add_templates_course => maketext('Copy from:'), diff --git a/templates/ContentGenerator/CourseAdmin/archive_course_confirm.html.ep b/templates/ContentGenerator/CourseAdmin/archive_course_confirm.html.ep index 0306175d3c..9385d07be3 100644 --- a/templates/ContentGenerator/CourseAdmin/archive_course_confirm.html.ep +++ b/templates/ContentGenerator/CourseAdmin/archive_course_confirm.html.ep @@ -79,7 +79,7 @@ % if ($all_tables_ok && $directories_ok) { % # No missing tables, missing fields, or directories % # Warn about overwriting an existing archive - % my $archive_path = "$ce2->{webworkDirs}{courses}/admin/archives/$archive_courseID.tar.gz"; + % my $archive_path = "$ce2->{webworkDirs}{courses}/$ce2->{admin_course_id}/archives/$archive_courseID.tar.gz"; % if (-e $archive_path && -w $archive_path) {

    <%= maketext( diff --git a/templates/ContentGenerator/Home.html.ep b/templates/ContentGenerator/Home.html.ep index 45a2c36292..448504c397 100644 --- a/templates/ContentGenerator/Home.html.ep +++ b/templates/ContentGenerator/Home.html.ep @@ -2,10 +2,11 @@ % % my $coursesDir = $ce->{webworkDirs}{courses}; % my @courseIDs = listCourses($ce); +% my $admin_course_id = $ce->{admin_course_id}; %

    <%= maketext('Welcome to WeBWorK!') %>

    % -% if ((grep { $_ eq 'admin' } @courseIDs) && !-f "$coursesDir/admin/hide_directory") { +% if ((grep { $_ eq $admin_course_id } @courseIDs) && !-f "$coursesDir/$admin_course_id/hide_directory") {

    <%= link_to maketext('Course Administration') => url_for('course_admin') =%>

    % } % @@ -13,7 +14,7 @@ %