<?php
|
|
|
|
// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
|
|
//
|
|
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
|
|
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
|
|
// $Id$
|
|
|
|
//this script may only be included - so its better to die if called directly.
|
|
if (strpos($_SERVER['SCRIPT_NAME'], basename(__FILE__)) !== false) {
|
|
header('location: index.php');
|
|
exit;
|
|
}
|
|
|
|
class Tiki_Hm_Output_HTTP
|
|
{
|
|
public function send_response($response, $input = array())
|
|
{
|
|
if (array_key_exists('http_headers', $input)) {
|
|
return $this->output_content($response, $input['http_headers']);
|
|
} else {
|
|
return $this->output_content($response, array());
|
|
}
|
|
}
|
|
|
|
protected function output_headers($headers)
|
|
{
|
|
foreach ($headers as $name => $value) {
|
|
Hm_Functions::header($name . ': ' . $value);
|
|
}
|
|
}
|
|
|
|
protected function output_content($content, $headers = array())
|
|
{
|
|
$this->output_headers($headers);
|
|
return $content;
|
|
}
|
|
}
|
|
|
|
class Tiki_Hm_Custom_Session extends Hm_Session
|
|
{
|
|
|
|
/**
|
|
* check for an active session or an attempt to start one
|
|
* @param object $request request object
|
|
* @return bool
|
|
*/
|
|
public function check($request)
|
|
{
|
|
$this->active = session_status() == PHP_SESSION_ACTIVE;
|
|
return $this->is_active();
|
|
}
|
|
|
|
/**
|
|
* Start the session. This could be an existing session or a new login
|
|
* @param object $request request details
|
|
* @return void
|
|
*/
|
|
public function start($request, $existing_session = false)
|
|
{
|
|
// Tiki handles this
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Call the configured authentication method to check user credentials
|
|
* @param string $user username
|
|
* @param string $pass password
|
|
* @return bool true if the authentication was successful
|
|
*/
|
|
public function auth($user, $pass)
|
|
{
|
|
$userlib = TikiLib::lib('user');
|
|
list($isvalid, $user) = $userlib->validate_user($user, $pass);
|
|
return $isvalid;
|
|
}
|
|
|
|
/**
|
|
* Return a session value, or a user settings value stored in the session
|
|
* @param string $name session value name to return
|
|
* @param mixed $default value to return if $name is not found
|
|
* @return mixed the value if found, otherwise $defaultHm_Auth
|
|
*/
|
|
public function get($name, $default = false, $user = false)
|
|
{
|
|
if ($user) {
|
|
return array_key_exists($this->session_prefix(), $_SESSION) && array_key_exists('user_data', $_SESSION[$this->session_prefix()]) && array_key_exists($name, $_SESSION[$this->session_prefix()]['user_data']) ? $_SESSION[$this->session_prefix()]['user_data'][$name] : $default;
|
|
} else {
|
|
return array_key_exists($this->session_prefix(), $_SESSION) && array_key_exists($name, $_SESSION[$this->session_prefix()]) ? $_SESSION[$this->session_prefix()][$name] : $default;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save a value in the session
|
|
* @param string $name the name to save
|
|
* @param string $value the value to save
|
|
* @return void
|
|
*/
|
|
public function set($name, $value, $user = false)
|
|
{
|
|
if ($user) {
|
|
$_SESSION[$this->session_prefix()]['user_data'][$name] = $value;
|
|
} else {
|
|
$_SESSION[$this->session_prefix()][$name] = $value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a value from the session
|
|
* @param string $name name of value to delete
|
|
* @return void
|
|
*/
|
|
public function del($name)
|
|
{
|
|
if (array_key_exists($this->session_prefix(), $_SESSION) && array_key_exists($name, $_SESSION[$this->session_prefix()])) {
|
|
unset($_SESSION[$this->session_prefix()][$name]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* End a session after a page request is complete. This only closes the session and
|
|
* does not destroy it
|
|
* @return void
|
|
*/
|
|
public function end()
|
|
{
|
|
$this->active = false;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Destroy a session for good
|
|
* @param object $request request details
|
|
* @return void
|
|
*/
|
|
public function destroy($request)
|
|
{
|
|
if (function_exists('delete_uploaded_files')) {
|
|
delete_uploaded_files($this);
|
|
}
|
|
unset($_SESSION[$this->session_prefix()]);
|
|
$this->active = false;
|
|
}
|
|
|
|
/**
|
|
* Dump current session contents
|
|
* @return array
|
|
*/
|
|
public function dump()
|
|
{
|
|
if (array_key_exists($this->session_prefix(), $_SESSION)) {
|
|
return $_SESSION[$this->session_prefix()];
|
|
} else {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public function close_early()
|
|
{
|
|
// noop;
|
|
}
|
|
|
|
/**
|
|
* When Cypht runs in a wiki page as a wiki plugin and SEFURL is off
|
|
* replace all Cypht links to include the page_id of the wiki page
|
|
* so tiki-index can load the correct wiki page. Cypht reuses page param
|
|
* for its internal uses.
|
|
*/
|
|
public function dedup_page_links($output)
|
|
{
|
|
global $prefs;
|
|
if ($prefs['feature_sefurl'] === 'y') {
|
|
return $output;
|
|
}
|
|
if (! $this->get('page_id')) {
|
|
return $output;
|
|
}
|
|
$output = str_replace("?page=", "?page_id=" . $this->get('page_id') . "&page=", $output);
|
|
$output = str_replace('<input type="hidden" name="page" value=', '<input type="hidden" name="page_id" value="' . $this->get('page_id') . '"><input type="hidden" name="page" value=', $output);
|
|
$output = str_replace('<input type=\\"hidden\\" name=\\"page\\" value=', '<input type=\\"hidden\\" name=\\"page_id\\" value=\\"' . $this->get('page_id') . '\\"><input type=\\"hidden\\" name=\\"page\\" value=', $output);
|
|
return $output;
|
|
}
|
|
|
|
protected function session_prefix()
|
|
{
|
|
return $this->site_config->get('session_prefix') ?? 'cypht';
|
|
}
|
|
}
|
|
|
|
class Tiki_Hm_Site_Config_File extends Hm_Site_Config_File
|
|
{
|
|
public $settings_per_page;
|
|
/**
|
|
* Load data based on source
|
|
* Overrides default configuration for Tiki integration
|
|
* @param string $source source location for site configuration
|
|
*/
|
|
public function __construct($source, $session_prefix = 'cypht', $settings_per_page = false)
|
|
{
|
|
global $user;
|
|
parent::__construct($source);
|
|
// override
|
|
$headerlib = TikiLib::lib('header');
|
|
$this->set('session_type', 'custom');
|
|
$this->set('session_class', 'Tiki_Hm_Custom_Session');
|
|
$this->set('session_prefix', $session_prefix);
|
|
$this->set('auth_type', 'custom');
|
|
$this->set('output_class', 'Tiki_Hm_Output_HTTP');
|
|
$this->set('cookie_path', ini_get('session.cookie_path'));
|
|
if ($user && (empty($_SESSION[$session_prefix]['user_data']) || count($_SESSION[$session_prefix]['user_data']) == 2)) {
|
|
$user_config = new Tiki_Hm_User_Config($this);
|
|
$user_config->load($user);
|
|
$_SESSION[$session_prefix]['user_data'] = $user_config->dump();
|
|
}
|
|
$this->settings_per_page = $settings_per_page;
|
|
$output_modules = $this->get('output_modules');
|
|
$handler_modules = $this->get('handler_modules');
|
|
foreach ($output_modules as $page => $_) {
|
|
unset($output_modules[$page]['header_start']);
|
|
unset($output_modules[$page]['header_content']);
|
|
unset($output_modules[$page]['header_end']);
|
|
unset($output_modules[$page]['content_start']);
|
|
unset($output_modules[$page]['content_end']);
|
|
if (isset($output_modules[$page]['header_css'])) {
|
|
unset($output_modules[$page]['header_css']);
|
|
$headerlib->add_cssfile('lib/cypht/site.css');
|
|
$headerlib->add_cssfile('lib/cypht/modules/tiki/site.css');
|
|
}
|
|
if (isset($output_modules[$page]['page_js'])) {
|
|
unset($output_modules[$page]['page_js']);
|
|
$headerlib->add_jsfile('lib/cypht/jquery.touch.js', true);
|
|
$headerlib->add_jsfile('lib/cypht/site.js', true);
|
|
}
|
|
}
|
|
// cleanup side menu
|
|
unset($output_modules['ajax_hm_folders']['logout_menu_item']);
|
|
unset($output_modules['ajax_hm_folders']['contacts_page_link']);
|
|
unset($output_modules['ajax_hm_folders']['settings_save_link']);
|
|
// show links according to permissions
|
|
if (! Perms::get()->admin_personal_webmail && ! Perms::get()->admin_group_webmail) {
|
|
unset($output_modules['ajax_hm_folders']['settings_servers_link']);
|
|
unset($output_modules['ajax_hm_folders']['folders_page_link']);
|
|
unset($output_modules['home']['welcome_dialog']);
|
|
unset($handler_modules['ajax_imap_folder_expand']['add_folder_manage_link']);
|
|
}
|
|
foreach ($handler_modules as $page => $modules) {
|
|
foreach ($modules as $module => $opts) {
|
|
if ($module == 'http_headers') {
|
|
$handler_modules[$page]['http_headers_tiki'] = ['tiki', true];
|
|
}
|
|
}
|
|
}
|
|
$this->set('output_modules', $output_modules);
|
|
$this->set('handler_modules', $handler_modules);
|
|
if (empty($_SESSION[$session_prefix]['user_data']['timezone_setting'])) {
|
|
$this->user_defaults['timezone_setting'] = TikiLib::lib('tiki')->get_display_timezone();
|
|
if (isset($_SESSION[$session_prefix]['user_data'])) {
|
|
$_SESSION[$session_prefix]['user_data']['timezone_setting'] = $this->user_defaults['timezone_setting'];
|
|
}
|
|
}
|
|
if (isset($_SESSION[$session_prefix]['user_data']['allow_external_images_setting'])) {
|
|
$this->set('allow_external_image_sources', $_SESSION[$session_prefix]['user_data']['allow_external_images_setting']);
|
|
}
|
|
// handle oauth2 config
|
|
$oauth2 = array(
|
|
'gmail' => array(
|
|
'client_id' => '',
|
|
'client_secret' => '',
|
|
'client_uri' => '',
|
|
'auth_uri' => '',
|
|
'token_uri' => '',
|
|
'refresh_uri' => '',
|
|
),
|
|
'outlook' => array(
|
|
'client_id' => '',
|
|
'client_secret' => '',
|
|
'client_uri' => '',
|
|
'auth_uri' => '',
|
|
'token_uri' => '',
|
|
'refresh_uri' => '',
|
|
),);
|
|
if (isset($_SESSION[$session_prefix]['user_data']['tiki_enable_oauth2_over_imap_setting'])) {
|
|
$this->set('tiki_enable_oauth2_over_imap', $_SESSION[$session_prefix]['user_data']['tiki_enable_oauth2_over_imap_setting']);
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['tiki_enable_gmail_contacts_module_setting'])) {
|
|
$this->set('tiki_enable_gmail_contacts_module', $_SESSION[$session_prefix]['user_data']['tiki_enable_gmail_contacts_module_setting']);
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['gmail_client_id_setting'])) {
|
|
$oauth2['gmail']['client_id'] = $_SESSION[$session_prefix]['user_data']['gmail_client_id_setting'];
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['gmail_client_secret_setting'])) {
|
|
$oauth2['gmail']['client_secret'] = $_SESSION[$session_prefix]['user_data']['gmail_client_secret_setting'];
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['gmail_client_uri_setting'])) {
|
|
$oauth2['gmail']['client_uri'] = $_SESSION[$session_prefix]['user_data']['gmail_client_uri_setting'];
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['gmail_auth_uri_setting'])) {
|
|
$oauth2['gmail']['auth_uri'] = $_SESSION[$session_prefix]['user_data']['gmail_auth_uri_setting'];
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['gmail_token_uri_setting'])) {
|
|
$oauth2['gmail']['token_uri'] = $_SESSION[$session_prefix]['user_data']['gmail_token_uri_setting'];
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['gmail_refresh_uri_setting'])) {
|
|
$oauth2['gmail']['refresh_uri'] = $_SESSION[$session_prefix]['user_data']['gmail_refresh_uri_setting'];
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['outlook_client_id_setting'])) {
|
|
$oauth2['outlook']['client_id'] = $_SESSION[$session_prefix]['user_data']['outlook_client_id_setting'];
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['outlook_client_secret_setting'])) {
|
|
$oauth2['outlook']['client_secret'] = $_SESSION[$session_prefix]['user_data']['outlook_client_secret_setting'];
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['outlook_client_uri_setting'])) {
|
|
$oauth2['outlook']['client_uri'] = $_SESSION[$session_prefix]['user_data']['outlook_client_uri_setting'];
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['outlook_auth_uri_setting'])) {
|
|
$oauth2['outlook']['auth_uri'] = $_SESSION[$session_prefix]['user_data']['outlook_auth_uri_setting'];
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['outlook_token_uri_setting'])) {
|
|
$oauth2['outlook']['token_uri'] = $_SESSION[$session_prefix]['user_data']['outlook_token_uri_setting'];
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['outlook_refresh_uri_setting'])) {
|
|
$oauth2['outlook']['refresh_uri'] = $_SESSION[$session_prefix]['user_data']['outlook_refresh_uri_setting'];
|
|
}
|
|
|
|
if (isset($_SESSION[$session_prefix]['user_data']['tiki_enable_oauth2_over_imap_setting']) && $_SESSION[$session_prefix]['user_data']['tiki_enable_oauth2_over_imap_setting'] == 1) {
|
|
$this->set('oauth2.ini', $oauth2);
|
|
if (isset($_SESSION[$session_prefix]['user_data']['tiki_enable_gmail_contacts_module_setting']) && $_SESSION[$session_prefix]['user_data']['tiki_enable_gmail_contacts_module_setting'] == 1) {
|
|
array_push($this->config['modules'], 'gmail_contacts');
|
|
$gmail_contact = array(
|
|
'load_gmail_contacts' => array(
|
|
'0' => 'gmail_contacts',
|
|
'1' => 1
|
|
)
|
|
);
|
|
array_push($this->config['handler_modules']['contacts'], $gmail_contact);
|
|
} else {
|
|
unset($this->config['modules']['gmail_contacts']);
|
|
unset($this->config['handler_modules']['contacts']['load_gmail_contacts']);
|
|
}
|
|
} else {
|
|
if (isset($this->config['oauth2.ini'])) {
|
|
$this->del('oauth2.ini');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Override user config handling in Cypht.
|
|
* Store settings in Tiki user preferences and load them from there.
|
|
* Ignore encryption and decryption of the settings due to missing password key when loading.
|
|
*/
|
|
class Tiki_Hm_User_Config extends Hm_Config
|
|
{
|
|
/* username */
|
|
private $username;
|
|
private $site_config;
|
|
|
|
/**
|
|
* Load site configuration
|
|
* @param object $config site config
|
|
*/
|
|
public function __construct($config)
|
|
{
|
|
$this->config = array_merge($this->config, $config->user_defaults);
|
|
$this->site_config = $config;
|
|
}
|
|
|
|
/**
|
|
* Load the settings for a user
|
|
* @param string $username username
|
|
* @param string $key key to decrypt the user data (not used)
|
|
* @return void
|
|
*/
|
|
public function load($username, $key = null)
|
|
{
|
|
$this->username = $username;
|
|
$session_prefix = $this->site_config->get('session_prefix');
|
|
if ($this->site_config->settings_per_page) {
|
|
$data = $_SESSION[$session_prefix]['plugin_data'] ?? TikiLib::lib('tiki')->get_user_preference('%', $_SESSION[$session_prefix]['preference_name']);
|
|
} else {
|
|
$data = TikiLib::lib('tiki')->get_user_preference($username, $_SESSION[$session_prefix]['preference_name']);
|
|
}
|
|
if ($data) {
|
|
$data = $this->decode($data);
|
|
$this->config = array_merge($this->config, $data);
|
|
$this->set_tz();
|
|
}
|
|
// merge imap/smtp servers config with session as plugin cypht might be overriding these
|
|
foreach (['imap_servers', 'smtp_servers'] as $key) {
|
|
if (! empty($_SESSION[$session_prefix]['user_data'][$key])) {
|
|
if (empty($this->config[$key])) {
|
|
$this->config[$key] = [];
|
|
}
|
|
foreach ($_SESSION[$session_prefix]['user_data'][$key] as $server) {
|
|
$found = false;
|
|
foreach ($this->config[$key] as $cserver) {
|
|
if ($server['server'] == $cserver['server'] && $server['tls'] == $cserver['tls'] && $server['port'] == $cserver['port'] && $server['user'] == $cserver['user']) {
|
|
$found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (! $found) {
|
|
do {
|
|
$id = uniqid();
|
|
} while (isset($this->config[$key][$id]));
|
|
$this->config[$key][$id] = $server;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reload from outside input - done upon load_user_data handler executed in Cypht.
|
|
* This loads user confirm from session but also saves to persistent storage
|
|
* as Tiki-Cypht does not warn user about unsaved settings when logging out...
|
|
* @param array $data new user data
|
|
* @param string $username
|
|
* @return void
|
|
*/
|
|
public function reload($data, $username = false)
|
|
{
|
|
$this->username = $username;
|
|
$this->config = $data;
|
|
$this->set_tz();
|
|
if ($username) {
|
|
$temp_config = new Tiki_Hm_User_Config($this->site_config);
|
|
$temp_config->load($username);
|
|
$existing = $temp_config->dump();
|
|
ksort($existing);
|
|
ksort($data);
|
|
if (json_encode($existing) != json_encode($data)) {
|
|
$this->save($username);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save user settings into Tiki
|
|
* @param string $username username
|
|
* @param string $key encryption key (not used)
|
|
* @return void
|
|
*/
|
|
public function save($username = null, $key = null)
|
|
{
|
|
if ($this->get('skip_saving_on_set', false)) {
|
|
return;
|
|
}
|
|
if (empty($username)) {
|
|
$username = $this->username;
|
|
}
|
|
$this->shuffle();
|
|
$removed = $this->filter_servers();
|
|
ksort($this->config);
|
|
$data = json_encode($this->config);
|
|
if ($this->site_config->settings_per_page) {
|
|
$original_plugin_data = $_SESSION[$this->site_config->get('session_prefix')]['plugin_data'] ?? '';
|
|
if ($original_plugin_data != $data) {
|
|
$util = new Services_Edit_Utilities();
|
|
$util->replacePlugin(new JitFilter([
|
|
'page' => $this->site_config->settings_per_page,
|
|
'message' => "Auto-saving Cypht settings.",
|
|
'type' => 'cypht',
|
|
'content' => $data,
|
|
'index' => 1
|
|
]), false);
|
|
}
|
|
} else {
|
|
TikiLib::lib('tiki')->set_user_preference($username, $_SESSION[$this->site_config->get('session_prefix')]['preference_name'], $data);
|
|
}
|
|
$this->restore_servers($removed);
|
|
}
|
|
|
|
/**
|
|
* Set a config value
|
|
* @param string $name config value name
|
|
* @param string $value config value
|
|
* @return void
|
|
*/
|
|
public function set($name, $value)
|
|
{
|
|
$this->config[$name] = $value;
|
|
$this->save($this->username);
|
|
}
|
|
|
|
/**
|
|
* Clear state variables in server list like 'object' and 'connected'.
|
|
* Pass the rest of the cleanup to parent.
|
|
*/
|
|
public function filter_servers() {
|
|
foreach ($this->config as $key => $vals) {
|
|
if (in_array($key, ['pop3_servers', 'imap_servers', 'smtp_servers'])) {
|
|
foreach ($vals as $index => $server) {
|
|
$this->config[$key][$index]['object'] = false;
|
|
$this->config[$key][$index]['connected'] = false;
|
|
}
|
|
}
|
|
}
|
|
return parent::filter_servers();
|
|
}
|
|
}
|