File: /var/roundcube/enhance_sso.php
<?php
class enhance_sso extends rcube_plugin
{
public $task = 'login|mail';
public function init()
{
$this->add_hook('startup', [$this, 'startup']);
$this->add_hook('authenticate', [$this, 'authenticate']);
}
public function startup($args)
{
if (!empty($_GET['token'])) {
$rcmail = rcmail::get_instance();
if (!empty($rcmail->user)){
$rcmail->logout_actions();
$rcmail->kill_session();
}
$args['task'] = 'login';
$args['action'] = 'login';
$_GET['_task'] = 'login';
$_GET['_action'] = 'login';
}
return $args;
}
public function authenticate($args)
{
if($_GET['token']){
$payload = ["ConsumeSsoToken" => [
'token' => $_GET['token'],
]];
$decoded = $this->appcd_request($payload);
$args['user'] = $decoded['email'];
$args['pass'] = $decoded['temporary_password'];
$args['cookiecheck'] = false;
}
return $args;
}
public function appcd_request(array $request, float $timeout = 30.0): ?array
{
$socketPath = '/var/run/enhance/unpriv.sock';
$errno = 0;
$errstr = '';
$fp = @stream_socket_client(
'unix://' . $socketPath,
$errno,
$errstr,
$timeout
);
if (!$fp) {
throw new RuntimeException("Failed to connect to appcd: $errstr ($errno)");
}
fwrite($fp, json_encode($request, JSON_UNESCAPED_SLASHES) . "\n");
$responseLine = fgets($fp);
fclose($fp);
if ($responseLine === false) {
return null;
}
$decoded = json_decode(trim($responseLine), true);
if (!is_array($decoded)) {
print_r($responseLine); die;
}
return $decoded;
}
}