Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2527806
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
28 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/composer.json b/composer.json
index 910564b..74048b4 100644
--- a/composer.json
+++ b/composer.json
@@ -1,27 +1,27 @@
{
"name": "kolab/free-busy",
"description": "Kolab Free/Busy Service",
"license": "AGPL-3.0",
- "version": "0.1.1",
+ "version": "0.1.2",
"repositories": [
{
"type": "pear",
"url": "http://pear.php.net/"
},
{
"type": "vcs",
"url": "git://git.kolab.org/git/pear/Net_LDAP3"
}
],
"autoload": {
"psr-0": { "": "lib/" }
},
"require": {
"php": ">=5.3.3",
"monolog/monolog": "1.2.*",
"kolab/Net_LDAP3": "dev-master",
"desarrolla2/cache": "dev-master",
"sabre/vobject" : "2.0.*"
},
"minimum-stability": "dev"
}
\ No newline at end of file
diff --git a/config/config.ini.sample b/config/config.ini.sample
index 62437d3..778f15a 100644
--- a/config/config.ini.sample
+++ b/config/config.ini.sample
@@ -1,61 +1,61 @@
;; Kolab Free/Busy Service configuration
;; Require HTTP authentication to access this service
[httpauth]
;; Example for static auth credentials
; type = static
; username = "<user>"
; password = "<pass>"
;; Example for LDAP-based authentication
; type = ldap
; host = ldap://localhost:389
; bind_dn = "uid=kolab-service,ou=Special Users,dc=yourdomain,dc=com"
; bind_pw = "<service-bind-pw>"
; base_dn = "dc=yourdomain,dc=com"
; filter = "(&(|(mail=%s)(alias=%s)(uid=%s))(objectclass=inetorgperson))" ; optional, %s is replaced by the username
;; Allow privileged access from these IPs
[trustednetworks]
-allow[] = 127.0.0.1
-allow[] = 192.168.0.0/16
-allow[] = 10.10.*
-allow[] = ::1
+allow = 127.0.0.1,
+ 192.168.0.0/16,
+ 10.10.*,
+ ::1
;; Logging configuration
[log]
driver = file ; supported drivers: file, syslog
path = ./log
name = freebusy
level = 300 ; (100 = Debug, 200 = Info, 300 = Warn, 400 = Error, 500 = Critical)
;; Directories to resolve email addresses and their f/b source locations
;; try local filesystem first
[directory "local"]
type = static
filter = "@yourdomain"
fbsource = file:/var/lib/kolab-freebusy/%s.ifb
;; local Kolab directory server
[directory "kolab-ldap"]
type = ldap
host = ldap://localhost:389
bind_dn = "uid=kolab-service,ou=Special Users,dc=yourdomain,dc=com"
bind_pw = "<service-bind-pw>"
base_dn = "dc=yourdomain,dc=com"
filter = "(&(objectClass=kolabInetOrgPerson)(|(uid=%s)(mail=%s)(alias=%s)))"
-attributes[] = mail
-lc_attributes[] = mail
+attributes = mail, sn
+lc_attributes = sn
fbsource = file:/www/kolab-freebusy/data/%mail.ifb
loglevel = 100 ; Debug
;; external MS Exchange 2010 server
[directory "exchange"]
type = static
filter = "@microsoft.com$"
fbsource = https://externalhost/free-busy/%s.ics
format = Exchange2010
diff --git a/lib/Kolab/Config.php b/lib/Kolab/Config.php
new file mode 100644
index 0000000..30cebbf
--- /dev/null
+++ b/lib/Kolab/Config.php
@@ -0,0 +1,284 @@
+<?php
+
+/**
+ * Model class to give access to service configuration
+ *
+ * This file is part of the Kolab PHP Utilities library
+ *
+ * @author Thomas Bruederli <bruederli@kolabsys.com>
+ *
+ * Copyright (C) 2013, 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/>.
+ */
+
+namespace Kolab;
+
+/**
+ * Wrapper class for service configuration
+ */
+class Config
+{
+ const STRING = 0;
+ const BOOL = 1;
+ const INT = 2;
+ const FLOAT = 3;
+ const ARR = 4;
+
+ protected static $instance;
+
+ protected $env = '';
+ protected $basedir = '../config';
+ protected $data = array();
+ protected $valid = false;
+
+ /**
+ * Singelton getter
+ *
+ * @param string Path to load config from
+ */
+ public static function get_instance($env = '', $dir = null)
+ {
+ if (!isset(self::$instance)) {
+ self::$instance = new Config($env);
+ if ($dir) self::$instance->basedir = $dif;
+ }
+
+ if (!self::$instance->valid) {
+ self::$instance->load('config.ini');
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * Default constructor
+ */
+ function __construct($env = '')
+ {
+ $this->env = $env;
+ $this->load($this->basedir . '/config.ini');
+ }
+
+ /**
+ * Load config from the given .ini file
+ */
+ private function load($file, $use_env = true)
+ {
+ // check for relative path
+ if (!is_readable($inifile) && is_readable($this->basedir . '/' . $inifile)) {
+ $inifile = $this->basedir . '/' . $inifile;
+ }
+
+ $inifile = $this->resolve_path($file, $use_env);
+ if ($raw = self::parse_ini_file($inifile, true)) {
+ foreach ($raw as $section => $values) {
+ $sub = null;
+ if (preg_match('/^(\w+)\s+"?(.+)"?$/Ui', $section, $m)) {
+ $section = $m[1];
+ $sub = trim($m[2], '"');
+ }
+ if (!empty($sub) && !empty($values)) {
+ $config[$section][$sub] = $values;
+ }
+ else if (!empty($values) && is_array($values)) {
+ $config[$section] = $values;
+ }
+ }
+
+ $this->register($config);
+ $this->valid = !empty($this->data);
+ }
+ else {
+ trigger_error("Failed to parse configuration from $inifile", E_USER_ERROR);
+ }
+ }
+
+ /**
+ * Helper method to resolve the absolute path to the given config file.
+ * This also takes the 'env' property into account.
+ */
+ private function resolve_path($file, $use_env)
+ {
+ if ($file[0] != '/') {
+ $file = realpath($this->basedir . '/' . $file);
+ }
+
+ // check if <file>-env.ini exists
+ if ($file && $use_env && !empty($this->env)) {
+ $envfile = preg_replace('/\.(ini|conf)$/', '-' . $this->env . '.\\1', $file);
+ if (is_file($envfile))
+ return $envfile;
+ }
+
+ return $file;
+ }
+
+ /**
+ * Replacement for PHP's parse_ini_file()
+ */
+ private static function parse_ini_file($filename)
+ {
+ $raw = array();
+ foreach (file($filename) as $_line) {
+ if ($_line[0] == ';') // skip comments
+ continue;
+
+ if (preg_match('/^\[([a-z0-9-_\.]+[^\]]*)\]/', $_line, $matches)) {
+ $_cur_section = $matches[1];
+ $raw[$_cur_section] = array();
+ unset($_cur_key);
+ }
+
+ if (preg_match('/^([a-z0-9\.-_]+)\s*=\s*(.*)/', $_line, $matches)) {
+ if (isset($_cur_section) && !empty($_cur_section)) {
+ $_cur_key = $matches[1];
+ $raw[$_cur_section][$matches[1]] = isset($matches[2]) ? trim($matches[2], ' "') : '';
+ }
+ }
+ else if (preg_match('/^\s+(.*)$/', $_line, $matches)) {
+ if (isset($_cur_key) && !empty($_cur_key)) {
+ $raw[$_cur_section][$_cur_key] .= $matches[1];
+ }
+ }
+ }
+
+ return $raw;
+ }
+
+ /**
+ * Dump the hierarchical structure of config options into a flat list with keys delimited by dots
+ */
+ private function register($config, $prefix = '')
+ {
+ // merge the new config values over existing data
+ if (empty($prefix)) {
+ $this->data = array_replace_recursive($this->data, $config);
+ }
+ else if (is_array($config)) {
+ $pkey = rtrim($prefix, '.');
+ $this->data[$pkey] = is_array($this->data[$pkey]) ? array_replace_recursive((array)$this->data[$pkey], $config) : $config;
+ }
+
+ foreach ((array)$config as $key => $val) {
+ if (is_array($val)) {
+ $this->register($val, "$prefix$key.");
+ }
+ else {
+ $this->data[$prefix.$key] = $val;
+ }
+ }
+
+ // resolve references in config options (e.g. %(foo.bar))
+ if (empty($prefix)) {
+ array_walk_recursive($this->data, array($this, 'resolve_reference'));
+ }
+ }
+
+ /**
+ * Callback to resolve references in the given config option value
+ */
+ private function resolve_reference(&$value, $key)
+ {
+ if (is_string($value)) {
+ $value = preg_replace_callback('/%[({]([\w.]+)[})]/i', array($this, 'replace_reference'), $value);
+ }
+ }
+
+ /**
+ * Callback function to replace the given reference with the read config value
+ */
+ private function replace_reference($m)
+ {
+ return $this->data[$m[1]];
+ }
+
+ /**
+ * Magic getter for direct read-only access to config options
+ */
+ public function __get($name)
+ {
+ return $this->data[$name];
+ }
+
+ /**
+ * Magic isset check
+ */
+ public function __isset($name)
+ {
+ return array_key_exists($name, $this->data);
+ }
+
+ /**
+ * Common getter for config options with fallback to default values
+ *
+ * @param string Config option name
+ * @param mixed Default value if option isn't set in config
+ * @param integer Expected variable type
+ * @return mixed Config option value
+ */
+ public function get($name, $default = null, $type = null)
+ {
+ switch ($name) {
+ case 'output.tempdir':
+ case 'session.savepath':
+ // return an absolute path for relative directory properties
+ if (isset($this->data[$name]) && $this->data[$name][0] != '/') {
+ $value = realpath(INSTALL_PATH . '/' . $this->data[$name]);
+ break;
+ }
+
+ default:
+ $value = array_key_exists($name, $this->data) ? $this->data[$name] : $default;
+ }
+
+ // convert value to the requested type
+ return $type ? self::convert($value, $type) : value;
+ }
+
+ /**
+ * Determines whether we have a valid configuration loaded
+ *
+ * @return boolean True if valid, False otherwise
+ */
+ public function valid()
+ {
+ return !empty($this->data);
+ }
+
+ /**
+ * Convert the given (string) value to the requested type
+ *
+ * @param string Config value
+ * @param int Output type (one of this class constants)
+ * @return mixed The converted value
+ */
+ public static function convert($value, $type)
+ {
+ // convert value to the requested type
+ switch ($type) {
+ case self::INT:
+ return intval($value);
+ case self::FLOAT:
+ return floatval($value);
+ case self::BOOL:
+ return (bool)preg_match('/^(true|1|on|enabled|yes)$/i', $value);
+ case self::ARR:
+ return preg_split('/,\s*/', strval($value));
+ }
+
+ return $value;
+ }
+}
+
diff --git a/lib/Kolab/FreeBusy/Config.php b/lib/Kolab/FreeBusy/Config.php
deleted file mode 100644
index ab82a1a..0000000
--- a/lib/Kolab/FreeBusy/Config.php
+++ /dev/null
@@ -1,173 +0,0 @@
-<?php
-
-/**
- * This file is part of the Kolab Server Free/Busy Service
- *
- * @author Thomas Bruederli <bruederli@kolabsys.com>
- *
- * Copyright (C) 2013, 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/>.
- */
-
-namespace Kolab\FreeBusy;
-
-/**
- * Wrapper class for service configuration
- */
-class Config
-{
- private static $instance;
-
- private $basedir = '.';
- private $data = array();
- private $valid = false;
-
- /**
- * Singelton getter
- *
- * @param string Path to load config from
- */
- public static function getInstance($dir = null)
- {
- if (!isset(self::$instance)) {
- self::$instance = new Config($dir);
- }
-
- if ($dir && !self::$instance->valid) {
- self::$instance->load($configdir . '/config.ini');
- }
-
- return self::$instance;
- }
-
- /**
- * Default constructor
- */
- function __construct($configdir = null)
- {
- if ($configdir) {
- $this->basedir = $configdir;
- $this->load($configdir . '/config.ini');
- }
- }
-
- /**
- * Load config from the given .ini file
- */
- private function load($inifile)
- {
- if ($raw = parse_ini_file($inifile, true)) {
- $config['directories'] = array();
- foreach ($raw as $section => $values) {
- // check for known sections
- if (in_array($section, array('httpauth','trustednetworks','log'))) {
- $config[$section] = $values;
- }
- else if (strpos($section, 'directory') === 0 || isset($values['fbsource'])) {
- $sect = preg_replace('/^directory\s*/', '', $section);
- $key = strlen($sect) ? $sect : count($config['directories']);
- $config['directories'][$key] = $values;
- }
- else if (!empty($values) && is_array($values)) {
- $config[$section] = $values;
- }
- }
-
- $this->register($config);
- $this->valid = !empty($this->data['directories']);
- }
- else {
- trigger_error("Failed to parse configuration from $inifile", E_USER_ERROR);
- }
- }
-
- /**
- * Dump the hierarchical structure of config options into a flat list with keys delimited by dots
- */
- private function register($config, $prefix = '')
- {
- // merge the new config values over existing data
- if (empty($prefix)) {
- $this->data = array_replace_recursive($this->data, $config);
- }
- else if (is_array($config)) {
- $pkey = rtrim($prefix, '.');
- $this->data[$pkey] = is_array($this->data[$pkey]) ? array_replace_recursive((array)$this->data[$pkey], $config) : $config;
- }
-
- foreach ((array)$config as $key => $val) {
- if (is_array($val)) {
- $this->register($val, "$prefix$key.");
- }
- else {
- $this->data[$prefix.$key] = $val;
- }
- }
-
- // resolve references in config options (e.g. %(foo.bar))
- if (empty($prefix)) {
- array_walk_recursive($this->data, array($this, 'resolve_reference'));
- }
- }
-
- /**
- * Callback to resolve references in the given config option value
- */
- private function resolve_reference(&$value, $key)
- {
- if (is_string($value)) {
- $value = preg_replace_callback('/%[({]([\w.]+)[})]/i', array($this, 'replace_reference'), $value);
- }
- }
-
- /**
- * Callback function to replace the given reference with the read config value
- */
- private function replace_reference($m)
- {
- return $this->data[$m[1]];
- }
-
- /**
- * Magic getter for direct read-only access to config options
- */
- public function __get($name)
- {
- return $this->data[$name];
- }
-
- /**
- * Common getter for config options with fallback in default values
- *
- * @param string Config option name
- * @param mixed Default value if option isn't set in config
- * @return mixed Config option value
- */
- public function get($name, $default = null)
- {
- return array_key_exists($name, $this->data) ? $this->data[$name] : $default;
- }
-
- /**
- * Determines whether we have a valid configuration loaded
- *
- * @return boolean True if valid, False otherwise
- */
- public function isValid()
- {
- return !empty($this->data);
- }
-}
-
diff --git a/lib/Kolab/FreeBusy/Directory.php b/lib/Kolab/FreeBusy/Directory.php
index 1c70f75..6478e85 100644
--- a/lib/Kolab/FreeBusy/Directory.php
+++ b/lib/Kolab/FreeBusy/Directory.php
@@ -1,105 +1,105 @@
<?php
/**
* This file is part of the Kolab Server Free/Busy Service
*
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2013, 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/>.
*/
namespace Kolab\FreeBusy;
/**
* Abstract class representing an address directory for free/busy data lookups
*/
abstract class Directory
{
protected $config;
/**
* Factory method creating an instace of Directory according to config
*
* @param array Hash array with config
*/
public static function factory($config)
{
switch (strtolower($config['type'])) {
case 'ldap':
return new DirectoryLDAP($config);
case 'static':
case 'external':
return new DirectoryStatic($config);
default:
Logger::get('directory')->addError("Invalid directory type '" . $config['type'] . "'!");
}
return null;
}
/**
* Resolve the given username to a Entity object
*
* @param string Username/Email to resolve
* @return object Entity if found, otherwise False
*/
abstract public function resolve($user);
/**
* Retrieve free/busy data for the given user.
*
* @param string Username or email to resolve
* @param boolean Get extemded free-busy if possible
* @return string VCalendar container if found, False otherwise
*/
public function getFreeBusyData($user, $extended = false)
{
// resolve user record first
if ($user = $this->resolve($user)) {
$fbsource = $this->config['fbsource'];
if ($source = Source::Factory($fbsource)) {
// forward request to Source instance
if ($data = $source->getFreeBusyData($this->postprocessAttrib($user), $extended)) {
// send data through the according format converter
$converter = Format::factory($this->config['format']);
$data = $converter->toVCalendar($data);
}
return $data;
}
}
return false;
}
/**
* Modify attribute values according to config
*/
protected function postprocessAttrib($attrib)
{
if (!empty($this->config['lc_attributes'])) {
- foreach ((array)$this->config['lc_attributes'] as $key) {
+ foreach (Config::convert($this->config['lc_attributes'], Config::ARR) as $key) {
if (!empty($attrib[$key]))
$attrib[$key] = strtolower($attrib[$key]);
}
}
return $attrib;
}
}
\ No newline at end of file
diff --git a/lib/Kolab/FreeBusy/DirectoryLDAP.php b/lib/Kolab/FreeBusy/DirectoryLDAP.php
index 5e31e24..f462f79 100644
--- a/lib/Kolab/FreeBusy/DirectoryLDAP.php
+++ b/lib/Kolab/FreeBusy/DirectoryLDAP.php
@@ -1,129 +1,129 @@
<?php
/**
* This file is part of the Kolab Server Free/Busy Service
*
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2013, 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/>.
*/
namespace Kolab\FreeBusy;
// PEAR modules operate in global namespace
use \Net_LDAP3;
use \Monolog\Logger as Monolog;
/**
* Implementation of an address lookup using an LDAP directory
*/
class DirectoryLDAP extends Directory
{
private $ldap;
private $logger;
private $ready = false;
/**
* Default constructor loading directory configuration
*/
public function __construct($config)
{
$this->config = $config;
$host = parse_url($config['host']);
$ldap_config = array(
'hosts' => array($host['host']),
'port' => $host['port'] ?: 389,
'use_tls' => $host['scheme'] == 'tls' || $host['scheme'] == 'ldaps',
'root_dn' => $config['base_dn'],
- 'return_attributes' => (array)$config['attributes'],
+ 'return_attributes' => Config::convert($config['attributes'], Config::ARR),
'log_hook' => array($this, 'log'),
) + $config;
// instantiate Net_LDAP3 and connect with logger
$this->logger = Logger::get('ldap', intval($config['loglevel']));
$this->ldap = new Net_LDAP3($ldap_config);
// connect + bind to LDAP server
if ($this->ldap->connect()) {
$this->ready = $this->ldap->bind($config['bind_dn'], $config['bind_pw']);
}
if ($this->ready) {
$this->logger->addInfo("Connected to $config[host] with '$config[bind_dn]'");
}
else {
$this->logger->addWarning("Connectiion to $config[host] with '$config[bind_dn]' failed!");
}
}
/**
* Callback for Net_LDAP3 logging
*/
public function log($level, $msg)
{
// map PHP log levels to Monolog levels
static $loglevels = array(
LOG_DEBUG => Monolog::DEBUG,
LOG_NOTICE => Monolog::NOTICE,
LOG_INFO => Monolog::INFO,
LOG_WARNING => Monolog::WARNING,
LOG_ERR => Monolog::ERROR,
LOG_CRIT => Monolog::CRITICAL,
LOG_ALERT => Monolog::ALERT,
LOG_EMERG => Monolog::EMERGENCY,
);
$msg = is_array($msg) ? join('; ', $msg) : strval($msg);
$this->logger->addRecord($loglevels[$level], $msg);
}
/**
* @see Directory::resolve()
*/
public function resolve($user)
{
$result = array('s' => $user);
if ($this->ready) {
// search with configured filter
$filter = preg_replace('/%s/i', $user, $this->config['filter']);
$ldapresult = $this->ldap->search($this->config['base_dn'], $filter, 'sub');
// got a valid result
if ($ldapresult && $ldapresult->count()) {
$ldapresult->rewind();
$entry = Net_LDAP3::normalize_entry($ldapresult->current()); // get the first entry
$this->logger->addInfo("Found " . $ldapresult->count() . " entries for $filter", $entry);
// convert entry attributes to strings and add them to the final result hash array
foreach ($entry as $k => $v) {
if (!empty($v)) {
$result[$k] = strval(is_array($v) ? $v[0] : $v);
}
}
return $result;
}
$this->logger->addInfo("No entry found for $filter");
}
return false;
}
}
diff --git a/web/index.php b/web/index.php
index 93a998a..fcbce69 100644
--- a/web/index.php
+++ b/web/index.php
@@ -1,137 +1,137 @@
<?php
/**
* Kolab Server Free/Busy Service Endpoint
*
* This is the public API to provide Free/Busy information for Kolab users.
*
- * @version 0.1.1
+ * @version 0.1.2
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2013, 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/>.
*/
define('KOLAB_FREEBUSY_ROOT', realpath('../'));
// suppress error notices
ini_set('error_reporting', E_ALL &~ E_NOTICE);
// use composer's autoloader for both dependencies and local lib
require_once KOLAB_FREEBUSY_ROOT . '/vendor/autoload.php';
+use Kolab\Config;
use Kolab\FreeBusy\Utils;
-use Kolab\FreeBusy\Config;
use Kolab\FreeBusy\Logger;
use Kolab\FreeBusy\Directory;
use Kolab\FreeBusy\HTTPAuth;
// load config
-$config = Config::getInstance(KOLAB_FREEBUSY_ROOT . '/config');
-if ($config->isValid()) {
+$config = Config::get_instance(KOLAB_FREEBUSY_ROOT . '/config');
+if ($config->valid()) {
// check for trusted IP first
$remote_ip = Utils::remoteIP();
- $trusted_ip = $config->trustednetworks ? Utils::checkIPRange($remote_ip, $config->trustednetworks['allow']) : false;
+ $trusted_ip = $config->trustednetworks ? Utils::checkIPRange($remote_ip, $config->get('trustednetworks.allow', array(), Config::ARR)) : false;
$log = Logger::get('web');
$uri = $_SERVER['REDIRECT_URL'];
// we're not always redirected here
if (empty($uri)) {
$uri = $_SERVER['REQUEST_URI'];
$log->addDebug('Request (direct): ' . $uri, array('ip' => $remote_ip, 'trusted' => $trusted_ip));
} else {
$log->addDebug('Request (redirect): ' . $uri, array('ip' => $remote_ip, 'trusted' => $trusted_ip));
}
// check HTTP authentication
if (!$trusted_ip && $config->httpauth) {
if (!HTTPAuth::check($config->httpauth)) {
$log->addDebug("Abort with 401 Unauthorized");
header('WWW-Authenticate: Basic realm="Kolab Free/Busy Service"');
header($_SERVER['SERVER_PROTOCOL'] . " 401 Unauthorized", true);
exit;
}
}
#header('Content-type: text/calendar; charset=utf-8', true);
header('Content-type: text/plain; charset=utf-8', true);
// analyse request
$url = array_filter(explode('/', $uri));
$user = strtolower(array_pop($url));
$action = strtolower(array_pop($url));
$extended = false;
// remove file extension
if (preg_match('/^(.+)\.([ipx]fb)$/i', $user, $m)) {
$user = $m[1];
$extended = $m[2] == 'xfb';
}
// iterate over directories
- foreach ($config->directories as $key => $dirconfig) {
+ foreach ($config->directory as $key => $dirconfig) {
$log->addDebug("Trying directory $key", $dirconfig);
$directory = Directory::factory($dirconfig);
if ($directory && ($fbdata = $directory->getFreeBusyData($user, $extended))) {
$log->addInfo("Found valid data for user $user in directory $key");
echo $fbdata;
exit;
}
}
// return 404 if request was sent from a trusted IP
if ($trusted_ip) {
$log->addDebug("Returning '404 Not Found' for user $user");
header($_SERVER['SERVER_PROTOCOL'] . " 404 Not found", true);
}
else {
$log->addInfo("Returning empty Free/Busy list for user $user");
$now = time();
$dtformat = 'Ymd\THis\Z';
// NOTE: The following settings should probably correspond with
// whatever period of time kolab-freebusyd thinks it should use.
// Should probably be a setting. For now, do 8 weeks in the past
$start = $now - (60 * 60 * 24 * 7 * 8);
// Should probably be a setting. For now, do 16 weeks into the future
$end = $now + (60 * 60 * 24 * 7 * 16);
// Return an apparent empty Free/Busy list.
print "BEGIN:VCALENDAR\n";
print "VERSION:2.0\n";
print "PRODID:-//kolab.org//NONSGML Kolab Server 3//EN\n";
print "METHOD:PUBLISH\n";
print "BEGIN:VFREEBUSY\n";
print "ORGANIZER:MAILTO:" . $user . ".ifb\n";
print "DTSTAMP:" . gmdate($dtformat) . "\n";
print "DTSTART:" . gmdate($dtformat, $start) . "\n";
print "DTEND:" . gmdate($dtformat, $end) . "\n";
print "COMMENT:This is a dummy vfreebusy that indicates an empty calendar\n";
print "FREEBUSY:19700101T000000Z/19700101T000000Z\n";
print "END:VFREEBUSY\n";
print "END:VCALENDAR\n";
}
}
// exit with error
# header($_SERVER['SERVER_PROTOCOL'] . " 500 Internal Server Error", true);
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Jan 31, 2:13 PM (20 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
426327
Default Alt Text
(28 KB)
Attached To
Mode
R28 freebusy
Attached
Detach File
Event Timeline
Log In to Comment