Archives quiz attempts as PDF and HTML files for long-term storage independent
of Moodle. If desired, Moodle backups (.mbz
) of both the quiz and the whole
course can be included. A checksum is calculated for every file within the
archive, as well as the archive itself, to allow verification of file integrity.
Archives can optionally be cryptographically signed by a trusted authority using
the Time-Stamp Protocol (TSP).
Comprehensive archive settings allow selecting what should be included in the
generated reports on a fine-granular level (e.g., exclude example solutions,
include answer history, ...).
Generated quiz attempt reports include all elements of the test, even complex ones like MathJax formulas, STACK plots, GeoGebra applets, and other question / content types that require JavaScript processing. All PDF and HTML files are fully text-searchable, including rendered MathJax formulas. Content is saved vector based, whenever possible, to allow high-quality printing and zooming while keeping the file size down.
Quiz archives are created by an external quiz archive worker service to remove load from Moodle and to eliminate the need to install a large number of software dependencies on the webserver. It can easily be deployed using Docker.
Available via the Moodle Plugin Directory:
- Archiving of quiz attempts as PDF and HTML files
- Support for file submissions / attachments (e.g., essay files)
- Quiz attempt reports are accessible completely independent of Moodle, hereby ensuring long-term readability
- Customization of generated PDF and HTML reports
- Allows creation of reduced reports, e.g., without example solutions, for handing out to students during inspection
- Support for complex content and question types, including Drag and Drop, MathJax formulas, STACK plots, and other question / content types that require JavaScript processing
- Quiz attempt reports are fully text-searchable, including mathematical formulas
- Moodle backups (
.mbz
) of both the quiz and the whole course are supported - Generation of checksums for every file within the archive and the archive itself
- Cryptographic signing of archives and their creation date using the Time-Stamp Protocol (TSP)
- Archive and attempt report names are fully customizable and support dynamic variables (e.g., course name, quiz name, username, ...)
- Fine granular permission / capability management (e.g., only allow archive creation but prevent deletion)
- Allows definition of global archiving defaults as well as forced archiving policies (i.e., locked archive job presets that cannot be changed by the user)
- Fully asynchronous archive creation to reduce load on Moodle Server
- Automatic deletion of quiz archives after a specified retention period
- Data compression and vector based MathJax formulas to preserve disk space
- Technical separation of Moodle and archive worker service
- Data-minimising and security driven design
Archive jobs are execute via an external quiz archive worker service. It uses the Moodle webservice API to query the required data and to upload the created archive.
This plugin prepares the archive job within Moodle, provides quiz data to the archive worker, handles data validation, and stores the created quiz archives inside the Moodle filestore. Created archives can be managed and downloaded via the Moodle web interface. A unique webservice access token is generated for every archive job. Each token has a limited validity and is invalidated either after job completion or after a specified timeout. This process requires a dedicated webservice user to be created (see Configuration). A single job webservice token can only be used for the specific quiz that is associated with the job to restrict queryable data to the required minimum.
You can install this plugin like any other Moodle plugin, as described below. However, keep in mind that you additionally need to deploy the external quiz archive worker service for this plugin to work.
- Log in to your Moodle site as an admin and go to Site administration > Plugins > Install plugins.
- Upload the ZIP file with the plugin code. You should only be prompted to add extra details if your plugin type is not automatically detected.
- Check the plugin validation report and finish the installation.
The plugin can be also installed by putting the contents of this directory to
{your/moodle/dirroot}/mod/quiz/report/archiver
Afterward, log in to your Moodle site as an admin and go to Site administration > Notifications to complete the installation.
Alternatively, you can run
$ php admin/cli/upgrade.php
to complete the installation from the command line.
The following sections describe the required steps to set up the plugin.
In summary: You need to create a dedicated Moodle user, a global role to manage permissions, setup a webservice for the archive worker, and set configuration options for the Moodle plugin.
Installation of the additional quiz archive worker service is mandatory for this plugin to work.
Detailed installation instructions can be found here: Quiz Archive Worker: Installation
Creation of the dedicated Moodle user and role, as well as the setup of the webservice for the archive worker, can be done automatically.
The easiest way is to use the automatic configuration feature provided via the Moodle admin interface.
- Navigate to Site Administration > Plugins (1) > Activity modules > Quiz > Quiz Archiver (2)
- Click the Automatic configuration button (3)
- Enter the URL under which the quit archive worker can be reached (4)
- (Optional) Change the configuration defaults (5)
- Execute the automatic configuration (6)
- Close the window (7)
- (Optional) Adjust the default plugin setting on the plugin settings page
Expand here to show CLI configuration instructions
If you want to configure this plugin in an automated fashion, you can use the
provided CLI script. The script is located at
{$CFG->wwwroot}/mod/quiz/report/archiver/cli/autoinstall.php
.
To execute the script:
- Open a terminal and navigate to the quiz archiver CLI directory:
cd /path/to/moodle/mod/quiz/report/archiver/cli
- Execute the CLI script using PHP:
php autoinstall.php --help
Usage:
Automatically configures Moodle for use with the quiz archiver plugin.
ATTENTION: This CLI script ...
- Enables web services and REST protocol
- Creates a quiz archiver service role and a corresponding user
- Creates a new web service with all required webservice functions
- Authorises the user to use the webservice.
Usage:
$ php autoinstall.php
$ php autoinstall.php --username="my-custom-archive-user"
$ php autoinstall.php [--help|-h]
Options:
--help, -h Show this help message
--force, -f Force the autoinstall, regardless of the current state of the system
--workerurl=<value> Sets the URL of the worker (default: http://localhost:8080)
--wsname=<value> Sets a custom name for the web service (default: quiz_archiver_webservice)
--rolename=<value> Sets a custom name for the web service role (default: quiz_archiver)
--username=<value> Sets a custom username for the web service user (default: quiz_archiver_serviceaccount)
Expand here to show manual configuration instructions
-
Create a designated Moodle user for the quiz archiver webservice
- Navigate to Site Administration > Users (1) > Accounts > Add a new user (2)
- Set a username (e.g.
quiz_archiver
) (3), a password (4), first and lastname (5), and a hidden email address (6) - Create the user (7)
-
Create a global role to handle permissions for the
quiz_archiver
Moodle user- Navigate to Site Administration > Users (1) > Permissions > Define roles (2)
- Select Add a new role (3)
- Set Use role or archetype (4) to
No role
- Upload the role definitions file from res/moodle_role_quiz_archiver.xml (5). This will automatically assign all required capabilities. You can check all capabilities prior to role creation in the next step or by manually inspecting the role definition XML file.
- Click on Continue (6) to import the role definitions for review
- Optionally change the role name or description and create the role (7)
-
Assign the
quiz_archiver
Moodle user to the created role- Navigate to Site Administration > Users (1) > Permissions > Assign system roles (2)
- Select the
Quiz Archiver Service Account
role (3) - Search the created
quiz_archiver
Moodle user (4), select it in the list of potential users (5), and add it to the role (6)
-
Enable webservices globally
- Navigate to Site Administration > Server (1) > Web services > Overview (2)
- Click on Enable web services (3), check the checkbox (4), and save the changes (5)
- Navigate back to the Overview (2) page
- Click on Enable protocols (6), enable the REST protocol (7), and save the changes (8)
-
Create an external webservice for the quiz archive worker to use
- Navigate to Site Administration > Server (1) > Web services > External services (2)
- Under the Custom services section, select Add (3)
- Enter a name (e.g.
quiz_archiver
) (4) and enable it (5) - Expand the additional settings (6), enable file up- and download (7)
- Create the new webservice by clicking Add service (8)
-
Add all
quiz_archiver_*
webservice functions to thequiz_archiver
external service- Navigate to Site Administration > Server (1) > Web services > External services (2)
- Open the Functions page for the
quiz_archiver
webservice (3) - Click the Add functions link (4)
- Search for
quiz_archiver
(5) and add allquiz_archiver_*
functions - Save the changes by clicking Add functions (6)
- Navigate to Site Administration > Plugins (1) > Activity modules > Quiz > Quiz Archiver (2)
- Set
worker_url
(3) to the URL under which the quiz archive worker can be reached (e.g.,http://quiz-archive-worker:5000
orhttp://127.0.0.1:5000
) - Select the previously created
quiz_archiver
webservice forwebservice_id
(4) from the drop-down menu - Enter the user ID of the previously created Moodle user for
webservice_userid
(5). It can easily be found by navigating to the users profile page and inspecting the page URL. It contains the user ID as theid
query parameter. - (Optional) Specify a custom job timeout in minutes
- (Optional) Specify a custom Moodle base URL. This is only required if you run
the quiz archive worker in an internal/private network, e.g., when using
Docker. If this setting is present, the public Moodle
$CFG->wwwroot
will be replaced by theinternal_wwwroot
setting. Example:https://your.public.moodle/
will be replaced byhttp://moodle.local/
. - Save all settings and create your first quiz archive (see Usage).
- (Optional) Adjust the default capability assignments.
- Job timeout prior to configured value
- Be aware that there is a configurable job timeout within the Moodle plugin
settings (
quiz_archiver | job_timeout_min
) as well as one within the quiz archive worker service (QUIZ_ARCHIVER_REQUEST_TIMEOUT_SEC
). Since the shortest timeout always takes precedence, make sure to adjust both settings as required.
- Be aware that there is a configurable job timeout within the Moodle plugin
settings (
- Access to (some) webservice functions fails
- Ensure that webservices and the REST protocol are enabled globally.
- Ensure that all required webservice functions are enabled for the
quiz_archiver
webservice. - Ensure that the
quiz_archiver
webservice has the rights to download and upload files. - Ensure that the
quiz_archiver
webservice user has accepted all site policies (e.g., privacy policy).
- Upload of the final archive fails
- Ensure you have configured
php
to accept large file uploads. Theupload_max_filesize
andpost_max_size
settings in yourphp.ini
should be set to a value that is large enough to allow the upload of the largest quiz archive file that you expect to be created. - Ensure that your Moodle is configured to allow large file uploads.
$CFG->maxbytes
should be set to the same value as PHPupload_max_filesize
. - If you are using an ingress webserver and
php-fpm
via FastCGI, ensure that thefastcgi_send_timeout
andfastcgi_read_timeout
settings are long enough to allow the upload of the largest quiz archive file that you expect. Nginx usually signals this problem by returning a '504 Gateway Time-out' after 60 seconds (default). - Ensure that your antivirus plugin is capable of handling large files. When
using ClamAV you can control maximum file sizes by setting
MaxFileSize
,MaxScanSize
, andStreamMaxLength
(when using a TCP socket) insideclamd.conf
.
- Ensure you have configured
The following capabilities are required for the listed actions:
mod/quiz_archiver:view
(context: Module): Required to view the quiz archiver overview page. It allows to download all created archives but does not allow do create new or delete existing archives (read-only access). By default, assigned to:teacher
,editingteacher
,manager
.mod/quiz_archiver:create
(context: Module): Allows creation of new quiz archives (read-write access). By default, assigned to:editingteacher
,manager
.mod/quiz_archiver:delete
, (context: Module): Allows deletion of existing quiz archives (read-write access). By default, assigned to:editingteacher
,manager
.mod/quiz_archiver:use_webservice
(context: System): Required to use any of the webservice functions this plugin provides. The webservice user (created in Configuration) needs to have this capability in order to create new quiz archives.
Once installed and set up, quizzes can be archived by performing the following steps:
- Navigate to a Moodle quiz
- Inside the
Quiz administration
menu expand theResults
section and click onQuiz Archiver
- Select the desired options and start the archive job by clicking the
Archive quiz
button - Wait until the archive job is completed. You can now download the archive
from the
Quiz Archiver
page using theDownload archive
button.
Created archives can be deleted by clicking the Delete archive
button. Details,
including all selected settings during archive creation, e.g. number of attempts
or included components, can be viewed by clicking the Details
button.
If you encounter permission errors, ensure that the user has the required Capabilities assigned.
This section discusses advanced usage of the plugin.
Default values for all archive job options can be configured globally via the plugin settings page. By default, users are allowed to customize these settings during archive creation. However, each setting can be locked individually to prevent users from modifying it during archive creation. This allows the enforcement of organization wide policies for archived quizzes.
To customize these options:
- Navigate to Site Administration > Plugins (1) > Activity modules > Quiz > Quiz Archiver (2)
- Scroll down to the Archive presets section (3)
- Set the desired default values for each option (4)
- Options can depend on another, as indicated by (6). This causes the dependent option to be disabled, if the parent option is not set (e.g., question feedback is not exported if question exporting is fully disabled)
- More options than shown in the screenshots are available. Scroll down to see all (7)
- (Optional) Lock individual options by checking the Lock checkbox (5)
Locked options will be grayed out during archive creation (8).
Quiz archives can be automatically deleted after a specified retention period. Automatic deletion can either be controlled on a per-archive basis or globally via the archive job presets. Archives with expired lifetimes are deleted by an asynchronous task that is, by default, scheduled to run every hour. Only the archived user data (attempt PDFs, attachments, ...) is deleted, while the job metadata is kept until manually deleted. This procedure allows to document the deletion of archive data in a traceable manner, while the privacy relevant user data is deleted.
If an archive is scheduled for automatic deletion, its remaining lifetime is shown in the job details modal, as depict above. You can access it via the Show details button on the quiz archiver overview page. Once deleted, archives change their status from 'Finished' to 'Deleted'. If you try to delete an archive that is scheduled for automatic deletion before its retention period expired, an extra warning message will be shown.
To enable the scheduled deletion for a single quiz archive:
- Navigate to the quiz archiver overview page
- Expand the Advanced settings section of the Create new quiz archive form
- Check the Automatic deletion checkbox (1)
- Set the desired retention period (2)
- Create the archive job (3)
Like any other archive settings, automatic deletion can be configured globally using the archive job presets.
Quiz archives and their creation date can be digitally signed by a trusted authority using the Time-Stamp Protocol (TSP) according to RFC 3161. This can be used to cryptographically prove the integrity and creation date of the archive at a later point in time. Quiz archives can be signed automatically at creation or manually later on.
- Navigate to Site Administration > Plugins (1) > Activity modules > Quiz > Quiz Archiver (2)
- Set
tsp_server_url
(3) to the URL of your desired TSP service - Globally enable archive signing by checking
tsp_enable
(4) - (Optional) Enable automatic archive signing by checking
tsp_automatic_signing
(5) - Save all settings (6)
Both the TSP query and the TSP response can be accessed via the job details dialog. To do so, navigate to the quiz archiver overview page and click the Show details button for the desired archive job.
If enabled, new archives will be automatically signed during creation. TSP data can be accessed via the Show details button of an archive job on the quiz archiver overview page. Existing archives will not be signed automatically (see Manual archive signing).
To manually sign a quiz archive, navigate to the quiz archiver overview page, click the Show details button for the desired archive job, and click the Sign archive now button.
To validate an archive and its signature, install openssl
and follow these
steps:
- Obtain the certificate files from your TSP authority (
.crt
and.pem
) - Navigate to the quiz archiver overview page and click the Show details button for the desired archive job
- Download the archive and both TSP signature files (
.tsq
and.tsr
) - Inspect TSP response to see time stamp and signed hash value
- Execute:
openssl ts -reply -in <archive>.tsr -text
- Execute:
- Verify the quiz archive against the TSP response. This process confirms that
the archive was signed by the TSP authority and that the archive was not
modified after signing, i.e., the hash values of the file matches the TSP
response.
- Execute:
openssl ts -verify -in <archive>.tsr -data <archive>.tar.gz -CAfile <tsa>.pem -untrusted <tsa>.crt
- Verify that the output is
Verification: OK
Errors are indicated byVerification: FAILED
- Execute:
- (Optional) Verify that TSP request and TSP response match
- Execute:
openssl ts -verify -in <archive>.tsr -queryfile <archive>.tsq -CAfile <tsa>.pem -untrusted <tsa>.crt
- Verify that the output is
Verification: OK
Errors are indicated byVerification: FAILED
- Execute:
For testing, a Moodle course that contains a reference quiz is provided. The quiz features an instance of every standard question type that is provided by Moodle. Example students are enrolled and possess graded attempts, ready to test the archive functionality.
You can import the reference course from the corresponding Moodle backup file located at res/backup-moodle2-course-qa-ref.mbz.
2024 Niels Gandraß [email protected]
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.