Moodle Plugins directory: Registration Rules | Moodle.org

Registration Rules
Moodle Registration Rules
The Registration Rules plugin enhances user account registration control in Moodle by incorporating various anti-spam measures and reCAPTCHA alternatives, to prevent automated spam bots from creating fake accounts.
🚀 List of features
- Extend the signup form to include reCAPTCHA alternatives from ALTCHA, Cloudflare Turnstile and hCaptcha
- Prevent accounts from being created with disposable email addresses.
- Check, warn and/or deny signup if password is listed in the Have I Been Pwned database.
- Check and deny signup if IP address, email address or username are listed in the Stop Forum Spam database.
- Implement other anti-spam measures such as injecting randomised hidden honeypot fields into the signup form, ensuring users take a minimum amount of time to register, rate limiting the number of allowed signups per session or IP address, and more!
- Flexible rules to allow or deny account registration around date/time windows.
- Entirely disable user signups with a single click.
- Apply reCAPTCHA alternatives and other rules to the forgotten password form for further security.
🧐 How it works
The Registration Rules plugin lets you set up a series of flexible rules to control user signups based on specific conditions. Each rule defines a check that is run during the registration process.
How rules are evaluated:
- When a user tries to sign up, the plugin checks their submitted details against the set rules.
- Each rule has a score. If the rule's condition is met, the corresponding score is added to the total.
- After all rules are checked, the plugin compares the total score with a configurable threshold.
- If the total score is below the threshold then registration is allowed. If it is above the threshold, the registration is denied.
📝How to use
Basic usage
-
Install the plugin in Moodle.
-
Browse to "Site administration / Plugins / Admin tools / Registration rules / Rules".
-
Select and configure the rules you want to use via the "Add rule" and/or "Add CAPTCHA" dropdown.
-
Browse to "Site administration / Plugins / Admin tools / Registration rules / Settings" and tick "Enable".
-
While on the general settings page you may wish to consider ticking the "Logging only" option initially, the plugin will then evaluate rules as normal but will only log the results instead of denying user registration.
Forced instances
When you have found your perfect configuration it is possible to enforce this via config.php
so that it cannot be changed via the admin interface, this is particularly useful for deploying sites with a preset configuration.
For more information, click the "View instances JSON" button on the "Rules" page.
Bundled CAPTCHA plugins
ALTCHA challenge
ALTCHA is a free, open-source reCAPTCHA alternative designed to protect your website from spam and abuse. It respects user privacy by avoiding the use of cookies, fingerprinting, or tracking, and is fully compliant with GDPR regulations.
ALTCHA functions by generating a challenge that the user's web browser must solve when they check the "I'm not a robot" box on a signup form. This rule includes a complexity setting, which determines the level of computational effort required to complete the challenge. Higher complexity enhances security but results in a longer wait time for the challenge to be solved.
- This plugin does not require a third party user account and does not communicate with external systems.
Cloudflare Turnstile
Cloudflare Turnstile is a privacy-preserving CAPTCHA alternative designed to verify user interactions without compromising user data. Unlike traditional CAPTCHA systems, Turnstile uses a non-intrusive browser-based challenge and behavioural analysis to differentiate between humans and bots, all without requiring users to solve puzzles or identify objects. Compliant with GDPR, it ensures a seamless and user-friendly experience while maintaining robust security.
- This plugin requires a user account to be created at https://www.cloudflare.com and communicates with external systems.
hCaptcha
hCaptcha is a reCAPTCHA alternative. Unlike some other CAPTCHA solutions, hCaptcha focuses on compliance with privacy laws like GDPR and does not sell user data. It works by presenting users with a visual challenge, such as identifying specific objects in images, to verify they are human.
- This plugin requires a user account to be created at https://www.hcaptcha.com and communicates with external systems.
Bundled rule plugins
Disposable emails
This rule ensures that accounts cannot be created using disposable email addresses. This means that users must provide a valid, permanent email address to register.
Disposable email addresses are temporary and intended for short-term use. They allow people to quickly obtain an email address without sharing their primary one. However, these anonymous addresses can also be misused by bad actors on the Internet, such as spammers.
Have I Been Pwned?!
Check, warn and deny signup if the user's password is listed in the Have I Been Pwned database, a free online service that aggregates details of data breaches.
- This plugin communicates with external systems but does not require you to register for a user account.
Hidden honeypot field
A honeypot field is a hidden field added to the signup form that is designed to trap and identify bots. It is a simple, effective technique for reducing spam and automated submissions on websites.
A random field will be added to the signup form that is invisible to the user, if this field contains data when the form is submitted then it must have been completed by a bot.
Limit by date/time
Control exactly when your users are allowed to register for new accounts by defining flexible rules to allow or deny account registration around date/time windows.
Multiple instances of this rule can be created to allow combinations of time periods where registration will be allowed and disallowed.
Note all selected times are in the default site timezone.
Minimum completion time
This rule helps to prevent spam by measuring how quickly the signup form is filled out and submitted. Since bots can typically complete forms almost instantly, this check helps distinguish between human users and automated account registration.
Nope
Completely disable account registration with one click, displaying a message to users in place of the signup form.
Rate Limit
Prevent brute-force registration attacks by limiting the number of registration attempts based on the user's session and/or IP address. This rule allows administrators to set individual parameters for both session and IP-based rate limiting, specifying the maximum number of allowed attempts within a defined time window. If the limit is exceeded, further registration attempts are temporarily blocked.
Stop Forum Spam
This helps reduce spam account registrations by comparing the submitted username, email address and IP address against a global database of known spammers provided by the free Stop Forum Spam service, an effective layer of protection against automated and malicious account creation.
- This plugin communicates with external systems but does not require you to register for a user account.
Verify Mail Server
This rule ensures that the email domain provided during registration has valid mail server DNS records, known as MX records. These indicate that the domain is configured to handle email traffic, helping to prevent signups using non-functional or randomly generated email addresses.
Proudly developed in MoodleMoot DACH 2024
Moodle Registration Rules was originally developed during MoodleMoot DACH 2024 as a collaboration between Dale Davies from Catalyst IT Europe, Philipp Hager and Andreas Hruska from eDaktik, Lukas Müller from lern.link and Michael Aherne from University of Strathclyde.
I've got a few things ready for a new release so I'll see if this can be included too.
I get a Exception - Call to undefined function tool_registrationrules\local\login_captcha_enabled()
when I try to add rules. This is the stack trace:
line 508 of /admin/tool/registrationrules/classes/local/rule_instances_controller.php: Error thrown
line 741 of /admin/tool/registrationrules/classes/local/rule_instances_controller.php: call to tool_registrationrules\local\rule_instances_controller->new_instance_of_type_allowed()
line 544 of /admin/tool/registrationrules/classes/local/rule_instances_controller.php: call to tool_registrationrules\local\rule_instances_controller->get_types_for_add_menu()
line 266 of /lib/outputrenderers.php: call to tool_registrationrules\local\rule_instances_controller->export_for_template()
line 104 of /admin/tool/registrationrules/manageruleinstances.php: call to renderer_base->render()
Do you have an idea what could be the issue?
TIA
Demars - This release includes the updte to add rules to the forgotten password page as discussed.
Many thanks everyone
parent does not exist!
line 943 of /lib/adminlib.php: call to debugging()
line 34 of /admin/tool/registrationrules/settings.php: call to admin_category->add()
line 81 of /lib/classes/plugininfo/tool.php: call to include()
line 735 of /admin/settings/plugins.php: call to core\plugininfo\tool->load_settings()
line 8878 of /lib/adminlib.php: call to require()
line 4510 of /lib/navigationlib.php: call to admin_get_root()
line 4377 of /lib/navigationlib.php: call to settings_navigation->load_administration_settings()
line 838 of /lib/pagelib.php: call to settings_navigation->initialise()
line 967 of /lib/pagelib.php: call to moodle_page->magic_get_settingsnav()
line 761 of /lib/classes/navigation/views/secondary.php: call to moodle_page->__get()
line 236 of /lib/classes/navigation/views/secondary.php: call to core\navigation\views\secondary->load_admin_navigation()
line 895 of /lib/pagelib.php: call to core\navigation\views\secondary->initialise()
line 967 of /lib/pagelib.php: call to moodle_page->magic_get_secondarynav()
line 111 of /theme/tm_moove/layout/drawers.php: call to moodle_page->__get()
line 1477 of /lib/outputrenderers.php: call to include()
line 1403 of /lib/outputrenderers.php: call to core_renderer->render_page_layout()
line 1973 of /lib/setuplib.php: call to core_renderer->header()
line 2944 of /lib/weblib.php: call to bootstrap_renderer->__call()
line 93 of /course/loginas.php: call to notice()
parent does not exist!
line 943 of /lib/adminlib.php: call to debugging()
line 96 of /admin/tool/registrationrules/settings.php: call to admin_category->add()
line 81 of /lib/classes/plugininfo/tool.php: call to include()
line 735 of /admin/settings/plugins.php: call to core\plugininfo\tool->load_settings()
line 8878 of /lib/adminlib.php: call to require()
line 4510 of /lib/navigationlib.php: call to admin_get_root()
line 4377 of /lib/navigationlib.php: call to settings_navigation->load_administration_settings()
line 838 of /lib/pagelib.php: call to settings_navigation->initialise()
line 967 of /lib/pagelib.php: call to moodle_page->magic_get_settingsnav()
line 761 of /lib/classes/navigation/views/secondary.php: call to moodle_page->__get()
line 236 of /lib/classes/navigation/views/secondary.php: call to core\navigation\views\secondary->load_admin_navigation()
line 895 of /lib/pagelib.php: call to core\navigation\views\secondary->initialise()
line 967 of /lib/pagelib.php: call to moodle_page->magic_get_secondarynav()
line 111 of /theme/tm_moove/layout/drawers.php: call to moodle_page->__get()
line 1477 of /lib/outputrenderers.php: call to include()
line 1403 of /lib/outputrenderers.php: call to core_renderer->render_page_layout()
line 1973 of /lib/setuplib.php: call to core_renderer->header()
line 2944 of /lib/weblib.php: call to bootstrap_renderer->__call()
line 93 of /course/loginas.php: call to notice()
parent does not exist!
line 943 of /lib/adminlib.php: call to debugging()
line 101 of /admin/tool/registrationrules/settings.php: call to admin_category->add()
line 81 of /lib/classes/plugininfo/tool.php: call to include()
line 735 of /admin/settings/plugins.php: call to core\plugininfo\tool->load_settings()
line 8878 of /lib/adminlib.php: call to require()
line 4510 of /lib/navigationlib.php: call to admin_get_root()
line 4377 of /lib/navigationlib.php: call to settings_navigation->load_administration_settings()
line 838 of /lib/pagelib.php: call to settings_navigation->initialise()
line 967 of /lib/pagelib.php: call to moodle_page->magic_get_settingsnav()
line 761 of /lib/classes/navigation/views/secondary.php: call to moodle_page->__get()
line 236 of /lib/classes/navigation/views/secondary.php: call to core\navigation\views\secondary->load_admin_navigation()
line 895 of /lib/pagelib.php: call to core\navigation\views\secondary->initialise()
line 967 of /lib/pagelib.php: call to moodle_page->magic_get_secondarynav()
line 111 of /theme/tm_moove/layout/drawers.php: call to moodle_page->__get()
line 1477 of /lib/outputrenderers.php: call to include()
line 1403 of /lib/outputrenderers.php: call to core_renderer->render_page_layout()
line 1973 of /lib/setuplib.php: call to core_renderer->header()
line 2944 of /lib/weblib.php: call to bootstrap_renderer->__call()
line 93 of /course/loginas.php: call to notice()
parent does not exist!
line 943 of /lib/adminlib.php: call to debugging()
line 110 of /admin/tool/registrationrules/settings.php: call to admin_category->add()
line 81 of /lib/classes/plugininfo/tool.php: call to include()
line 735 of /admin/settings/plugins.php: call to core\plugininfo\tool->load_settings()
line 8878 of /lib/adminlib.php: call to require()
line 4510 of /lib/navigationlib.php: call to admin_get_root()
line 4377 of /lib/navigationlib.php: call to settings_navigation->load_administration_settings()
line 838 of /lib/pagelib.php: call to settings_navigation->initialise()
line 967 of /lib/pagelib.php: call to moodle_page->magic_get_settingsnav()
line 761 of /lib/classes/navigation/views/secondary.php: call to moodle_page->__get()
line 236 of /lib/classes/navigation/views/secondary.php: call to core\navigation\views\secondary->load_admin_navigation()
line 895 of /lib/pagelib.php: call to core\navigation\views\secondary->initialise()
line 967 of /lib/pagelib.php: call to moodle_page->magic_get_secondarynav()
line 111 of /theme/tm_moove/layout/drawers.php: call to moodle_page->__get()
line 1477 of /lib/outputrenderers.php: call to include()
line 1403 of /lib/outputrenderers.php: call to core_renderer->render_page_layout()
line 1973 of /lib/setuplib.php: call to core_renderer->header()
line 2944 of /lib/weblib.php: call to bootstrap_renderer->__call()
line 93 of /course/loginas.php: call to notice()