Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# moodle-factor_user

* [What is this?](#what-is-this)
* [Branches](#branches)
* [Installation](#installation)
* [Configuration](#configuration)
* [Support](#support)

## What is this?

This is a factor plugin for the Moodle [MFA Plugin](https://github.com/moodle/moodle/tree/main/admin/tool/mfa) which allows specific user accounts to be exempted from MFA requirements entirely.

Users listed in the configuration will automatically **pass** this factor, bypassing the need for any additional authentication. All other users receive a neutral result, meaning this factor does not affect them and other configured factors will determine their MFA requirement as normal.

This is intended for **integration accounts** or **service accounts** that authenticate programmatically and cannot complete interactive MFA challenges.

## Branches

| Moodle version | Branch |
|---|---|
| Moodle 4.5+ | `main` |

## Installation

Clone or copy this plugin into your Moodle installation:

```bash
git clone https://github.com/catalyst/moodle-factor_user admin/tool/mfa/factor/user
```

Then run the upgrade:

```bash
php admin/cli/upgrade.php
```

Or complete the upgrade via **Site administration → Notifications**.

## Configuration

1. Go to **Site administration → Security → Multi-factor authentication**.
2. Enable and configure the **Exempted users** factor.
3. Set the **weight** to a value that, on its own, satisfies your MFA threshold (typically 100).
4. In the **Exempted usernames** textarea, enter one username per line for each account that should bypass MFA.

### Example

```
integration_api
lms_sync_account
hr_feed_user
```

Any user whose username appears in this list will pass MFA automatically. Users not on the list are unaffected by this factor.

### Recommended setup

Combine this factor with your normal MFA factors (e.g. TOTP, Email). Ensure this factor is ordered **before** the others so exempted accounts are passed immediately without being prompted for a second factor.

## Security issues

> **Note:** This plugin is a workaround. Ideally, integration and service accounts should be configured with the **No login** (`nologin`) or **Web services** (`webservice`) authentication method in Moodle. Accounts using these auth methods cannot log in via the standard login form and are therefore naturally exempt from MFA without needing this plugin. Use this factor only when those auth methods are not an option for your integration.

Granting MFA exemptions reduces security for the affected accounts. Ensure that:

- Only non-interactive service/integration accounts are added to the exemption list.
- Exempted accounts use strong, unique passwords and have minimal permissions.

If you find a security issue with this or any Catalyst plugin, please **do not** open a GitHub issue. Instead, responsibly disclose the issue in private via email:

security@catalyst-au.net

## Support

If you have issues please log them in GitHub.

This plugin was developed by Catalyst IT Australia:

https://www.catalyst-au.net

<img alt="Catalyst IT" src="https://cdn.rawgit.com/CatalystIT-AU/moodle-auth_saml2/master/pix/catalyst-logo.svg" width="400">
1 change: 0 additions & 1 deletion classes/factor.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class factor extends object_factor_base {

/**
* User factor implementation.
* This factor is a singleton, return single instance.
Expand Down
1 change: 0 additions & 1 deletion classes/privacy/provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements null_provider {

/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
Expand Down
30 changes: 22 additions & 8 deletions settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,37 @@
defined('MOODLE_INTERNAL') || die();

if ($ADMIN->fulltree) {
$settings->add(new admin_setting_heading('factor_user/description', '',
new lang_string('settings:description', 'factor_user')));
$settings->add(new admin_setting_heading(
'factor_user/description',
'',
new lang_string('settings:description', 'factor_user')
));
$settings->add(new admin_setting_heading('factor_user/settings', new lang_string('settings', 'moodle'), ''));

$enabled = new admin_setting_configcheckbox('factor_user/enabled',
$enabled = new admin_setting_configcheckbox(
'factor_user/enabled',
new lang_string('settings:enablefactor', 'tool_mfa'),
new lang_string('settings:enablefactor_help', 'tool_mfa'), 0);
new lang_string('settings:enablefactor_help', 'tool_mfa'),
0
);
$enabled->set_updatedcallback(function () {
\tool_mfa\manager::do_factor_action('user', get_config('factor_user', 'enabled') ? 'enable' : 'disable');
});
$settings->add($enabled);

$settings->add(new admin_setting_configtext('factor_user/weight',
$settings->add(new admin_setting_configtext(
'factor_user/weight',
new lang_string('settings:weight', 'tool_mfa'),
new lang_string('settings:weight_help', 'tool_mfa'), 100, PARAM_INT));
new lang_string('settings:weight_help', 'tool_mfa'),
100,
PARAM_INT
));

$settings->add(new admin_setting_configtextarea('factor_user/usernames',
$settings->add(new admin_setting_configtextarea(
'factor_user/usernames',
new lang_string('settings:usernames', 'factor_user'),
new lang_string('settings:usernames_help', 'factor_user'), '', PARAM_TEXT));
new lang_string('settings:usernames_help', 'factor_user'),
'',
PARAM_TEXT
));
}
1 change: 0 additions & 1 deletion tests/factor_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class factor_test extends \advanced_testcase {

/**
* Tests that a user in the exemption list receives STATE_PASS.
*
Expand Down
2 changes: 1 addition & 1 deletion version.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

defined('MOODLE_INTERNAL') || die();

$plugin->version = 2026072900; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2026072901; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024100100; // Requires this Moodle version (4.5).
$plugin->component = 'factor_user'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;
Loading