Files
medicalalert-web-reloaded/wp/wp-content/mu-plugins/okta-wordpress-sign-in-widget-main/okta-widget.php
2024-03-01 15:41:58 +00:00

227 lines
7.3 KiB
PHP

<?php
namespace Okta;
/**
* Plugin Name: Okta Sign-In Widget
* Plugin URI: https://github.com/oktadeveloper/okta-wordpress-sign-in-widget
* Description: Log in to your site using the Okta Sign-In Widget
* Version: 0.3.0
* Author: Aaron Parecki, Tom Smith, Nico Triballier, Joël Franusic
* Author URI: https://developer.okta.com/
* License: MIT
* License URI: http://opensource.org/licenses/MIT
* Text Domain: okta
* Domain Path: /languages
* Update URI: false
*/
include plugin_dir_path(__FILE__).'/includes/okta-admin.php';
class OktaSignIn
{
private $OktaAdmin;
private $base_url = false;
private $introspection_endpoint = false;
public function __construct()
{
$this->OktaAdmin = new OktaAdmin;
$this->setBaseUrl();
// https://developer.wordpress.org/reference/hooks/login_init/
add_action('login_init', array($this, 'loginAction'));
// This runs on every pageload to insert content into the HTML <head> section
// https://codex.wordpress.org/Plugin_API/Action_Reference/wp_head
add_action('wp_head', array($this, 'addLogInExistingSessionAction'));
add_action('init', array($this, 'startSessionAction'));
}
private function setBaseUrl()
{
if($issuer = get_option('okta-issuer-url')) {
$this->base_url = parse_url($issuer, PHP_URL_SCHEME).'://'.parse_url($issuer, PHP_URL_HOST);
}
}
private function getIntrospectionEndpoint() {
if($this->introspection_endpoint)
return $this->introspection_endpoint;
if(!$this->base_url)
return false;
$response = wp_remote_get(get_option('okta-issuer-url').'/.well-known/openid-configuration');
if(!$response)
return false;
$metadata = json_decode($response['body'], true);
if(!$metadata)
return false;
if(!isset($metadata['introspection_endpoint']))
return false;
return $this->introspection_endpoint = $metadata['introspection_endpoint'];
}
public function startSessionAction()
{
if (session_status() != PHP_SESSION_ACTIVE) {
session_start();
}
}
public function addLogInExistingSessionAction()
{
if (!is_user_logged_in()) {
$this->startSessionAction();
$_SESSION['redirect_to'] = $_SERVER['REQUEST_URI'];
include("templates/log-in-existing-session.php");
}
}
private function httpPost($url, $body)
{
$args = array(
'headers' => array(
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded',
),
'body' => $body,
);
return wp_remote_post($url, $args);
}
public function loginAction()
{
// Support redirecting back to the page the user was on before they clicked log in
$redirect_to = false;
if (isset($_GET['redirect_to'])) {
$redirect_to = $_GET['redirect_to'];
$_SESSION['redirect_to'] = $_GET['redirect_to'];
}
// When signing out of WordPress, tell the Okta JS library to log out of Okta as well
if (isset($_GET["action"]) && $_GET["action"] === "logout") {
$this->logUserOutOfOkta();
}
if (isset($_GET['log_in_from_id_token'])) {
$this->logUserIntoWordPressWithIDToken($_GET['log_in_from_id_token'], $redirect_to);
exit;
}
if($this->useWordpressLogin()) {
return;
}
// If there is no code in the query string, show the Okta sign-in widget
$template = plugin_dir_path(__FILE__) . 'templates/sign-in-form.php';
load_template($template);
exit;
}
private function useWordpressLogin()
{
// Always skip showing the Okta widget on POST requests
if($_SERVER['REQUEST_METHOD'] === 'POST')
return true;
// If the plugin isn't configured yet, don't show the Okta widget
if(!$this->base_url)
return true;
// null when plugin is not configured, "1"/"0" after
if(get_option('okta-allow-wordpress-login') === null || get_option('okta-allow-wordpress-login') === "1")
{
if(isset($_GET['wordpress_login']) && $_GET['wordpress_login'] == 'true')
return true;
if(isset($_GET['action']) && $_GET['action'] == 'lostpassword')
return true;
if(isset($_GET['checkemail']))
return true;
}
return false;
}
private function logUserOutOfOkta() {
$user = wp_get_current_user();
wp_clear_auth_cookie();
$template = plugin_dir_path(__FILE__) . 'templates/sign-out.php';
load_template($template);
exit;
}
private function logUserIntoWordPressWithIDToken($id_token, $redirect_to)
{
$introspection_endpoint = $this->getIntrospectionEndpoint();
if(!$this->introspection_endpoint)
die("The plugin is not configured properly. Please double check the Issuer URI in the configuration.");
/********************************************/
// [jpf] TODO: Implement client-side id_token validation to speed up the verification process
// (~300ms for /introspect endpoint v. ~5ms for client-side validation)
$payload = array(
'client_id' => get_option('okta-widget-client-id'),
'token' => $id_token,
'token_type_hint' => 'id_token'
);
$response = $this->httpPost($this->introspection_endpoint, $payload);
if ($response === false) {
die("Invalid id_token received from Okta");
}
$claims = json_decode($response['body'], true);
if (!$claims['active']) {
die("Okta reports that id_token is not active or client authentication failed:" . $claims['error_description']);
}
/********************************************/
$this->logUserIntoWordPressFromEmail($claims, $redirect_to);
}
private function logUserIntoWordPressFromEmail($claims, $redirect_to)
{
$email = $claims['email'];
// Find or create the WordPress user for this email address
$user = get_user_by('email', $email);
if (!$user) {
$random_password = wp_generate_password($length = 64, $include_standard_special_chars = false);
$user_id = wp_create_user($email, $random_password, $email);
$user = get_user_by('id', $user_id);
} else {
$user_id = $user->ID;
}
do_action('okta_widget_before_login', $claims, $user);
// Actually log the user in now
wp_set_current_user($user_id);
wp_set_auth_cookie($user_id);
error_log("Logging in WordPress user with ID of: " . $user_id);
// See also: https://developer.wordpress.org/reference/functions/do_action/
// Run the wp_login actions now that the user is logged in
do_action('wp_login', $user->user_login, $user);
if (isset($_SESSION['redirect_to'])) {
$redirect_uri = $_SESSION['redirect_to'];
unset($_SESSION['redirect_to']);
} else {
$redirect_uri = home_url();
}
wp_redirect($redirect_uri);
}
}
$okta = new OktaSignIn();