Add M365 Login plugin: Microsoft Entra ID sign-in for existing users
Adds a WordPress plugin that places a customisable "Sign in with Microsoft" button on wp-login.php and signs existing users in via the OpenID Connect authorization code flow with PKCE. Users are matched by e-mail address only; no accounts are created. Security: single-use state/nonce bound to an HttpOnly cookie, ID token signature verification against Microsoft's JWKS (RS256 only) with issuer/audience/tenant/expiry/nonce checks, optional tenant pinning, account binding to the Microsoft object ID, e-mail domain allow-list, client secret encrypted at rest (AES-256-GCM). Admin: settings screen with connection, button and security tabs, live button preview, colour presets, media-library icon picker, redirect URI copy button and tenant connectivity test. Packaging for WordPress.org: readme.txt with External services section, GPL-2.0 license, uninstall.php, POT + German translations, .distignore, build script, PHPCS config and CI running Plugin Check. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJxAHYdMfKPoN4koRc4Ci2
This commit is contained in:
commit
3e3e87b399
35 changed files with 5413 additions and 0 deletions
125
includes/class-m365-login.php
Normal file
125
includes/class-m365-login.php
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
/**
|
||||
* Plugin bootstrap.
|
||||
*
|
||||
* @package M365_Login
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Wires the individual components together.
|
||||
*/
|
||||
final class M365_Login {
|
||||
|
||||
/**
|
||||
* Singleton instance.
|
||||
*
|
||||
* @var M365_Login|null
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Settings component.
|
||||
*
|
||||
* @var M365_Login_Settings
|
||||
*/
|
||||
public $settings;
|
||||
|
||||
/**
|
||||
* Authentication component.
|
||||
*
|
||||
* @var M365_Login_Auth
|
||||
*/
|
||||
public $auth;
|
||||
|
||||
/**
|
||||
* Login button component.
|
||||
*
|
||||
* @var M365_Login_Button
|
||||
*/
|
||||
public $button;
|
||||
|
||||
/**
|
||||
* Admin component.
|
||||
*
|
||||
* @var M365_Login_Admin|null
|
||||
*/
|
||||
public $admin = null;
|
||||
|
||||
/**
|
||||
* Returns the singleton.
|
||||
*
|
||||
* @return M365_Login
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
add_action( 'init', array( $this, 'load_textdomain' ) );
|
||||
|
||||
$this->settings = new M365_Login_Settings();
|
||||
$this->auth = new M365_Login_Auth( $this->settings );
|
||||
$this->button = new M365_Login_Button( $this->settings );
|
||||
|
||||
if ( is_admin() ) {
|
||||
$this->admin = new M365_Login_Admin( $this->settings, $this->auth );
|
||||
}
|
||||
|
||||
add_filter( 'plugin_action_links_' . plugin_basename( M365_LOGIN_FILE ), array( $this, 'action_links' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads bundled translations.
|
||||
*/
|
||||
public function load_textdomain() {
|
||||
load_plugin_textdomain( 'm365-login', false, dirname( plugin_basename( M365_LOGIN_FILE ) ) . '/languages' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a "Settings" link on the plugins screen.
|
||||
*
|
||||
* @param string[] $links Existing links.
|
||||
* @return string[]
|
||||
*/
|
||||
public function action_links( $links ) {
|
||||
$url = admin_url( 'options-general.php?page=m365-login' );
|
||||
array_unshift( $links, '<a href="' . esc_url( $url ) . '">' . esc_html__( 'Settings', 'm365-login' ) . '</a>' );
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activation hook: seed defaults and check requirements.
|
||||
*/
|
||||
public static function activate() {
|
||||
if ( version_compare( PHP_VERSION, '7.4', '<' ) ) {
|
||||
deactivate_plugins( plugin_basename( M365_LOGIN_FILE ) );
|
||||
wp_die(
|
||||
esc_html__( 'M365 Login requires PHP 7.4 or newer.', 'm365-login' ),
|
||||
esc_html__( 'Plugin activation failed', 'm365-login' ),
|
||||
array( 'back_link' => true )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'openssl_encrypt' ) ) {
|
||||
deactivate_plugins( plugin_basename( M365_LOGIN_FILE ) );
|
||||
wp_die(
|
||||
esc_html__( 'M365 Login requires the PHP OpenSSL extension (needed to verify Microsoft token signatures and to encrypt the client secret).', 'm365-login' ),
|
||||
esc_html__( 'Plugin activation failed', 'm365-login' ),
|
||||
array( 'back_link' => true )
|
||||
);
|
||||
}
|
||||
|
||||
$settings = new M365_Login_Settings();
|
||||
if ( false === get_option( M365_LOGIN_OPTION, false ) ) {
|
||||
add_option( M365_LOGIN_OPTION, $settings->defaults(), '', 'no' );
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue