Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f422ac0e4 |
@@ -9,6 +9,7 @@ Authenticate WordPress user via json web token from Laravel Application.
|
|||||||
- Admin settings page
|
- Admin settings page
|
||||||
- Custom invalid token page
|
- Custom invalid token page
|
||||||
- Optional debug mode with full exception details and stack traces
|
- Optional debug mode with full exception details and stack traces
|
||||||
|
- Configurable role for users created through Mahak authentication
|
||||||
|
|
||||||
Debug mode is disabled by default. An administrator can enable it from **Settings > Mahak Authentication** while troubleshooting. The debug page includes server clock/timezone data, safe JWT timing claims, and a Copy Markdown report. JWT contents, secrets, request parameters, and stack-trace arguments are omitted. Because diagnostic pages still expose server paths and other technical details to visitors of the login URL, disable it again after diagnosing the problem.
|
Debug mode is disabled by default. An administrator can enable it from **Settings > Mahak Authentication** while troubleshooting. The debug page includes server clock/timezone data, safe JWT timing claims, and a Copy Markdown report. JWT contents, secrets, request parameters, and stack-trace arguments are omitted. Because diagnostic pages still expose server paths and other technical details to visitors of the login URL, disable it again after diagnosing the problem.
|
||||||
|
|
||||||
@@ -16,7 +17,9 @@ Debug mode is disabled by default. An administrator can enable it from **Setting
|
|||||||
|
|
||||||
Administrators can check for and install published releases from **Settings > Mahak Authentication**. Updates also appear in WordPress's standard **Plugins** and **Updates** screens.
|
Administrators can check for and install published releases from **Settings > Mahak Authentication**. Updates also appear in WordPress's standard **Plugins** and **Updates** screens.
|
||||||
|
|
||||||
To publish an update, change the plugin `Version` header and `MAHAK_AUTHENTICATE_BRIDGE_VERSION` constant to the same version, commit the change, and push a matching tag such as `v2.3.0` to Mahgit. The Gitea Actions workflow builds and attaches the ZIP required by the WordPress updater.
|
The **New user role** setting defaults to WordPress Default, using the site's current global new-user role without changing it. Administrators can select a different role only for accounts created by this plugin; existing users keep their current roles.
|
||||||
|
|
||||||
|
To publish an update, change the plugin `Version` header and `MAHAK_AUTHENTICATE_BRIDGE_VERSION` constant to the same version, commit the change, and push a matching tag such as `v2.4.0` to Mahgit. The Gitea Actions workflow builds and attaches the ZIP required by the WordPress updater.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* Plugin Name: Mahak Authenticate Bridge
|
* Plugin Name: Mahak Authenticate Bridge
|
||||||
* Plugin URI: https://mahgit.ir/dabestaniha/mahak-authenticate-bridge
|
* Plugin URI: https://mahgit.ir/dabestaniha/mahak-authenticate-bridge
|
||||||
* Description: Authenticate WordPress user via json web token from Mahakiha Application.
|
* Description: Authenticate WordPress user via json web token from Mahakiha Application.
|
||||||
* Version: 2.2.3
|
* Version: 2.3.1
|
||||||
* Requires PHP: 7.4
|
* Requires PHP: 7.4
|
||||||
* Update URI: https://mahgit.ir/dabestaniha/mahak-authenticate-bridge
|
* Update URI: https://mahgit.ir/dabestaniha/mahak-authenticate-bridge
|
||||||
* Author: Dabestaniha
|
* Author: Dabestaniha
|
||||||
@@ -18,7 +18,7 @@ use Dabestaniha\AuthenticateBridge\App\Http\Controllers\SettingsPageMenuControll
|
|||||||
use Dabestaniha\AuthenticateBridge\App\Http\Controllers\SettingsPageFormController;
|
use Dabestaniha\AuthenticateBridge\App\Http\Controllers\SettingsPageFormController;
|
||||||
use Dabestaniha\AuthenticateBridge\App\Support\PluginUpdater;
|
use Dabestaniha\AuthenticateBridge\App\Support\PluginUpdater;
|
||||||
|
|
||||||
define('MAHAK_AUTHENTICATE_BRIDGE_VERSION', '2.2.3');
|
define('MAHAK_AUTHENTICATE_BRIDGE_VERSION', '2.3.1');
|
||||||
define('MAHAK_AUTHENTICATE_BRIDGE_FILE', __FILE__);
|
define('MAHAK_AUTHENTICATE_BRIDGE_FILE', __FILE__);
|
||||||
|
|
||||||
require_once __DIR__.'/src/Autoloader.php';
|
require_once __DIR__.'/src/Autoloader.php';
|
||||||
|
|||||||
@@ -64,7 +64,20 @@ class AuthenticateController extends InvocableController
|
|||||||
$username .= '_'.wp_generate_password(4, false);
|
$username .= '_'.wp_generate_password(4, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$user_id = wp_create_user($username, $random_password, $email);
|
$configured_role = sanitize_key((string) get_configured_option('new-user-role', 'wordpress_default'));
|
||||||
|
|
||||||
|
if ($configured_role === 'wordpress_default') {
|
||||||
|
$configured_role = sanitize_key((string) get_option('default_role', 'subscriber'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$role = get_role($configured_role) === null ? 'subscriber' : $configured_role;
|
||||||
|
$user_id = wp_insert_user([
|
||||||
|
'user_login' => $username,
|
||||||
|
'user_pass' => $random_password,
|
||||||
|
'user_email' => $email,
|
||||||
|
'display_name' => $name,
|
||||||
|
'role' => $role,
|
||||||
|
]);
|
||||||
|
|
||||||
if (is_wp_error($user_id)) {
|
if (is_wp_error($user_id)) {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
@@ -72,16 +85,8 @@ class AuthenticateController extends InvocableController
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$updated_user_id = wp_update_user([
|
// Enforce the configured role after user_register callbacks from other plugins have completed.
|
||||||
'ID' => $user_id,
|
(new \WP_User($user_id))->set_role($role);
|
||||||
'display_name' => $name,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (is_wp_error($updated_user_id)) {
|
|
||||||
throw new RuntimeException(
|
|
||||||
'WordPress could not update the user: '.$updated_user_id->get_error_message()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $user_id;
|
return $user_id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ class SettingsPageFormController extends InvocableController
|
|||||||
return (int) filter_var($value, FILTER_VALIDATE_BOOLEAN);
|
return (int) filter_var($value, FILTER_VALIDATE_BOOLEAN);
|
||||||
};
|
};
|
||||||
$args['default'] = 0;
|
$args['default'] = 0;
|
||||||
|
} elseif ($configured === 'new-user-role') {
|
||||||
|
$args['sanitize_callback'] = fn ($value): string => $this->sanitize_new_user_role($value);
|
||||||
|
$args['default'] = 'wordpress_default';
|
||||||
}
|
}
|
||||||
|
|
||||||
register_setting(config('mahak.settings-group'), $options_key, $args);
|
register_setting(config('mahak.settings-group'), $options_key, $args);
|
||||||
@@ -58,6 +61,14 @@ class SettingsPageFormController extends InvocableController
|
|||||||
config('mahak.section-id')
|
config('mahak.section-id')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
config('mahak.options.new-user-role'),
|
||||||
|
config('mahak.translations.new-user-role'),
|
||||||
|
fn () => $this->new_user_role(),
|
||||||
|
config('mahak.settings-page'),
|
||||||
|
config('mahak.section-id')
|
||||||
|
);
|
||||||
|
|
||||||
add_settings_field(
|
add_settings_field(
|
||||||
config('mahak.options.debug-mode'),
|
config('mahak.options.debug-mode'),
|
||||||
config('mahak.translations.debug-mode'),
|
config('mahak.translations.debug-mode'),
|
||||||
@@ -130,4 +141,54 @@ class SettingsPageFormController extends InvocableController
|
|||||||
echo "<label><input type='checkbox' name='".esc_attr($name)."' value='1' ".checked($enabled, true, false).' /> ';
|
echo "<label><input type='checkbox' name='".esc_attr($name)."' value='1' ".checked($enabled, true, false).' /> ';
|
||||||
echo esc_html(config('mahak.translations.debug-mode-description')).'</label>';
|
echo esc_html(config('mahak.translations.debug-mode-description')).'</label>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function new_user_role(): void
|
||||||
|
{
|
||||||
|
$name = config('mahak.options.new-user-role');
|
||||||
|
$value = sanitize_key((string) get_option($name, 'wordpress_default'));
|
||||||
|
$roles = wp_roles()->get_names();
|
||||||
|
|
||||||
|
if ($value !== 'wordpress_default' && !isset($roles[$value])) {
|
||||||
|
$value = 'wordpress_default';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "<select name='".esc_attr($name)."'>";
|
||||||
|
$defaultRole = sanitize_key((string) get_option('default_role', 'subscriber'));
|
||||||
|
$defaultRoleLabel = $roles[$defaultRole] ?? $defaultRole;
|
||||||
|
$translatedDefaultRole = function_exists('translate_user_role')
|
||||||
|
? translate_user_role($defaultRoleLabel)
|
||||||
|
: $defaultRoleLabel;
|
||||||
|
echo "<option value='wordpress_default' ".selected($value, 'wordpress_default', false).'>';
|
||||||
|
echo esc_html(config('mahak.translations.wordpress-default-role').' — '.$translatedDefaultRole).'</option>';
|
||||||
|
|
||||||
|
foreach ($roles as $role => $label) {
|
||||||
|
$translatedLabel = function_exists('translate_user_role') ? translate_user_role($label) : $label;
|
||||||
|
echo "<option value='".esc_attr($role)."' ".selected($value, $role, false).'>';
|
||||||
|
echo esc_html($translatedLabel).'</option>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</select>';
|
||||||
|
echo '<p class="description">'.esc_html(config('mahak.translations.new-user-role-description')).'</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sanitize_new_user_role($value): string
|
||||||
|
{
|
||||||
|
$role = sanitize_key((string) $value);
|
||||||
|
|
||||||
|
if ($role === 'wordpress_default') {
|
||||||
|
return $role;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_role($role) !== null) {
|
||||||
|
return $role;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_settings_error(
|
||||||
|
config('mahak.options.new-user-role'),
|
||||||
|
'mahak_invalid_new_user_role',
|
||||||
|
'نقش انتخابشده معتبر نیست. نقش پیشفرض وردپرس استفاده شد.'
|
||||||
|
);
|
||||||
|
|
||||||
|
return 'wordpress_default';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ return [
|
|||||||
'user-identifier' => 'mahak_user_identifier',
|
'user-identifier' => 'mahak_user_identifier',
|
||||||
'login-route' => 'mahak_login_route',
|
'login-route' => 'mahak_login_route',
|
||||||
'after-login-route' => 'mahak_after_login_route',
|
'after-login-route' => 'mahak_after_login_route',
|
||||||
|
'new-user-role' => 'mahak_new_user_role',
|
||||||
'debug-mode' => 'mahak_debug_mode',
|
'debug-mode' => 'mahak_debug_mode',
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -38,6 +39,9 @@ return [
|
|||||||
'user-identifier' => 'فیلد شناسایی کاربر',
|
'user-identifier' => 'فیلد شناسایی کاربر',
|
||||||
'login-route' => 'مسیر لاگین ماهک',
|
'login-route' => 'مسیر لاگین ماهک',
|
||||||
'after-login-route' => 'مسیر بعد از لاگین',
|
'after-login-route' => 'مسیر بعد از لاگین',
|
||||||
|
'new-user-role' => 'نقش کاربر جدید',
|
||||||
|
'wordpress-default-role' => 'پیشفرض وردپرس',
|
||||||
|
'new-user-role-description' => 'در حالت پیشفرض وردپرس، نقش عمومی کاربران جدید استفاده میشود. نقش انتخابی دیگر فقط به کاربران ساختهشده توسط این افزونه اختصاص مییابد.',
|
||||||
'debug-mode' => 'حالت اشکالزدایی',
|
'debug-mode' => 'حالت اشکالزدایی',
|
||||||
'debug-mode-description' => 'در صورت بروز خطا، جزئیات کامل فنی در صفحه نمایش داده شود. این گزینه را فقط هنگام عیبیابی فعال کنید.',
|
'debug-mode-description' => 'در صورت بروز خطا، جزئیات کامل فنی در صفحه نمایش داده شود. این گزینه را فقط هنگام عیبیابی فعال کنید.',
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const TEST_PLUGIN = 'mahak-authenticate-bridge/dabestaniha-authenticate-bridge.p
|
|||||||
const TEST_SECRET = 'integration-test-secret';
|
const TEST_SECRET = 'integration-test-secret';
|
||||||
const TEST_EMAIL = 'mahak-auth-user@example.test';
|
const TEST_EMAIL = 'mahak-auth-user@example.test';
|
||||||
const TEST_NAME = 'Mahak Auth User';
|
const TEST_NAME = 'Mahak Auth User';
|
||||||
|
const TEST_ROLE_EMAIL = 'mahak-role-user@example.test';
|
||||||
|
|
||||||
function fail(string $message): void
|
function fail(string $message): void
|
||||||
{
|
{
|
||||||
@@ -86,6 +87,8 @@ function activate_and_configure_plugin(): void
|
|||||||
update_option('mahak_user_identifier', 'email');
|
update_option('mahak_user_identifier', 'email');
|
||||||
update_option('mahak_login_route', 'mahak/login');
|
update_option('mahak_login_route', 'mahak/login');
|
||||||
update_option('mahak_after_login_route', 'wp-admin/profile.php');
|
update_option('mahak_after_login_route', 'wp-admin/profile.php');
|
||||||
|
update_option('default_role', 'subscriber');
|
||||||
|
update_option('mahak_new_user_role', 'wordpress_default');
|
||||||
|
|
||||||
pass('Plugin activated and configured');
|
pass('Plugin activated and configured');
|
||||||
}
|
}
|
||||||
@@ -213,6 +216,10 @@ function test_valid_authentication(): void
|
|||||||
|
|
||||||
assert_true($user !== false, 'Authenticated user was not created.');
|
assert_true($user !== false, 'Authenticated user was not created.');
|
||||||
assert_true($user->display_name === TEST_NAME, 'Authenticated user display name was not saved.');
|
assert_true($user->display_name === TEST_NAME, 'Authenticated user display name was not saved.');
|
||||||
|
assert_true(
|
||||||
|
$user->roles === ['subscriber'],
|
||||||
|
'New user did not receive the plugin-configured Subscriber role.'
|
||||||
|
);
|
||||||
|
|
||||||
$cookieHeader = cookie_header_from_response($response['headers']);
|
$cookieHeader = cookie_header_from_response($response['headers']);
|
||||||
$profileResponse = http_request(TEST_SITE_URL.'/wp-admin/profile.php', $cookieHeader);
|
$profileResponse = http_request(TEST_SITE_URL.'/wp-admin/profile.php', $cookieHeader);
|
||||||
@@ -222,7 +229,38 @@ function test_valid_authentication(): void
|
|||||||
'Issued cookies did not authenticate a follow-up WordPress admin request.'
|
'Issued cookies did not authenticate a follow-up WordPress admin request.'
|
||||||
);
|
);
|
||||||
|
|
||||||
pass('Valid JWT creates/logs in user and issued cookies authenticate follow-up request');
|
pass('Valid JWT creates a Subscriber and issued cookies authenticate follow-up requests');
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_configured_new_user_role_is_enforced(): void
|
||||||
|
{
|
||||||
|
$smsRoleOverride = function (int $userId): void {
|
||||||
|
(new WP_User($userId))->set_role('administrator');
|
||||||
|
};
|
||||||
|
add_action('user_register', $smsRoleOverride);
|
||||||
|
|
||||||
|
$controller = new Dabestaniha\AuthenticateBridge\App\Http\Controllers\AuthenticateController();
|
||||||
|
$userId = $controller->find_or_create_user('email', TEST_ROLE_EMAIL, 'Role Test User');
|
||||||
|
|
||||||
|
remove_action('user_register', $smsRoleOverride);
|
||||||
|
|
||||||
|
$user = get_userdata($userId);
|
||||||
|
assert_true(
|
||||||
|
$user !== false && $user->roles === ['subscriber'],
|
||||||
|
'Configured role was not enforced after another plugin changed the role during user_register.'
|
||||||
|
);
|
||||||
|
|
||||||
|
$user->set_role('author');
|
||||||
|
$existingUserId = $controller->find_or_create_user('email', TEST_ROLE_EMAIL, 'Role Test User');
|
||||||
|
$existingUser = get_userdata($existingUserId);
|
||||||
|
|
||||||
|
assert_true($existingUserId === $userId, 'Existing user was not reused.');
|
||||||
|
assert_true(
|
||||||
|
$existingUser !== false && $existingUser->roles === ['author'],
|
||||||
|
'Existing user role was changed during authentication.'
|
||||||
|
);
|
||||||
|
|
||||||
|
pass('Configured role overrides creation hooks without changing existing users');
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_invalid_authentication(): void
|
function test_invalid_authentication(): void
|
||||||
@@ -310,7 +348,7 @@ function test_debug_error_details(): void
|
|||||||
|
|
||||||
function test_plugin_update_discovery(): void
|
function test_plugin_update_discovery(): void
|
||||||
{
|
{
|
||||||
$packageUrl = 'https://mahgit.ir/dabestaniha/mahak-authenticate-bridge/releases/download/v2.3.0/mahak-authenticate-bridge.zip';
|
$packageUrl = 'https://mahgit.ir/dabestaniha/mahak-authenticate-bridge/releases/download/v2.4.0/mahak-authenticate-bridge.zip';
|
||||||
$mockRelease = function ($response, array $request, string $url) use ($packageUrl) {
|
$mockRelease = function ($response, array $request, string $url) use ($packageUrl) {
|
||||||
if ($url !== 'https://mahgit.ir/api/v1/repos/dabestaniha/mahak-authenticate-bridge/releases/latest') {
|
if ($url !== 'https://mahgit.ir/api/v1/repos/dabestaniha/mahak-authenticate-bridge/releases/latest') {
|
||||||
return $response;
|
return $response;
|
||||||
@@ -319,8 +357,8 @@ function test_plugin_update_discovery(): void
|
|||||||
return [
|
return [
|
||||||
'headers' => [],
|
'headers' => [],
|
||||||
'body' => json_encode([
|
'body' => json_encode([
|
||||||
'tag_name' => 'v2.3.0',
|
'tag_name' => 'v2.4.0',
|
||||||
'html_url' => 'https://mahgit.ir/dabestaniha/mahak-authenticate-bridge/releases/tag/v2.3.0',
|
'html_url' => 'https://mahgit.ir/dabestaniha/mahak-authenticate-bridge/releases/tag/v2.4.0',
|
||||||
'body' => 'Test release',
|
'body' => 'Test release',
|
||||||
'draft' => false,
|
'draft' => false,
|
||||||
'prerelease' => false,
|
'prerelease' => false,
|
||||||
@@ -346,7 +384,7 @@ function test_plugin_update_discovery(): void
|
|||||||
remove_filter('pre_http_request', $mockRelease, 10);
|
remove_filter('pre_http_request', $mockRelease, 10);
|
||||||
|
|
||||||
assert_true(isset($updates->response[TEST_PLUGIN]), 'A newer Mahgit release was not offered as a WordPress update.');
|
assert_true(isset($updates->response[TEST_PLUGIN]), 'A newer Mahgit release was not offered as a WordPress update.');
|
||||||
assert_true($updates->response[TEST_PLUGIN]->new_version === '2.3.0', 'The offered plugin version was incorrect.');
|
assert_true($updates->response[TEST_PLUGIN]->new_version === '2.4.0', 'The offered plugin version was incorrect.');
|
||||||
assert_true($updates->response[TEST_PLUGIN]->package === $packageUrl, 'The release package URL was incorrect.');
|
assert_true($updates->response[TEST_PLUGIN]->package === $packageUrl, 'The release package URL was incorrect.');
|
||||||
|
|
||||||
pass('Published Mahgit releases are discovered by the WordPress updater');
|
pass('Published Mahgit releases are discovered by the WordPress updater');
|
||||||
@@ -357,6 +395,7 @@ install_wordpress();
|
|||||||
activate_and_configure_plugin();
|
activate_and_configure_plugin();
|
||||||
wait_for_http();
|
wait_for_http();
|
||||||
test_valid_authentication();
|
test_valid_authentication();
|
||||||
|
test_configured_new_user_role_is_enforced();
|
||||||
test_invalid_authentication();
|
test_invalid_authentication();
|
||||||
test_debug_error_details();
|
test_debug_error_details();
|
||||||
test_plugin_update_discovery();
|
test_plugin_update_discovery();
|
||||||
|
|||||||
Reference in New Issue
Block a user