You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
5.1 KiB
PHTML
139 lines
5.1 KiB
PHTML
3 years ago
|
<?php
|
||
|
class OpenID_Connect_Generic_Webhook {
|
||
|
/**
|
||
|
* The settings object instance.
|
||
|
*
|
||
|
* @var OpenID_Connect_Generic_Option_Settings
|
||
|
*/
|
||
|
private $settings;
|
||
|
|
||
|
/**
|
||
|
* Plugin client wrapper instance.
|
||
|
*
|
||
|
* @var OpenID_Connect_Generic_Client_Wrapper
|
||
|
*/
|
||
|
private $client_wrapper;
|
||
|
|
||
|
/**
|
||
|
* The logger object instance.
|
||
|
*
|
||
|
* @var OpenID_Connect_Generic_Option_Logger
|
||
|
*/
|
||
|
private $logger;
|
||
|
|
||
|
public function __construct(OpenID_Connect_Generic_Option_Settings $settings,
|
||
|
OpenID_Connect_Generic_Client_Wrapper $client_wrapper,
|
||
|
OpenID_Connect_Generic_Option_Logger $logger) {
|
||
|
$this->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',
|
||
|
],
|
||
|
],
|
||
|
];
|
||
|
}
|
||
|
}
|