diff --git a/auth.php b/auth.php index 6948d80..af11bd4 100644 --- a/auth.php +++ b/auth.php @@ -36,6 +36,8 @@ class auth_plugin_oidc extends \auth_plugin_base { /** @var object Plugin config. */ public $config; + /** @var object extending \auth_oidc\loginflow\base */ + public $loginflow; /** * Constructor. */ @@ -77,7 +79,7 @@ public function loginpage_idp_list($wantsurl) { /** * Set an HTTP client to use. * - * @param auth_oidchttpclientinterface $httpclient [description] + * @param auth_oidc\httpclientinterface $httpclient [description] */ public function set_httpclient(\auth_oidc\httpclientinterface $httpclient) { return $this->loginflow->set_httpclient($httpclient); @@ -87,10 +89,15 @@ public function set_httpclient(\auth_oidc\httpclientinterface $httpclient) { * Hook for overriding behaviour of login page. * This method is called from login/index.php page for all enabled auth plugins. * + * @return bool|void if redirecting + * @throws \coding_exception * @global object * @global object */ public function loginpage_hook() { + if ($this->should_login_redirect()) { + $this->loginflow->handleredirect(); + } global $frm; // can be used to override submitted login form global $user; // can be used to replace authenticate_user_login() return $this->loginflow->loginpage_hook($frm, $user); @@ -105,6 +112,56 @@ public function handleredirect() { return $this->loginflow->handleredirect(); } + /** + * Determines if we will redirect to the redirecturi + * + * @return bool If this returns true then redirect + * @throws \coding_exception + */ + public function should_login_redirect() { + global $SESSION; + $redirect = optional_param('redirect', 1, PARAM_BOOL); + if (!empty($redirect)) { + $redirect = 0; + } + + if (!$this->config->forceredirect) { + return false; // Never redirect if we haven't enabled the forceredirect setting + } + // Never redirect on POST. + if (isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'POST')) { + return false; + } + + // Check whether we've skipped the login page already. + // This is here because loginpage_hook is called again during form + // submission (all of login.php is processed) and ?oidc=off is not + // preserved forcing us to the IdP. + if ((isset($SESSION->oidc) && $SESSION->oidc == 0)) { + return false; + } + + // Never redirect if requested so. + if ($redirect === 0) { + $SESSION->oidc = $redirect; + return false; + } + // We are off to OIDC so reset the force in SESSION. + if (isset($SESSION->oidc)) { + unset($SESSION->oidc); + } + return true; + } + + /** + * Will check if we have to redirect before going to login page + */ + public function pre_loginpage_hook() { + if ($this->should_login_redirect()) { + $this->loginflow->handleredirect(); + } + } + /** * Handle OIDC disconnection from Moodle account. * diff --git a/lang/en/auth_oidc.php b/lang/en/auth_oidc.php index 76aba7c..914e1ff 100644 --- a/lang/en/auth_oidc.php +++ b/lang/en/auth_oidc.php @@ -70,6 +70,8 @@ $string['cfg_opname_desc'] = 'This is an end-user-facing label that identifies the type of credentials the user must use to login. This label is used throughout the user-facing portions of this plugin to identify your provider.'; $string['cfg_redirecturi_key'] = 'Redirect URI'; $string['cfg_redirecturi_desc'] = 'This is the URI to register as the "Redirect URI". Your OpenID Connect identity provider should ask for this when registering Moodle as a client.
NOTE: You must enter this in your OpenID Connect provider *exactly* as it appears here. Any difference will prevent logins using OpenID Connect.'; +$string['cfg_forceredirect_key'] = 'Force redirect'; +$string['cfg_forceredirect_desc'] = 'If enabled, will skip the login index page and redirect to the OpenID Connect page. Can be bypassed with ?redirect=0 URL param'; $string['cfg_tokenendpoint_key'] = 'Token Endpoint'; $string['cfg_tokenendpoint_desc'] = 'The URI of the token endpoint from your identity provider to use.'; $string['cfg_userrestrictions_key'] = 'User Restrictions'; diff --git a/settings.php b/settings.php index 1729f9c..d18d8dd 100644 --- a/settings.php +++ b/settings.php @@ -55,6 +55,11 @@ $configdesc = new lang_string('cfg_redirecturi_desc', 'auth_oidc'); $settings->add(new \auth_oidc\form\adminsetting\redirecturi('auth_oidc/redirecturi', $configkey, $configdesc)); +$configkey = new lang_string('cfg_forceredirect_key', 'auth_oidc'); +$configdesc = new lang_string('cfg_forceredirect_desc', 'auth_oidc'); +$configdefault = 0; +$settings->add(new admin_setting_configcheckbox('auth_oidc/forceredirect', $configkey, $configdesc, $configdefault)); + $configkey = new lang_string('cfg_autoappend_key', 'auth_oidc'); $configdesc = new lang_string('cfg_autoappend_desc', 'auth_oidc'); $configdefault = ''; @@ -165,4 +170,4 @@ $configdesc = new lang_string('cfg_customicon_desc', 'auth_oidc'); $setting = new admin_setting_configstoredfile('auth_oidc/customicon', $configkey, $configdesc, 'customicon'); $setting->set_updatedcallback('auth_oidc_initialize_customicon'); -$settings->add($setting); \ No newline at end of file +$settings->add($setting);