340 lines
9.4 KiB
PHP
340 lines
9.4 KiB
PHP
<?php
|
|
|
|
/**
|
|
* WAP Client plugin.
|
|
*
|
|
* @version @package_version@
|
|
* @author Aleksander Machniak <machniak@kolabsys.com>
|
|
*
|
|
* Copyright (C) 2016, Kolab Systems AG <contact@kolabsys.com>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
class wap_client extends rcube_plugin
|
|
{
|
|
public $task = 'settings';
|
|
public $noajax = true;
|
|
|
|
protected $rc;
|
|
protected $wap;
|
|
protected $userinfo;
|
|
protected $token;
|
|
|
|
|
|
/**
|
|
* Initializes the plugin
|
|
*/
|
|
function init()
|
|
{
|
|
$this->rc = rcmail::get_instance();
|
|
|
|
$this->add_hook('preferences_list', array($this, 'prefs_table'));
|
|
$this->add_hook('preferences_save', array($this, 'save_prefs'));
|
|
}
|
|
|
|
/**
|
|
* Hook to inject plugin-specific user settings
|
|
*/
|
|
public function prefs_table($args)
|
|
{
|
|
global $CURR_SECTION;
|
|
|
|
if ($args['section'] != 'server') {
|
|
return;
|
|
}
|
|
|
|
$this->load_config();
|
|
|
|
$accounts = (array) $this->rc->config->get('wap_client_accounts');
|
|
|
|
if (empty($accounts)) {
|
|
return;
|
|
}
|
|
|
|
$this->add_texts('localization');
|
|
|
|
if ($CURR_SECTION) {
|
|
$account_type = $this->get_account_type();
|
|
$_SESSION['wap_client_account_type'] = $account_type;
|
|
}
|
|
|
|
$input = new html_radiobutton(array('name' => '_account_type', 'style' => 'display:block; float:left'));
|
|
$content = '';
|
|
|
|
foreach ($accounts as $idx => $def) {
|
|
$id = 'account_type_' . strtolower(asciiwords($idx, true));
|
|
$name = $idx;
|
|
$name = $this->rc->text_exists('wap_client.account.' . $name) ? $this->gettext('account.' . $name) : $name;
|
|
$desc = $this->rc->text_exists('wap_client.accountdesc.' . $name) ? $this->gettext('accountdesc.' . $name) : $def['description'];
|
|
|
|
$name = html::span(array('style' => 'font-weight: bold'), rcube::Q($name));
|
|
if ($desc) {
|
|
$name .= html::br() . html::span(null, rcube::Q($desc));
|
|
}
|
|
|
|
$label_style = 'display:block; margin: 5px 0; padding-left: 30px';
|
|
$content .= $input->show($account_type, array('value' => $idx, 'id' => $id))
|
|
. html::label(array('for' => $id, 'style' => $label_style), $name);
|
|
}
|
|
|
|
$conf = array(
|
|
'account' => array(
|
|
'name' => rcube::Q($this->gettext('accountoptions')),
|
|
'options' => array(
|
|
'account_type' => array(
|
|
'title' => $this->gettext('accounttype'),
|
|
'content' => $content,
|
|
)
|
|
)
|
|
)
|
|
);
|
|
|
|
$args['blocks'] = array_merge($conf, $args['blocks']);
|
|
|
|
return $args;
|
|
}
|
|
|
|
/**
|
|
* Hook to save plugin-specific user settings
|
|
*/
|
|
public function save_prefs($args)
|
|
{
|
|
if ($args['section'] != 'server') {
|
|
return;
|
|
}
|
|
|
|
$account_type = rcube_utils::get_input_value('_account_type', rcube_utils::INPUT_POST);
|
|
|
|
if (!$account_type || $account_type == $_SESSION['wap_client_account_type']) {
|
|
return;
|
|
}
|
|
|
|
$this->add_texts('localization');
|
|
|
|
$this->set_account_type($account_type);
|
|
}
|
|
|
|
/**
|
|
* Get current account type (from WAP)
|
|
*/
|
|
protected function get_account_type()
|
|
{
|
|
$this->init_wap();
|
|
|
|
if (empty($this->userinfo)) {
|
|
$this->rc->output->show_message($this->gettext('failedtypedetection'), 'warning');
|
|
return;
|
|
}
|
|
|
|
$roles = (array) $this->userinfo['nsroledn'];
|
|
$accounts = (array) $this->rc->config->get('wap_client_accounts');
|
|
$root_dn = $this->rc->config->get('wap_client_root_dn');
|
|
$base_dn = $this->rc->config->get('wap_client_base_dn');
|
|
|
|
foreach ($accounts as $name => $account) {
|
|
foreach ((array) $account['nsroledn'] as $role) {
|
|
$value = str_replace('$base_dn', $base_dn, $value);
|
|
$value = str_replace('$root_dn', $root_dn, $value);
|
|
|
|
if (!in_array($value, $roles)) {
|
|
continue 2;
|
|
}
|
|
}
|
|
|
|
return $name;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set account type (in WAP)
|
|
*/
|
|
protected function set_account_type($type)
|
|
{
|
|
if (!$this->init_wap()) {
|
|
return false;
|
|
}
|
|
|
|
$query = $this->userinfo;
|
|
$accounts = (array) $this->rc->config->get('wap_client_accounts');
|
|
$root_dn = $this->rc->config->get('wap_client_root_dn');
|
|
$base_dn = $this->rc->config->get('wap_client_base_dn');
|
|
$account = $accounts[$type];
|
|
|
|
if (empty($account)) {
|
|
$this->rc->output->show_message($this->gettext('failedtypeupdate'), 'warning');
|
|
return;
|
|
}
|
|
|
|
unset($account['description']);
|
|
|
|
foreach ($account as $attr => $value) {
|
|
switch ($attr) {
|
|
case 'nsroledn':
|
|
$value = array();
|
|
foreach ((array) $account['nsroledn'] as $role) {
|
|
$role = str_replace('$base_dn', $base_dn, $role);
|
|
$role = str_replace('$root_dn', $root_dn, $role);
|
|
$value[] = $role;
|
|
}
|
|
|
|
default:
|
|
$query[$attr] = $value;
|
|
}
|
|
}
|
|
|
|
$response = $this->post('user.edit', $query);
|
|
|
|
if (!$response || $response['status'] != 'OK') {
|
|
$this->rc->output->show_message($this->gettext('failedtypeupdate'), 'warning');
|
|
return;
|
|
}
|
|
|
|
$this->userinfo = $query;
|
|
}
|
|
|
|
/**
|
|
* Initialize WAP connection and user session
|
|
*/
|
|
protected function init_wap()
|
|
{
|
|
if ($this->wap) {
|
|
return $this->wap;
|
|
}
|
|
|
|
$this->load_config();
|
|
$this->require_plugin('libkolab');
|
|
|
|
$uri = $this->rc->config->get('wap_client_uri');
|
|
$user = $this->rc->get_user_name();
|
|
$pass = $this->rc->decrypt($_SESSION['password']);
|
|
|
|
if (!$uri) {
|
|
rcube::raise_error("wap_client_uri is not set", true, false);
|
|
return;
|
|
}
|
|
|
|
// get HTTP_Request2 object
|
|
$this->uri = rcube_utils::resolve_url($uri);
|
|
$this->wap = libkolab::http_request($this->uri);
|
|
|
|
$query = array(
|
|
'username' => $user,
|
|
'password' => $pass,
|
|
// 'domain' => $domain,
|
|
'info' => true,
|
|
);
|
|
|
|
// authenticate the user
|
|
$response = $this->post('system.authenticate', $query);
|
|
|
|
if ($response) {
|
|
$this->userinfo = $response['result']['info'];
|
|
$this->token = $response['result']['session_token'];
|
|
}
|
|
|
|
return $this->wap;
|
|
}
|
|
|
|
/**
|
|
* API's POST request.
|
|
*
|
|
* @param string $action Action name
|
|
* @param array $post POST arguments
|
|
*
|
|
* @return kolab_client_api_result Response
|
|
*/
|
|
protected function post($action, $post = array())
|
|
{
|
|
$url = $this->build_url($action);
|
|
|
|
if ($this->rc->config->get('wap_client_debug')) {
|
|
$this->rc->write_log('wap', "Calling API POST: $url\n" . @json_encode($post));
|
|
}
|
|
|
|
if ($this->token) {
|
|
$this->wap->setHeader('X-Session-Token', $this->token);
|
|
}
|
|
|
|
$this->wap->setMethod(HTTP_Request2::METHOD_POST);
|
|
$this->wap->setBody(@json_encode($post));
|
|
|
|
return $this->get_response($url);
|
|
}
|
|
|
|
/**
|
|
* Build Net_URL2 object for the request
|
|
*
|
|
* @param string $action Action GET parameter
|
|
* @param array $args GET parameters (hash array: name => value)
|
|
*
|
|
* @return Net_URL2 URL object
|
|
*/
|
|
private function build_url($action, $args = array())
|
|
{
|
|
$url = rtrim($this->uri, '/');
|
|
|
|
if ($action) {
|
|
$url .= '/' . urlencode($action);
|
|
}
|
|
|
|
$url = new Net_URL2($url);
|
|
|
|
if (!empty($args)) {
|
|
$url->setQueryVariables($args);
|
|
}
|
|
|
|
return $url;
|
|
}
|
|
|
|
/**
|
|
* HTTP Response handler.
|
|
*
|
|
* @param Net_URL2 $url URL object
|
|
*
|
|
* @return array Response data
|
|
*/
|
|
protected function get_response($url)
|
|
{
|
|
try {
|
|
$this->wap->setUrl($url);
|
|
$response = $this->wap->send();
|
|
}
|
|
catch (Exception $e) {
|
|
rcube::raise_error($e, true, false);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$body = $response->getBody();
|
|
}
|
|
catch (Exception $e) {
|
|
rcube::raise_error($e, true, false);
|
|
return;
|
|
}
|
|
|
|
if ($this->rc->config->get('wap_client_debug')) {
|
|
$this->rc->write_log('wap', "Response:\n$body");
|
|
}
|
|
|
|
$body = @json_decode($body, true);
|
|
|
|
if (!is_array($body)) {
|
|
rcube::raise_error("Failed to decode WAP response", true, false);
|
|
return;
|
|
}
|
|
|
|
return $body;
|
|
}
|
|
}
|