diff --git a/includes/openid-connect-generic-client-wrapper.php b/includes/openid-connect-generic-client-wrapper.php index b049b72..3922ba0 100644 --- a/includes/openid-connect-generic-client-wrapper.php +++ b/includes/openid-connect-generic-client-wrapper.php @@ -9,6 +9,7 @@ * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ +use MatthiasMullie\Minify\JS; use \WP_Error as WP_Error; /** @@ -122,6 +123,13 @@ class OpenID_Connect_Generic_Client_Wrapper { add_action( 'wp_loaded', array( $client_wrapper, 'ensure_tokens_still_fresh' ) ); } + // Disable some profile settings + add_action( 'personal_options_update', array( $client_wrapper, 'disable_profile_change' ), 5 ); + add_action( 'show_user_profile', array( $client_wrapper, 'show_user_profile' ), 0 ); + + // Avatar + add_filter( 'get_avatar', array( $client_wrapper, 'get_avatar' ), 100, 5); + return $client_wrapper; } @@ -238,6 +246,76 @@ class OpenID_Connect_Generic_Client_Wrapper { return apply_filters( 'openid-connect-generic-auth-url', $url ); } + public function disable_profile_change( $user_id ) { + $user = get_user_by('id', $user_id ); + $_POST['email'] = $user->user_email; + // $_POST['nickname'] = $user->user_nickname; + } + + public function show_user_profile( $user ) { + if ( !empty( $this->settings->profile_edit_url ) ) { + $profileUrl = $this->settings->profile_edit_url; + $clientId = $this->settings->client_id; + $currentUrl = admin_url( 'profile.php' ); + if ( strpos( $profileUrl, '?' ) === false ) { + $profileUrl .= '?'; + } else { + $profileUrl .= '&'; + } + $profileUrl .= http_build_query( array( + 'referrer' => $clientId, + 'referrer_uri' => $currentUrl, + ) ); +?> + +
| + | + 前往用户中心 + | +
|---|
+ settings->enable_webhook) {
+ ?>
+
+
+
+
+
+ keycloak
+
[openid_connect_generic_login_button]
diff --git a/includes/openid-connect-generic-webhook.php b/includes/openid-connect-generic-webhook.php
new file mode 100644
index 0000000..22a7614
--- /dev/null
+++ b/includes/openid-connect-generic-webhook.php
@@ -0,0 +1,139 @@
+settings = $settings;
+ $this->client_wrapper = $client_wrapper;
+ $this->logger = $logger;
+ }
+
+ public static function register(OpenID_Connect_Generic_Option_Settings $settings,
+ OpenID_Connect_Generic_Client_Wrapper $client_wrapper,
+ OpenID_Connect_Generic_Option_Logger $logger) {
+ $webhook = new OpenID_Connect_Generic_Webhook($settings, $client_wrapper, $logger);
+
+ add_action('rest_api_init', [$webhook, 'register_rest_api']);
+
+ return $webhook;
+ }
+
+ public function register_rest_api() {
+ register_rest_route('openid-connect/v1', '/webhook/keycloak', [
+ [
+ 'methods' => ['GET', 'POST'],
+ 'callback' => [$this, 'webhook_keycloak'],
+ ],
+ 'schema' => [$this, 'webhook_keycloak_schema'],
+ ]);
+ }
+
+ public function webhook_keycloak(WP_REST_Request $request) {
+ if (!$this->settings->enable_webhook) {
+ $this->logger->log('Webhook is disabled in setting.', 'webhook');
+ return rest_ensure_response([
+ 'status' => -1,
+ 'code' => 'ERR::WEBHOOK_DISABLED',
+ 'error' => 'Webhook is disabled in setting.'
+ ]);
+ }
+ $query = $request->get_query_params();
+ if (!empty($this->settings->webhook_key) && $query['key'] != $this->settings->webhook_key) {
+ $this->logger->log('Webhook key is incorrect.', 'webhook');
+ return rest_ensure_response([
+ 'status' => -1,
+ 'code' => 'ERR::WEBHOOK_KEY_INCORRECT',
+ 'error' => 'Webhook key is incorrect.'
+ ]);
+ }
+ $event = $request->get_json_params();
+ if (is_null($event)) {
+ $this->logger->log('Event body is empty.', 'webhook');
+ return rest_ensure_response([
+ 'status' => -1,
+ 'code' => 'ERR::EMPTY_EVENT_BODY',
+ 'error' => 'Event body is empty.',
+ ]);
+ }
+ if ($event['realmId'] != $this->settings->realm) {
+ $this->logger->log("Realm id mismatch: {$event['realmId']}", 'webhook');
+ return rest_ensure_response([
+ 'status' => 0,
+ 'warning' => "Realm id mismatch: {$event['realmId']}",
+ ]);
+ }
+ if (!in_array($event['type'], ['UPDATE_PROFILE', 'UPDATE_EMAIL'])) {
+ return rest_ensure_response([
+ 'status' => 0,
+ 'warning' => 'Event type ignored',
+ ]);
+ }
+
+ $subject = $event['userId'];
+ $user = $this->client_wrapper->get_user_by_identity($subject);
+ if (!$user) {
+ $this->logger->log("Cannot find user for subject: {$subject}", 'webhook');
+ return rest_ensure_response([
+ 'status' => 0,
+ 'warning' => "Cannot find user for subject: {$subject}",
+ ]);
+ }
+ if (isset($event['userInfo'])) { // Update user profile
+ $this->client_wrapper->update_user_profile($user, $event['userInfo']);
+ $this->logger->log("Updated user profile: {$user->user_login}", 'webhook');
+ }
+
+ return rest_ensure_response([
+ 'status' => 1
+ ]);
+ }
+
+ public function webhook_keycloak_schema() {
+ return [
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
+ // The title property marks the identity of the resource.
+ 'title' => 'keycloak-webhook',
+ 'type' => 'object',
+ 'required' => ['type', 'realmId', 'userId', 'userInfo'],
+ 'properties' => [
+ 'type' => [
+ 'description' => esc_html__('Event Type', 'daggerhart-openid-connect-generic'),
+ 'type' => 'string',
+ ],
+ 'realmId' => [
+ 'description' => esc_html__('IDP Realm ID', 'daggerhart-openid-connect-generic'),
+ 'type' => 'string',
+ ],
+ 'userId' => [
+ 'description' => esc_html__('IDP User ID', 'daggerhart-openid-connect-generic'),
+ 'type' => 'string',
+ ],
+ 'userInfo' => [
+ 'description' => esc_html__('IDP User Info', 'daggerhart-openid-connect-generic'),
+ 'type' => 'object',
+ ],
+ ],
+ ];
+ }
+}
\ No newline at end of file
diff --git a/openid-connect-generic.php b/openid-connect-generic.php
index fcb94dd..713896c 100644
--- a/openid-connect-generic.php
+++ b/openid-connect-generic.php
@@ -173,6 +173,8 @@ class OpenID_Connect_Generic {
if ( is_admin() ) {
OpenID_Connect_Generic_Settings_Page::register( $this->settings, $this->logger );
}
+
+ OpenID_Connect_Generic_Webhook::register( $this->settings, $this->client_wrapper, $this->logger );
}
/**
@@ -342,10 +344,14 @@ class OpenID_Connect_Generic {
'identity_key' => 'preferred_username',
'nickname_key' => 'preferred_username',
'email_format' => '{email}',
+ 'profile_edit_url' => '',
'displayname_format' => '',
'identify_with_username' => false,
+ 'realm' => '',
// Plugin settings.
+ 'enable_webhook' => false,
+ 'webhook_key' => '',
'enforce_privacy' => 0,
'alternate_redirect_uri' => 0,
'token_refresh_enable' => 1,