WAP Client plugin (T1124)
This commit is contained in:
parent
4fe52716e3
commit
ed93508c8a
4 changed files with 429 additions and 0 deletions
26
plugins/wap_client/composer.json
Normal file
26
plugins/wap_client/composer.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "kolab/wap_client",
|
||||
"type": "roundcube-plugin",
|
||||
"description": "Kolab Web Admin Client",
|
||||
"homepage": "https://git.kolab.org/diffusion/RPK/",
|
||||
"license": "AGPLv3",
|
||||
"version": "0.1.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Aleksander Machniak",
|
||||
"email": "machniak@kolabsys.com",
|
||||
"role": "Lead"
|
||||
}
|
||||
],
|
||||
"repositories": [
|
||||
{
|
||||
"type": "composer",
|
||||
"url": "http://plugins.roundcube.net"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"roundcube/plugin-installer": ">=0.1.3",
|
||||
"kolab/libkolab": ">=3.2.8"
|
||||
}
|
||||
}
|
49
plugins/wap_client/config.inc.php.dist
Normal file
49
plugins/wap_client/config.inc.php.dist
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Kolab WAP Client plugin configuration
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
// Kolab WAP API URL
|
||||
$config['wap_client_uri'] = '/kolab-webadmin/api';
|
||||
|
||||
// Log conversation with WAP
|
||||
$config['wap_client_debug'] = false;
|
||||
|
||||
// Domain root DN
|
||||
$config['wap_client_root_dn'] = 'dc=example,dc=org';
|
||||
|
||||
// Domain base DN
|
||||
$config['wap_client_base_dn'] = 'dc=example,dc=org';
|
||||
|
||||
// Accounts definition
|
||||
$config['wap_client_accounts'] = array();
|
||||
/*
|
||||
$config['wap_client_accounts'] = array(
|
||||
'Lite' => array(
|
||||
'description' => 'Mail account with 2GB quota',
|
||||
'nsroledn' => array('cn=imap-user,$base_dn', 'cn=active-user,$root_dn'),
|
||||
'mailquota' => 2097152,
|
||||
),
|
||||
'Professional' => array(
|
||||
'description' => 'Professional groupware account with 10GB quota',
|
||||
'nsroledn' => array('cn=activesync-user,$base_dn', 'cn=kolab-user,$base_dn', 'cn=active-user,$root_dn'),
|
||||
'mailquota' => 10485760,
|
||||
),
|
||||
);
|
||||
*/
|
14
plugins/wap_client/localization/en_US.inc
Normal file
14
plugins/wap_client/localization/en_US.inc
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Localizations for the WPA Clien plugin
|
||||
*
|
||||
* Copyright (C) 2016, Kolab Systems AG
|
||||
*
|
||||
* For translation see https://www.transifex.com/projects/p/kolab/resource/wpa_client/
|
||||
*/
|
||||
|
||||
$labels['accountoptions'] = 'Account options';
|
||||
$labels['accounttype'] = 'Account type';
|
||||
$labels['failedtypedetection'] = 'Failed to retrieve account type.';
|
||||
$labels['failedtypeupdate'] = 'Failed to change account type.';
|
340
plugins/wap_client/wap_client.php
Normal file
340
plugins/wap_client/wap_client.php
Normal file
|
@ -0,0 +1,340 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue