wp-m365-login/includes/class-m365-login.php
friloo 1202283eda
Add Entra group restriction, button-only mode and detailed README
Groups: a Graph-backed picker on the Security tab (search by name or
paste object IDs) stores allowed group IDs. During sign-in membership is
read from the ID token's groups claim when present, otherwise verified
through Microsoft Graph checkMemberGroups (transitive). Verification
failures refuse the sign-in.

Button-only mode: hides the password form and the lost-password link
and rejects password sign-ins on wp-login.php via the authenticate
filter. A generated, rate-limited fallback key re-enables the form for
30 minutes per browser; M365_LOGIN_DISABLE_BUTTON_ONLY switches the
mode off from wp-config.php.

Also: new German-language README with sequence diagram, settings
reference, troubleshooting and hook examples; readme.txt external
services section now covers Microsoft Graph; translations updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJxAHYdMfKPoN4koRc4Ci2
2026-09-22 14:30:53 +00:00

133 lines
3 KiB
PHP

<?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;
/**
* Microsoft Graph client.
*
* @var M365_Login_Graph
*/
public $graph;
/**
* 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->graph = new M365_Login_Graph( $this->settings );
$this->auth = new M365_Login_Auth( $this->settings, $this->graph );
$this->button = new M365_Login_Button( $this->settings );
if ( is_admin() ) {
$this->admin = new M365_Login_Admin( $this->settings, $this->auth, $this->graph );
}
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' );
}
}
}