SSO: Display (localized) error message on failed SSO login.
This commit is contained in:
parent
cf50715f4f
commit
2eea216d36
3 changed files with 61 additions and 19 deletions
|
@ -69,14 +69,13 @@ class kolab_sso_openidc
|
|||
{
|
||||
$this->plugin->debug("[{$this->id}][authorize] Response: " . $_SERVER['REQUEST_URI']);
|
||||
|
||||
$error = $this->response_error(
|
||||
$this->error = $this->error_message(
|
||||
rcube_utils::get_input_value('error', rcube_utils::INPUT_GET),
|
||||
rcube_utils::get_input_value('error_description', rcube_utils::INPUT_GET),
|
||||
rcube_utils::get_input_value('error_uri', rcube_utils::INPUT_GET)
|
||||
);
|
||||
|
||||
if ($error) {
|
||||
// TODO: display error in UI
|
||||
if ($this->error) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -85,25 +84,35 @@ class kolab_sso_openidc
|
|||
|
||||
if (!$state) {
|
||||
$this->plugin->debug("[{$this->id}][response] State missing");
|
||||
$error = $this->plugin->gettext('errorinvalidresponse');
|
||||
$this->error = $this->plugin->gettext('errorinvalidresponse');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($state != $this->plugin->rc->get_request_token()) {
|
||||
$this->plugin->debug("[{$this->id}][response] Invalid response state");
|
||||
$error = $this->plugin->gettext('errorinvalidresponse');
|
||||
$this->error = $this->plugin->gettext('errorinvalidresponse');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$code) {
|
||||
$this->plugin->debug("[{$this->id}][response] Code missing");
|
||||
$error = $this->plugin->gettext('errorinvalidresponse');
|
||||
$this->error = $this->plugin->gettext('errorinvalidresponse');
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->request_token($code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error message for the response handler
|
||||
*/
|
||||
public function response_error()
|
||||
{
|
||||
if ($this->error) {
|
||||
return $this->plugin->rc->gettext('loginfailed') . ' ' . $this->error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Existing session validation
|
||||
*/
|
||||
|
@ -194,11 +203,12 @@ class kolab_sso_openidc
|
|||
$response = @json_decode($response, true);
|
||||
|
||||
if ($status != 200 || !is_array($response) || !empty($response['error'])) {
|
||||
$err = $this->error_message(is_array($response) ? $response['error'] : null);
|
||||
$err = $this->error_text(is_array($response) ? $response['error'] : null);
|
||||
throw new Exception("OpenIDC request failed with error: $err");
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$this->error = $this->plugin->gettext('errorunknown');
|
||||
rcube::raise_error(array(
|
||||
'line' => __LINE__, 'file' => __FILE__, 'message' => $e->getMessage()),
|
||||
true, false);
|
||||
|
@ -218,6 +228,7 @@ class kolab_sso_openidc
|
|||
if (empty($response['access_token']) || empty($response['token_type'])
|
||||
|| strtolower($response['token_type']) != 'bearer'
|
||||
) {
|
||||
$this->error = $this->plugin->gettext('errorinvalidresponse');
|
||||
$this->plugin->debug("[{$this->id}][$mode] Error: Invalid or unsupported response");
|
||||
return;
|
||||
}
|
||||
|
@ -276,6 +287,7 @@ class kolab_sso_openidc
|
|||
$result['email'] = $email;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$this->error = $this->plugin->gettext('errorinvalidtoken');
|
||||
rcube::raise_error(array(
|
||||
'line' => __LINE__, 'file' => __FILE__, 'message' => $e->getMessage()),
|
||||
true, false);
|
||||
|
@ -328,30 +340,30 @@ class kolab_sso_openidc
|
|||
/**
|
||||
* Returns (localized) user-friendly error message
|
||||
*/
|
||||
protected function response_error($error, $description, $uri)
|
||||
protected function error_message($error, $description, $uri)
|
||||
{
|
||||
if (empty($error)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$msg = $this->error_message($error);
|
||||
$msg = $this->error_text($error);
|
||||
|
||||
$this->plugin->debug("[{$this->id}] Error: $msg");
|
||||
|
||||
// TODO: Add URI to the message
|
||||
rcube::raise_error(array(
|
||||
'message' => "[SSO] $msg." . ($description ? " $description" : '') . ($uri ? " ($uri)" : '')
|
||||
), true, false);
|
||||
|
||||
$label = 'error' . str_replace('_', '', $error);
|
||||
if ($this->plugin->rc->text_exists($label, 'kolab_sso')) {
|
||||
return $this->plugin->gettext($label);
|
||||
if (!$this->plugin->rc->text_exists($label, 'kolab_sso')) {
|
||||
$label = 'errorunknown';
|
||||
}
|
||||
|
||||
return $this->plugin->gettext('responseerrorunknown');
|
||||
return $this->plugin->gettext($label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns error message for specified OpenIDC error code
|
||||
* Returns error text for specified OpenIDC error code
|
||||
*/
|
||||
protected function error_message($error)
|
||||
protected function error_text($error)
|
||||
{
|
||||
switch ($error) {
|
||||
// OAuth2 codes
|
||||
|
@ -389,11 +401,11 @@ class kolab_sso_openidc
|
|||
case 'invalid_request_object':
|
||||
return "Invalid Request Object";
|
||||
case 'request_not_supported':
|
||||
return "Request param not supported";
|
||||
return "Request not supported";
|
||||
case 'request_uri_not_supported':
|
||||
return "request_uri param not supported";
|
||||
case 'registration_not_supported':
|
||||
return "Registration parameter not supported";
|
||||
return "Registration not supported";
|
||||
}
|
||||
|
||||
return "Unknown error";
|
||||
|
|
|
@ -27,6 +27,7 @@ class kolab_sso extends rcube_plugin
|
|||
private $data;
|
||||
private $old_data;
|
||||
private $driver;
|
||||
private $logon_error;
|
||||
private $debug = false;
|
||||
|
||||
|
||||
|
@ -68,6 +69,9 @@ class kolab_sso extends rcube_plugin
|
|||
$this->data['url'] = $_SESSION['sso_url'];
|
||||
$this->data['mode'] = $mode;
|
||||
}
|
||||
else {
|
||||
$this->logon_error = $driver->response_error();
|
||||
}
|
||||
}
|
||||
// This is where we handle clicking one of "Login by SSO" buttons
|
||||
else if ($_SESSION['temp'] && $this->rc->check_request()) {
|
||||
|
@ -168,6 +172,10 @@ class kolab_sso extends rcube_plugin
|
|||
$this->add_hook('ldap_connected', array($this, 'ldap_connected'));
|
||||
$this->add_hook('chwala_authenticate', array($this, 'chwala_authenticate'));
|
||||
}
|
||||
else if ($this->logon_error) {
|
||||
$args['valid'] = false;
|
||||
$args['error'] = $this->logon_error;
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
|
|
@ -2,3 +2,25 @@
|
|||
|
||||
$labels['loginby'] = 'Login by $provider';
|
||||
$labels['sso'] = 'Single Sign On';
|
||||
$labels['errorunknown'] = 'Unknown SSO error.';
|
||||
$labels['errorinvalidresponse'] = 'Invalid SSO response.';
|
||||
$labels['errortokenfailed'] = 'Failed to get SSO token.';
|
||||
$labels['errorivalidtoken'] = 'Invalid SSO token.';
|
||||
$labels['errorinvalidrequest'] = 'Malformed SSO request.';
|
||||
$labels['errorunauthorizedclient'] = 'Unauthorized SSO client.';
|
||||
$labels['errorinvalidclient'] = 'SSO client authentication failed.';
|
||||
$labels['erroraccessdienied'] = 'SSO request denied.';
|
||||
$labels['errorunsupportedresponsetype'] = 'Unsupported SSO response type.';
|
||||
$labels['errorinvalidgrant'] = 'Invalid authorization grant.';
|
||||
$labels['errorinvalidscope'] = 'Invalid SSO scope.';
|
||||
$labels['errorservererror'] = 'SSO server error.';
|
||||
$labels['errortemporarilyunavailable'] = 'SSO service temporarily unavailable.';
|
||||
$labels['errorinteractionrequired'] = 'User interaction required.';
|
||||
$labels['errorloginrequired'] = 'User authentication required.';
|
||||
$labels['erroraccountselectionrequired'] = 'User account selection required.';
|
||||
$labels['errorconsentrequired'] = 'User consent required.';
|
||||
$labels['errorinvalidrequesturi'] = 'Invalid request_uri.';
|
||||
$labels['errorinvalidrequestobject'] = 'Invalid request object';
|
||||
$labels['errorrequestnotsupported'] = 'Request not supported.';
|
||||
$labels['errorrequesturinotsupported'] = 'Request_uri parameter not supported.';
|
||||
$labels['errorregistrationnotsupported'] = 'Registration not supported';
|
||||
|
|
Loading…
Add table
Reference in a new issue