summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2012-08-06 15:09:54 +0200
committerJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2012-08-06 15:09:54 +0200
commit0e2c7ea47b6fd7793883ba17445695db75739a69 (patch)
treed3edc928182157452154d7f59bb75a8178be87a5 /lib
parenta5ef1ae5ba0c1ac48ccebfa0341502104b7650e5 (diff)
parentd72a65514e28d73b13209183567609e2a2e1f564 (diff)
downloadwebadmin-0e2c7ea47b6fd7793883ba17445695db75739a69.tar.gz
Merge branch 'master' of ssh://git.kolab.org/git/kolab-wap
Diffstat (limited to 'lib')
-rw-r--r--lib/Auth/LDAP.php17
-rw-r--r--lib/Conf.php8
-rw-r--r--lib/api/kolab_api_service_domain.php10
-rw-r--r--lib/client/kolab_client_task_resource.php20
-rw-r--r--lib/functions.php1
-rw-r--r--lib/hosted/kolab_client_task_signup.php310
-rw-r--r--lib/hosted/recaptchalib.php277
-rw-r--r--lib/kolab_client_api.php1
-rw-r--r--lib/kolab_client_task.php40
-rw-r--r--lib/locale/en_US.php1
10 files changed, 649 insertions, 36 deletions
diff --git a/lib/Auth/LDAP.php b/lib/Auth/LDAP.php
index 28233c1..8fb5f42 100644
--- a/lib/Auth/LDAP.php
+++ b/lib/Auth/LDAP.php
@@ -899,6 +899,9 @@ class LDAP
if (empty($base_dn))
$base_dn = $this->conf->get('ldap', $type_str . "_user_base_dn");
+ if (empty($base_dn))
+ $base_dn = $this->conf->get('ldap', "user_base_dn");
+
// If still no base dn to add the user to... use the toplevel dn
if (empty($base_dn))
$base_dn = $this->conf->get($this->domain, "base_dn");
@@ -988,13 +991,14 @@ class LDAP
*/
private function domain_root_dn($domain = '')
{
+ //console("Auth::LDAP::domain_root_dn(\$domain) called with \$domain", $domain);
$conf = Conf::get_instance();
if ($domain == '') {
return false;
}
- if (!$this->_connect($domain)) {
+ if (!$this->_connect()) {
return false;
}
@@ -1019,13 +1023,14 @@ class LDAP
);
$result = $result[key($result)];
+ //console("intermediate result for domain_root_dn()", $result);
if (is_array($result)) {
- if (in_array('inetdomainbasedn', $result)) {
+ if (in_array('inetdomainbasedn', $result) && !empty($result['inetdomainbasedn'])) {
return $result['inetdomainbasedn'];
} else {
if (is_array($result[$domain_name_attribute])) {
- return $this->_standard_root_dn($result[$domain_name_attribute[0]]);
+ return $this->_standard_root_dn($result[$domain_name_attribute][0]);
} else {
return $this->_standard_root_dn($result[$domain_name_attribute]);
}
@@ -1068,6 +1073,10 @@ class LDAP
private function domains_list()
{
+ $conf = Conf::get_instance();
+
+ $this->_bind($conf->get('bind_dn'), $conf->get('bind_pw'));
+
$section = $this->conf->get('kolab', 'auth_mechanism');
$base_dn = $this->conf->get($section, 'domain_base_dn');
$filter = $this->conf->get($section, 'domain_filter');
@@ -1100,6 +1109,8 @@ class LDAP
private function entry_find_by_attribute($attribute, $base_dn = null)
{
+ //console("Auth::LDAP::entry_find_by_attribute(\$attribute, \$base_dn) called with base_dn", $base_dn);
+
if (empty($attribute) || !is_array($attribute)) {
return false;
}
diff --git a/lib/Conf.php b/lib/Conf.php
index e91110c..a207f79 100644
--- a/lib/Conf.php
+++ b/lib/Conf.php
@@ -57,7 +57,6 @@ class Conf {
}
$this->read_config();
-
}
public function get($key1, $key2 = null, $type = null)
@@ -127,9 +126,10 @@ class Conf {
return $this->_conf[$domain_section_name][$key1];
}
} catch (Exception $e) {
- $domain_section_name = $this->get_raw('kolab', 'primary_domain');
- if (isset($this->_conf[$domain_section_name][$key1])) {
- return $this->_conf[$domain_section_name][$key1];
+ if ($domain_section_name = $this->_conf['kolab']['primary_domain']) {
+ if (isset($this->_conf[$domain_section_name][$key1])) {
+ return $this->_conf[$domain_section_name][$key1];
+ }
}
}
}
diff --git a/lib/api/kolab_api_service_domain.php b/lib/api/kolab_api_service_domain.php
index 750062c..7f93de6 100644
--- a/lib/api/kolab_api_service_domain.php
+++ b/lib/api/kolab_api_service_domain.php
@@ -92,8 +92,14 @@ class kolab_api_service_domain extends kolab_api_service
return;
}
- $auth = Auth::get_instance();
- $auth->domain_add($postdata[$dna]);
+ $auth = Auth::get_instance($conf->get('kolab', 'primary_domain'));
+
+ if (is_array($postdata[$dna])) {
+ $parent_domain = array_shift($postdata[$dna]);
+ return $auth->domain_add($parent_domain, $postdata[$dna]);
+ } else {
+ return $auth->domain_add($postdata[$dna]);
+ }
}
public function domain_edit($getdata, $postdata)
diff --git a/lib/client/kolab_client_task_resource.php b/lib/client/kolab_client_task_resource.php
index 5e3f7a2..55ece20 100644
--- a/lib/client/kolab_client_task_resource.php
+++ b/lib/client/kolab_client_task_resource.php
@@ -326,4 +326,24 @@ class kolab_client_task_resource extends kolab_client_task
return $form->output();
}
+ /**
+ * Returns list of resource types.
+ *
+ * @return array List of resource types
+ */
+ public function resource_types()
+ {
+ if (isset($_SESSION['resource_types'])) {
+ return $_SESSION['resource_types'];
+ }
+
+ $result = $this->api->post('resource_types.list');
+ $list = $result->get('list');
+
+ if (is_array($list) && !$this->config_get('devel_mode')) {
+ $_SESSION['resource_types'] = $list;
+ }
+
+ return $list;
+ }
}
diff --git a/lib/functions.php b/lib/functions.php
index 9761358..8c74cf7 100644
--- a/lib/functions.php
+++ b/lib/functions.php
@@ -47,6 +47,7 @@ $include_path = INSTALL_PATH . PATH_SEPARATOR;
$include_path .= INSTALL_PATH . '/client' . PATH_SEPARATOR;
$include_path .= INSTALL_PATH . '/api' . PATH_SEPARATOR;
$include_path .= INSTALL_PATH . '/ext' . PATH_SEPARATOR;
+$include_path .= INSTALL_PATH . '/hosted' . PATH_SEPARATOR;
$include_path .= ini_get('include_path');
if (set_include_path($include_path) === false) {
diff --git a/lib/hosted/kolab_client_task_signup.php b/lib/hosted/kolab_client_task_signup.php
new file mode 100644
index 0000000..50b784b
--- /dev/null
+++ b/lib/hosted/kolab_client_task_signup.php
@@ -0,0 +1,310 @@
+<?php
+/*
+ +--------------------------------------------------------------------------+
+ | This file is part of the Kolab Web Admin Panel |
+ | |
+ | Copyright (C) 2011-2012, Kolab Systems AG |
+ | |
+ | 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/> |
+ +--------------------------------------------------------------------------+
+ | Author: Aleksander Machniak <machniak@kolabsys.com> |
+ | Author: Torsten Grote <grote@kolabsys.com> |
+ +--------------------------------------------------------------------------+
+*/
+
+require_once('hosted/recaptchalib.php');
+
+class kolab_client_task_signup extends kolab_client_task
+{
+ protected $ajax_only = true;
+
+ /**
+ * Overwrite Main execution.
+ */
+ public function run()
+ {
+ // don't set any cookies
+ ini_set('session.use_cookies', '0');
+
+ // Initialize locales
+ $this->locale_init();
+
+ // Assign self to template variable
+ $this->output->assign('engine', $this);
+
+ // Run security checks
+ // TODO figure out to reenable this
+// $this->input_checks();
+
+ $action = $this->get_input('action', 'GET');
+
+ if ($action) {
+ $method = 'action_' . $action;
+ if (method_exists($this, $method)) {
+ $this->$method();
+ }
+ }
+ else if (method_exists($this, 'action_default')) {
+ $this->action_default();
+ }
+ }
+
+ private function login($domain=NULL)
+ {
+ if(is_null($domain)) {
+ $domain = $this->config_get('primary_domain');
+ }
+
+ // Login ($result is a kolab_client_api_result instance)
+ $result = $this->api->login($this->config_get('bind_dn'), $this->config_get('bind_pw'), $domain);
+
+ // Set the session token we got in the API client instance, so subsequent
+ // API calls are made in the same session.
+ $this->token = $result->get('session_token');
+ $this->api->set_session_token($this->token);
+ }
+
+ public function action_default()
+ {
+ $this->login();
+
+ $data = $this->get_input('data', 'POST');
+ $form = $this->user_form($data);
+
+ // add captcha
+ $publickey = $this->config_get('recaptcha_public_key');
+ // TODO find a less dirty way to add captcha into form
+ $form = preg_replace('/<div class="formbuttons">/', '<div id="recaptcha_div"></div><div class="formbuttons">', $form);
+
+ // load captcha
+ $form .= '
+ <script type="text/javascript">
+ Recaptcha.create("'.$publickey.'", "recaptcha_div", {theme: "red"});
+ </script>';
+
+ $this->output->assign('form', $form);
+ $this->output->set_object('taskcontent', $form);
+ }
+
+ // check if user already exists
+ public function action_check_user($data = array()) {
+ if(count($data) == 0) $data = $this->get_input('data', 'POST');
+
+ $this->login($data['domain']);
+
+ // Assemble mail attribute
+ $mail = $data['uid'].'@'.$data['domain'];
+
+ $post = array('search' => array('mail' => array('value' => $mail) ) );
+ $result = $this->api->post('users.list', null, $post);
+
+ if($result->get('count') > 0) {
+ // TODO make this message translatable
+ $this->output->command('update_user_info("User does already exist!", "uid")');
+ return false;
+ }
+
+ $this->output->command('update_user_info("", "uid")');
+ return true;
+ }
+
+ public function action_add_user() {
+ $data = $this->get_input('data', 'POST');
+
+ // Check for valid CAPTCHA
+ $resp = recaptcha_check_answer(
+ $this->config_get('recaptcha_private_key'),
+ $_SERVER['REMOTE_ADDR'],
+ $data['recaptcha_challenge_field'],
+ $data['recaptcha_response_field']
+ );
+
+ if (!$resp->is_valid) {
+ // What happens when the CAPTCHA was entered incorrectly
+ $this->output->command('display_message', "The reCAPTCHA wasn't entered correctly. Please reload and try it again.", 'error');
+ return;
+ }
+
+ // Check again for user availability before adding user
+ // this also logs into the API
+ // TODO perform security check on value of $data['uid'] and $data['domain']
+ if(!$this->action_check_user($data)) {
+ $this->output->command('form_value_error', 'uid');
+ return;
+ }
+
+ // Remove domain from $data before adding user
+ unset($data['domain']);
+
+ // Add user
+ $result = $this->api->post('user.add', null, $data);
+
+ if (array_key_exists('error_code', $result)) {
+ // TODO make this message translatable
+ $this->output->command('display_message', 'An Error occured. You could not be signed up. Please try again.', 'error');
+ return;
+ } else {
+ // TODO make this message translatable
+ $this->output->set_object('taskcontent', '<h3>Your account has been successfully added!</h3>Congratulations, you now have your own Kolab account.');
+ }
+ }
+
+ private function user_form($data = array()) {
+ $attribs['id'] = 'signup-form';
+
+ $fields_map = array(
+ 'type_id' => 'other',
+ 'givenname' => 'other',
+ 'sn' => 'other',
+ 'cn' => 'other',
+ 'mailalternateaddress' => 'other',
+ 'uid' => 'other',
+ 'domain' => 'other',
+ 'userpassword' => 'other',
+ 'userpassword2' => 'other',
+ 'mail' => 'other',
+ 'alias' => 'other',
+ );
+
+ // Prepare fields
+ list($fields, $types, $type) = $this->form_prepare('user', $data, array('userpassword2'));
+
+ // Show only required fields
+ foreach ($fields as $field_name => $field_attrs) {
+ if(!array_key_exists('required', $field_attrs) or $field_attrs['required'] != 'true') {
+ unset($fields[$field_name]);
+ }
+ }
+
+ // Add user type id selector
+ $accttypes = array();
+ foreach ($types as $idx => $elem) {
+ if($elem['used_for'] == 'hosted') {
+ $accttypes[$idx] = array('value' => $idx, 'content' => $elem['name']);
+ }
+ }
+
+ $fields['type_id'] = array(
+ 'section' => 'personal',
+ 'type' => kolab_form::INPUT_SELECT,
+ 'options' => $accttypes,
+ 'onchange' => "kadm.change_user_type()",
+ );
+
+ // Add object type field
+ $fields['object_type'] = array(
+ 'type' => kolab_form::INPUT_HIDDEN,
+ 'value' => 'user',
+ );
+
+ // Add available domains
+ $fields['domain'] = array(
+ 'type' => kolab_form::INPUT_SELECT,
+ 'options' => $this->get_domains(),
+ 'onchange' => 'kadm.check_user_availability()',
+ );
+
+ // Check for user availability
+ $fields['uid']['onchange'] = 'kadm.check_user_availability()';
+
+ // Hide cn field
+ if (isset($fields['cn'])) {
+ // TODO use type info from user types table
+ $fields['cn']['type'] = kolab_form::INPUT_HIDDEN;
+
+ // TODO auto generate value again with indirect API call
+ $fields['cn']['value'] = 'temporary fake cn';
+ $fields['sn']['onchange'] = '';
+ $fields['givenname']['onchange'] = '';
+ }
+
+ // Add password confirmation
+ if (isset($fields['userpassword'])) {
+ $fields['userpassword2'] = $fields['userpassword'];
+ $fields['userpassword']['onchange'] = 'password_match()';
+ $fields['userpassword2']['onchange'] = 'password_match()';
+ }
+
+ // Change field labels for hosted case
+ // TODO make translatable
+ $fields['uid']['label'] = "Username";
+ $fields['mail']['label'] = "Your Future Email Address";
+ if(isset($fields['mailalternateaddress'])) $fields['mailalternateaddress']['label'] = "Your Current Email Address";
+ $fields['domain']['label'] = "Domain";
+
+ // Create form object and populate with fields
+ $form = $this->form_create('user', $attribs, array('other'), $fields, $fields_map, $data, true);
+
+ $form->set_title(kolab_html::escape('Sign up'));
+
+ $this->output->add_translation('user.password.mismatch', 'user.add.success');
+
+ return $form->output();
+ }
+
+ private function get_domains() {
+ // Get a list of domains ($domains again is a kolab_client_api_result instance)
+ $domains_list = $this->api->get('domains.list')->get('list');
+
+ if (empty($domains_list)) {
+ return array();
+ }
+
+ // The domain name attribute (the name of the LDAP attribute that holds the actual domain name space)
+ // is configurable as well. Provide a fallback.
+ $domain_name_attribute = $this->config->get('ldap','domain_name_attribute');
+ if (empty($domain_name_attribute)) {
+ $domain_name_attribute = 'associateddomain';
+ }
+
+ // Placeholder for the domain names in this deployment
+ $domain_names = array();
+
+ foreach ($domains_list as $domain_dn => $domain_attrs) {
+ // If $domain_attrs[$domain_name_attribute] is an array, the primary domain name space
+ // is the first value in the array.
+ if (is_array($domain_attrs[$domain_name_attribute])) {
+ $_domain_names = $domain_attrs[$domain_name_attribute];
+ $domain_name = array_shift($domain_attrs[$domain_name_attribute]);
+ } else {
+ $_domain_names = (array)($domain_attrs[$domain_name_attribute]);
+ $domain_name = $domain_attrs[$domain_name_attribute];
+ }
+
+ $domain_names = array_merge($domain_names, $_domain_names);
+ }
+
+ // prepare array with proper key ids for form building
+ foreach ($domain_names as $domain) {
+ $domain_form_names[$domain] = $domain;
+ }
+
+ return $domain_form_names;
+ }
+
+ /**
+ * Overrides config_get() from kolab_client_task
+ * Returns configuration option value for hosting.
+ *
+ * @param string $name Option name
+ * @param mixed $fallback Default value
+ *
+ * @return mixed Option value
+ */
+ public function config_get($name, $fallback = null)
+ {
+ $value = $this->config->get('kolab_hosting', $name);
+ return $value !== null ? $value : $fallback;
+ }
+}
diff --git a/lib/hosted/recaptchalib.php b/lib/hosted/recaptchalib.php
new file mode 100644
index 0000000..32c4f4d
--- /dev/null
+++ b/lib/hosted/recaptchalib.php
@@ -0,0 +1,277 @@
+<?php
+/*
+ * This is a PHP library that handles calling reCAPTCHA.
+ * - Documentation and latest version
+ * http://recaptcha.net/plugins/php/
+ * - Get a reCAPTCHA API Key
+ * https://www.google.com/recaptcha/admin/create
+ * - Discussion group
+ * http://groups.google.com/group/recaptcha
+ *
+ * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
+ * AUTHORS:
+ * Mike Crawford
+ * Ben Maurer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * The reCAPTCHA server URL's
+ */
+define("RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api");
+define("RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api");
+define("RECAPTCHA_VERIFY_SERVER", "www.google.com");
+
+/**
+ * Encodes the given data into a query string format
+ * @param $data - array of string elements to be encoded
+ * @return string - encoded request
+ */
+function _recaptcha_qsencode ($data) {
+ $req = "";
+ foreach ( $data as $key => $value )
+ $req .= $key . '=' . urlencode( stripslashes($value) ) . '&';
+
+ // Cut the last '&'
+ $req=substr($req,0,strlen($req)-1);
+ return $req;
+}
+
+
+
+/**
+ * Submits an HTTP POST to a reCAPTCHA server
+ * @param string $host
+ * @param string $path
+ * @param array $data
+ * @param int port
+ * @return array response
+ */
+function _recaptcha_http_post($host, $path, $data, $port = 80) {
+
+ $req = _recaptcha_qsencode ($data);
+
+ $http_request = "POST $path HTTP/1.0\r\n";
+ $http_request .= "Host: $host\r\n";
+ $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
+ $http_request .= "Content-Length: " . strlen($req) . "\r\n";
+ $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
+ $http_request .= "\r\n";
+ $http_request .= $req;
+
+ $response = '';
+ if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
+ die ('Could not open socket');
+ }
+
+ fwrite($fs, $http_request);
+
+ while ( !feof($fs) )
+ $response .= fgets($fs, 1160); // One TCP-IP packet
+ fclose($fs);
+ $response = explode("\r\n\r\n", $response, 2);
+
+ return $response;
+}
+
+
+
+/**
+ * Gets the challenge HTML (javascript and non-javascript version).
+ * This is called from the browser, and the resulting reCAPTCHA HTML widget
+ * is embedded within the HTML form it was called from.
+ * @param string $pubkey A public key for reCAPTCHA
+ * @param string $error The error given by reCAPTCHA (optional, default is null)
+ * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false)
+
+ * @return string - The HTML to be embedded in the user's form.
+ */
+function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
+{
+ if ($pubkey == null || $pubkey == '') {
+ die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
+ }
+
+ if ($use_ssl) {
+ $server = RECAPTCHA_API_SECURE_SERVER;
+ } else {
+ $server = RECAPTCHA_API_SERVER;
+ }
+
+ $errorpart = "";
+ if ($error) {
+ $errorpart = "&amp;error=" . $error;
+ }
+ return '<script type="text/javascript" src="'. $server . '/challenge?k=' . $pubkey . $errorpart . '"></script>
+
+ <noscript>
+ <iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/>
+ <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
+ <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
+ </noscript>';
+}
+
+
+
+
+/**
+ * A ReCaptchaResponse is returned from recaptcha_check_answer()
+ */
+class ReCaptchaResponse {
+ var $is_valid;
+ var $error;
+}
+
+
+/**
+ * Calls an HTTP POST function to verify if the user's guess was correct
+ * @param string $privkey
+ * @param string $remoteip
+ * @param string $challenge
+ * @param string $response
+ * @param array $extra_params an array of extra variables to post to the server
+ * @return ReCaptchaResponse
+ */
+function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array())
+{
+ if ($privkey == null || $privkey == '') {
+ die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
+ }
+
+ if ($remoteip == null || $remoteip == '') {
+ die ("For security reasons, you must pass the remote ip to reCAPTCHA");
+ }
+
+
+
+ //discard spam submissions
+ if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) {
+ $recaptcha_response = new ReCaptchaResponse();
+ $recaptcha_response->is_valid = false;
+ $recaptcha_response->error = 'incorrect-captcha-sol';
+ return $recaptcha_response;
+ }
+
+ $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify",
+ array (
+ 'privatekey' => $privkey,
+ 'remoteip' => $remoteip,
+ 'challenge' => $challenge,
+ 'response' => $response
+ ) + $extra_params
+ );
+
+ $answers = explode ("\n", $response [1]);
+ $recaptcha_response = new ReCaptchaResponse();
+
+ if (trim ($answers [0]) == 'true') {
+ $recaptcha_response->is_valid = true;
+ }
+ else {
+ $recaptcha_response->is_valid = false;
+ $recaptcha_response->error = $answers [1];
+ }
+ return $recaptcha_response;
+
+}
+
+/**
+ * gets a URL where the user can sign up for reCAPTCHA. If your application
+ * has a configuration page where you enter a key, you should provide a link
+ * using this function.
+ * @param string $domain The domain where the page is hosted
+ * @param string $appname The name of your application
+ */
+function recaptcha_get_signup_url ($domain = null, $appname = null) {
+ return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname));
+}
+
+function _recaptcha_aes_pad($val) {
+ $block_size = 16;
+ $numpad = $block_size - (strlen ($val) % $block_size);
+ return str_pad($val, strlen ($val) + $numpad, chr($numpad));
+}
+
+/* Mailhide related code */
+
+function _recaptcha_aes_encrypt($val,$ky) {
+ if (! function_exists ("mcrypt_encrypt")) {
+ die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed.");
+ }
+ $mode=MCRYPT_MODE_CBC;
+ $enc=MCRYPT_RIJNDAEL_128;
+ $val=_recaptcha_aes_pad($val);
+ return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
+}
+
+
+function _recaptcha_mailhide_urlbase64 ($x) {
+ return strtr(base64_encode ($x), '+/', '-_');
+}
+
+/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */
+function recaptcha_mailhide_url($pubkey, $privkey, $email) {
+ if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) {
+ die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .
+ "you can do so at <a href='http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>");
+ }
+
+
+ $ky = pack('H*', $privkey);
+ $cryptmail = _recaptcha_aes_encrypt ($email, $ky);
+
+ return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail);
+}
+
+/**
+ * gets the parts of the email to expose to the user.
+ * eg, given johndoe@example,com return ["john", "example.com"].
+ * the email is then displayed as john...@example.com
+ */
+function _recaptcha_mailhide_email_parts ($email) {
+ $arr = preg_split("/@/", $email );
+
+ if (strlen ($arr[0]) <= 4) {
+ $arr[0] = substr ($arr[0], 0, 1);
+ } else if (strlen ($arr[0]) <= 6) {
+ $arr[0] = substr ($arr[0], 0, 3);
+ } else {
+ $arr[0] = substr ($arr[0], 0, 4);
+ }
+ return $arr;
+}
+
+/**
+ * Gets html to display an email address given a public an private key.
+ * to get a key, go to:
+ *
+ * http://www.google.com/recaptcha/mailhide/apikey
+ */
+function recaptcha_mailhide_html($pubkey, $privkey, $email) {
+ $emailparts = _recaptcha_mailhide_email_parts ($email);
+ $url = recaptcha_mailhide_url ($pubkey, $privkey, $email);
+
+ return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) .
+ "' onclick=\"window.open('" . htmlentities ($url) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ($emailparts [1]);
+
+}
+
+
+?>
diff --git a/lib/kolab_client_api.php b/lib/kolab_client_api.php
index dd70677..cf2f946 100644
--- a/lib/kolab_client_api.php
+++ b/lib/kolab_client_api.php
@@ -225,6 +225,7 @@ class kolab_client_api
return new kolab_client_api_result(null,
self::ERROR_INTERNAL, $e->getMessage());
}
+ //console($body);
$body = @json_decode($body, true);
$err_code = null;
diff --git a/lib/kolab_client_task.php b/lib/kolab_client_task.php
index e93aa40..b41d75b 100644
--- a/lib/kolab_client_task.php
+++ b/lib/kolab_client_task.php
@@ -67,7 +67,7 @@ class kolab_client_task
/**
* Localization initialization.
*/
- private function locale_init()
+ protected function locale_init()
{
$language = $this->get_language();
$LANG = array();
@@ -521,31 +521,6 @@ class kolab_client_task
}
/**
- * Returns list of resource types.
- *
- * @return array List of resource types
- */
- protected function resource_types()
- {
-
- if (isset($_SESSION['resource_types'])) {
- return $_SESSION['resource_types'];
- }
-
-
- $result = $this->api->post('resource_types.list');
- $list = $result->get('list');
-
-
- if (is_array($list) && !$this->config_get('devel_mode')) {
- $_SESSION['resource_types'] = $list;
- }
-
- return $list;
- }
-
-
- /**
* Returns list of user types.
*
* @return array List of user types
@@ -756,11 +731,22 @@ class kolab_client_task
if (!empty($field['maxlength'])) {
$result['data-maxlength'] = $field['maxlength'];
}
+ if (!empty($field['maxcount'])) {
+ $result['data-maxcount'] = $field['maxcount'];
+ }
if (!empty($field['autocomplete'])) {
$result['data-autocomplete'] = true;
}
break;
+ case 'password':
+ $result['type'] = kolab_form::INPUT_PASSWORD;
+
+ if (isset($field['maxlength'])) {
+ $result['maxlength'] = $field['maxlength'];
+ }
+ break;
+
default:
$result['type'] = kolab_form::INPUT_TEXT;
if (isset($field['maxlength'])) {
@@ -1231,7 +1217,7 @@ class kolab_client_task
$this->output->set_env('form_id', $attribs['id']);
$this->output->set_env('assoc_fields', $assoc_fields);
$this->output->set_env('required_fields', $req_fields);
- $this->output->add_translation('form.required.empty');
+ $this->output->add_translation('form.required.empty', 'form.maxcount.exceeded');
return $form;
}
diff --git a/lib/locale/en_US.php b/lib/locale/en_US.php
index 6b3e78a..389e303 100644
--- a/lib/locale/en_US.php
+++ b/lib/locale/en_US.php
@@ -25,6 +25,7 @@ $LANG['domain.type_id'] = 'Standard Domain';
$LANG['error'] = 'Error';
$LANG['form.required.empty'] = 'Some of the required fields are empty!';
+$LANG['form.maxcount.exceeded'] = 'Maximum count of items exceeded!';
$LANG['group.add'] = 'Add Group';
$LANG['group.add.success'] = 'Group created successfully.';