Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None
diff --git a/plugins/kolab/Kolab/Configuration.php b/plugins/kolab/Kolab/Configuration.php
index 08d82b03..a8b9c6ed 100644
--- a/plugins/kolab/Kolab/Configuration.php
+++ b/plugins/kolab/Kolab/Configuration.php
@@ -1,175 +1,222 @@
<?php
namespace Kolab;
/**
* This feature sets configuration options specific to logged in user.
*/
class Configuration extends Feature
{
+ private $done = false;
+
/**
* Feature initialization
*/
public function init()
{
$this->plugin->add_hook('startup', [$this, 'startupHook']);
$this->plugin->add_hook('ready', [$this, 'readyHook']);
+ $this->plugin->add_hook('authenticate', [$this, 'authenticateHook']);
}
/**
* Apply configuration overlay
*/
private function applyConfigurationOverlays($overlays): void
{
$overlaySettings = (array) $this->rc->config->get('configuration-overlays');
foreach ($overlays as $overlay) {
if (!array_key_exists($overlay, $overlaySettings)) {
\rcube::raise_error("Can't find configuration overlay: $overlay", true);
continue;
}
$this->applyConfiguration($overlaySettings[$overlay]);
}
}
/**
* Apply configuration
*/
private function applyConfiguration($config): void
{
foreach ($config as $key => $value) {
$mode = null;
if (preg_match('/^merge:/', $key)) {
$mode = 'merge';
$key = substr($key, 6);
}
switch ($key) {
case 'kolab-configuration-overlays':
$this->applyConfigurationOverlays($value);
continue 2;
case 'plugins':
foreach ($value as $plugin) {
- // Note that kolab_2fa plugin does not work when kolab_auth plugin is disabled,
- // it does not inject itself into authentication process. We may be able to fix
- // that, but since in Kolab4 we use SSO this should not be an issue.
- // The 2FA UI should still work.
- // In the future we might move this UI into Cockpit or use companion app
- // and drop the plugin completely.
-
if (!$this->rc->plugins->get_plugin($plugin)) {
- $this->rc->plugins->load_plugin($plugin);
+ $loaded = $this->rc->plugins->load_plugin($plugin);
+
+ // Depending on whether we load the kolab_2fa plugin from startup hook
+ // or other (in logon process or in settings) we might need to invoke its
+ // startup initialization code
+ if ($loaded && $plugin == 'kolab_2fa' && $this->rc->task != 'settings') {
+ /** @var \kolab_2fa $kolab_2fa */
+ $kolab_2fa = $this->rc->plugins->get_plugin($plugin);
+ $kolab_2fa->startup(['task' => $this->rc->task ?? '', 'action' => $this->rc->action ?? '']);
+ }
}
}
break;
case 'skin':
if ($this->rc->output->type == 'html') {
$this->rc->output->set_skin($value);
$this->rc->output->set_env('skin', $value);
}
break;
case 'debug':
$this->setDebug($value);
break;
default:
if ($mode == 'merge') {
$orig_setting = $this->rc->config->get($key);
if (!empty($orig_setting) && is_array($orig_setting) && is_array($value)) {
$value = array_merge($orig_setting, $value);
}
}
$this->rc->config->set($key, $value);
}
}
}
/**
* Enable debug logging for the current user
*/
private function setDebug($mode = ''): void
{
if (!$mode) {
return;
}
if (defined('KOLAB_SYNC_START') && !str_contains($mode, 'syncroton')) {
return;
}
if (defined('RCMAIL_VERSION') && !str_contains($mode, 'roundcube')) {
return;
}
if (defined('FILE_API_START') && !str_contains($mode, 'chwala')) {
return;
}
$opts = [
'activesync_debug',
'dav_debug',
'imap_debug',
'kolab_debug',
'ldap_debug',
'oauth_debug',
'redis_debug',
'smtp_debug',
'sql_debug',
'performance_stats',
];
foreach ($opts as $key) {
$this->rc->config->set($key, true);
}
if (class_exists('kolab_sync_logger')) {
// We have to set activesync_debug mode directly on the logger, as the framework is already initialized
if ($this->rc->logger) {
$this->rc->logger->mode = \kolab_sync_logger::DEBUG;
}
// Same goes for the storage debug mode (IMAP)
if ($this->rc->storage) {
$this->rc->storage->set_debug(true);
}
}
// SQL debug need to be set directly on DB object. Setting config variable will not work here
// because the object is already initialized/configured
if ($db = $this->rc->get_dbh()) {
$db->set_debug(true);
}
}
+ /**
+ * Authentication hook handler
+ */
+ public function authenticateHook($args): array
+ {
+ // Startup handler is not enough to properly load kolab_2fa plugin
+ // for the webmail logon page
+ if (defined('RCMAIL_START') && empty($args['abort']) && !empty($args['valid'])
+ && empty($args['sso']) && $args['user'] !== '' && $args['pass'] !== ''
+ ) {
+ $this->rc->user->data = ['username' => $args['user']];
+ $this->rc->password = $args['pass'];
+ $this->applyConfiguration($this->getConfig());
+ }
+
+ return $args;
+ }
+
/**
* Startup hook handler
*/
public function startupHook($args): array
{
// For Kolab Syncroton we have to use the 'ready' hook.
if ($args['task'] != 'syncroton') {
- $this->applyConfiguration(Client::getMyConfig());
+ // For the 2FA logon step we have to use user credentials from the session
+ // to get the configuration and be able to enable the kolab_2fa plugin
+ if ($args['task'] == 'login' && !empty($_SESSION['kolab_2fa_factors'])) {
+ // note: password is already set in session
+ $this->rc->user->data = ['username' => $_SESSION['username']];
+ }
+
+ $this->applyConfiguration($this->getConfig());
}
return $args;
}
/**
* Ready hook handler
*/
public function readyHook($args): array
{
// For Kolab Syncroton we have to use the 'ready' hook. In 'startup' hook
// user is not yet authenticated.
if ($args['task'] == 'syncroton') {
- $this->applyConfiguration(Client::getMyConfig());
+ $this->applyConfiguration($this->getConfig());
}
return $args;
}
+
+ /**
+ * Get webmail configuration for Kolab API
+ */
+ private function getConfig(): array
+ {
+ if ($this->done) {
+ // We make sure to trigger configuration once per request
+ return [];
+ }
+
+ $config = Client::getMyConfig();
+
+ $this->done = !empty($config);
+
+ return $config;
+ }
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Apr 4, 9:40 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18823502
Default Alt Text
(7 KB)

Event Timeline