Line endings

This commit is contained in:
2016-12-16 14:51:48 +01:00
parent 41ea9199a0
commit 275913dea8
21 changed files with 3655 additions and 3648 deletions

View File

@@ -1,14 +1,14 @@
Backend setup:
1. Create a Admin User in Zarafa:
zarafa-admin -c adminuser -e admin@domain.com -f "Calendar Sync Admin" -p topsecretpw -a 1
2. Edit the config.php to fit your needs.
3. Setup cron to run your script every 10 minutes (or whatever...)
4. If you get an error, make sure that the mapi module is loaded for php-cli:
* Add: /etc/php5/cli/conf.d/50-mapi.ini
* Content: extension=mapi.so
Backend setup:
1. Create a Admin User in Zarafa:
zarafa-admin -c adminuser -e admin@domain.com -f "Calendar Sync Admin" -p topsecretpw -a 1
2. Edit the config.php to fit your needs.
3. Setup cron to run your script every 10 minutes (or whatever...)
4. If you get an error, make sure that the mapi module is loaded for php-cli:
* Add: /etc/php5/cli/conf.d/50-mapi.ini
* Content: extension=mapi.so
Never run the backend script as root!

View File

@@ -1 +1,8 @@
<?php
<?php
// config options
$ADMINUSERNAME = "admin";
$ADMINPASSWORD = "admin";
$SERVER = "file:///var/run/zarafa";
$CALDAVURL = "http://localhost:8080/ical/";
$TEMPDIR = "/tmp/";
?>

View File

@@ -1,165 +1,165 @@
<?php
/**
* functions.php, zarafa calender to ics im/exporter backend
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* gets the data from a URL */
function curl_get_data($url, $username = NULL, $password = NULL) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
if($username != NULL && $password != NULL) {
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
}
$data = curl_exec($ch);
$http_status = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
curl_close($ch);
if($http_status > 210 || $http_status < 200)
return NULL;
return $data;
}
/* gets all zarafa users */
function get_user_ics_list($userStore) {
// get settings
// first check if property exist and we can open that using mapi_openproperty
$storeProps = mapi_getprops($userStore, array(PR_EC_WEBACCESS_SETTINGS_JSON));
// Check if property exists, if it doesn not exist then we can continue with empty set of settings
if (isset($storeProps[PR_EC_WEBACCESS_SETTINGS_JSON]) || propIsError(PR_EC_WEBACCESS_SETTINGS_JSON, $storeProps) == MAPI_E_NOT_ENOUGH_MEMORY) {
// read the settings property
$stream = mapi_openproperty($userStore, PR_EC_WEBACCESS_SETTINGS_JSON, IID_IStream, 0, 0);
if ($stream == false) {
echo "Error opening settings property\n";
}
$settings_string = "";
$stat = mapi_stream_stat($stream);
mapi_stream_seek($stream, 0, STREAM_SEEK_SET);
for ($i = 0; $i < $stat['cb']; $i += 1024) {
$settings_string .= mapi_stream_read($stream, 1024);
}
if(empty($settings_string)) {
// property exists but without any content so ignore it and continue with
// empty set of settings
return;
}
$settings = json_decode($settings_string, true);
if (empty($settings) || empty($settings['settings'])) {
echo "Error retrieving existing settings\n";
}
$calcontext = $settings["settings"]["zarafa"]["v1"]["contexts"]["calendar"];
if(isset($calcontext["icssync"])) {
foreach($calcontext["icssync"] as $syncitem) {
echo "Found sync url: " . $syncitem["icsurl"] . " for calendar: " . $syncitem["calendar"] . "\n";
}
return $calcontext["icssync"];
}
return NULL;
}
}
/* updates the webapp settings */
function update_last_sync_date($userStore, $icsentry) {
// get settings
// first check if property exist and we can open that using mapi_openproperty
$storeProps = mapi_getprops($userStore, array(PR_EC_WEBACCESS_SETTINGS_JSON));
// Check if property exists, if it doesn not exist then we can continue with empty set of settings
if (isset($storeProps[PR_EC_WEBACCESS_SETTINGS_JSON]) || propIsError(PR_EC_WEBACCESS_SETTINGS_JSON, $storeProps) == MAPI_E_NOT_ENOUGH_MEMORY) {
// read the settings property
$stream = mapi_openpropertytostream($userStore, PR_EC_WEBACCESS_SETTINGS_JSON, MAPI_MODIFY);
if ($stream == false) {
echo "Error opening settings property\n";
}
$settings_string = "";
$stat = mapi_stream_stat($stream);
mapi_stream_seek($stream, 0, STREAM_SEEK_SET);
for ($i = 0; $i < $stat['cb']; $i += 1024) {
$settings_string .= mapi_stream_read($stream, 1024);
}
if(empty($settings_string)) {
// property exists but without any content so ignore it and continue with
// empty set of settings
return;
}
$settings = json_decode($settings_string, true);
if (empty($settings) || empty($settings['settings'])) {
echo "Error retrieving existing settings\n";
}
$settings["settings"]["zarafa"]["v1"]["contexts"]["calendar"]["icssync"][$icsentry]["lastsync"] = date('Y-m-d H:i:s');
$newsettings = json_encode($settings);
mapi_stream_setsize($stream, strlen($newsettings));
mapi_stream_seek($stream, 0, STREAM_SEEK_SET);
mapi_stream_write($stream, $newsettings);
$res = mapi_stream_commit ($stream);
return $res;
}
return false;
}
/* upload a file */
function upload_ics_to_caldav($filename, $caldavurl, $username, $calendarname, $authuser = NULL, $authpass = NULL) {
$url = $caldavurl . $username . "/" . rawurlencode($calendarname) . "/";
$post = array('file'=>'@'.$filename);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$fp = fopen($filename, 'r');
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize ($filename));
if($authuser != NULL && $authpass != NULL) {
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$authuser:$authpass");
}
$result=curl_exec($ch);
$http_status = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
curl_close($ch);
echo "uploading file to: " . $url . " (" . $http_status . ")\n";
return $http_status;
}
<?php
/**
* functions.php, zarafa calender to ics im/exporter backend
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* gets the data from a URL */
function curl_get_data($url, $username = NULL, $password = NULL) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
if($username != NULL && $password != NULL) {
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
}
$data = curl_exec($ch);
$http_status = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
curl_close($ch);
if($http_status > 210 || $http_status < 200)
return NULL;
return $data;
}
/* gets all zarafa users */
function get_user_ics_list($userStore) {
// get settings
// first check if property exist and we can open that using mapi_openproperty
$storeProps = mapi_getprops($userStore, array(PR_EC_WEBACCESS_SETTINGS_JSON));
// Check if property exists, if it doesn not exist then we can continue with empty set of settings
if (isset($storeProps[PR_EC_WEBACCESS_SETTINGS_JSON]) || propIsError(PR_EC_WEBACCESS_SETTINGS_JSON, $storeProps) == MAPI_E_NOT_ENOUGH_MEMORY) {
// read the settings property
$stream = mapi_openproperty($userStore, PR_EC_WEBACCESS_SETTINGS_JSON, IID_IStream, 0, 0);
if ($stream == false) {
echo "Error opening settings property\n";
}
$settings_string = "";
$stat = mapi_stream_stat($stream);
mapi_stream_seek($stream, 0, STREAM_SEEK_SET);
for ($i = 0; $i < $stat['cb']; $i += 1024) {
$settings_string .= mapi_stream_read($stream, 1024);
}
if(empty($settings_string)) {
// property exists but without any content so ignore it and continue with
// empty set of settings
return;
}
$settings = json_decode($settings_string, true);
if (empty($settings) || empty($settings['settings'])) {
echo "Error retrieving existing settings\n";
}
$calcontext = $settings["settings"]["zarafa"]["v1"]["contexts"]["calendar"];
if(isset($calcontext["icssync"])) {
foreach($calcontext["icssync"] as $syncitem) {
echo "Found sync url: " . $syncitem["icsurl"] . " for calendar: " . $syncitem["calendar"] . "\n";
}
return $calcontext["icssync"];
}
return NULL;
}
}
/* updates the webapp settings */
function update_last_sync_date($userStore, $icsentry) {
// get settings
// first check if property exist and we can open that using mapi_openproperty
$storeProps = mapi_getprops($userStore, array(PR_EC_WEBACCESS_SETTINGS_JSON));
// Check if property exists, if it doesn not exist then we can continue with empty set of settings
if (isset($storeProps[PR_EC_WEBACCESS_SETTINGS_JSON]) || propIsError(PR_EC_WEBACCESS_SETTINGS_JSON, $storeProps) == MAPI_E_NOT_ENOUGH_MEMORY) {
// read the settings property
$stream = mapi_openpropertytostream($userStore, PR_EC_WEBACCESS_SETTINGS_JSON, MAPI_MODIFY);
if ($stream == false) {
echo "Error opening settings property\n";
}
$settings_string = "";
$stat = mapi_stream_stat($stream);
mapi_stream_seek($stream, 0, STREAM_SEEK_SET);
for ($i = 0; $i < $stat['cb']; $i += 1024) {
$settings_string .= mapi_stream_read($stream, 1024);
}
if(empty($settings_string)) {
// property exists but without any content so ignore it and continue with
// empty set of settings
return;
}
$settings = json_decode($settings_string, true);
if (empty($settings) || empty($settings['settings'])) {
echo "Error retrieving existing settings\n";
}
$settings["settings"]["zarafa"]["v1"]["contexts"]["calendar"]["icssync"][$icsentry]["lastsync"] = date('Y-m-d H:i:s');
$newsettings = json_encode($settings);
mapi_stream_setsize($stream, strlen($newsettings));
mapi_stream_seek($stream, 0, STREAM_SEEK_SET);
mapi_stream_write($stream, $newsettings);
$res = mapi_stream_commit ($stream);
return $res;
}
return false;
}
/* upload a file */
function upload_ics_to_caldav($filename, $caldavurl, $username, $calendarname, $authuser = NULL, $authpass = NULL) {
$url = $caldavurl . $username . "/" . rawurlencode($calendarname) . "/";
$post = array('file'=>'@'.$filename);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$fp = fopen($filename, 'r');
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize ($filename));
if($authuser != NULL && $authpass != NULL) {
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$authuser:$authpass");
}
$result=curl_exec($ch);
$http_status = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
curl_close($ch);
echo "uploading file to: " . $url . " (" . $http_status . ")\n";
return $http_status;
}
?>

View File

@@ -1,150 +1,150 @@
#!/usr/bin/php
<?php
/**
* sync.php, zarafa calender to ics im/exporter backend
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
if(php_sapi_name() !== 'cli') {
die("Script must be run from commandline!");
}
/**
* Make sure that the zarafa mapi extension is enabled in cli mode:
* Add: /etc/php5/cli/conf.d/50-mapi.ini
* Content: extension=mapi.so
*/
// MAPI includes
include('/usr/share/php/mapi/mapi.util.php');
include('/usr/share/php/mapi/mapidefs.php');
include('/usr/share/php/mapi/mapicode.php');
include('/usr/share/php/mapi/mapitags.php');
include('/usr/share/php/mapi/mapiguid.php');
include('config.php');
include('functions.php');
// log in to zarafa
$session = mapi_logon_zarafa($ADMINUSERNAME, $ADMINPASSWORD, $SERVER);
if($session === FALSE) {
exit("Logon failed with error " .mapi_last_hresult() . "\n");
}
// load all stores for the admin user
$storeTable = mapi_getmsgstorestable($session);
if($storeTable === FALSE) {
exit("Storetable could not be opened. Error " .mapi_last_hresult() . "\n");
}
$storesList = mapi_table_queryallrows($storeTable, array(PR_ENTRYID, PR_DEFAULT_STORE));
// get admin users default store
foreach ($storesList as $row) {
if($row[PR_DEFAULT_STORE]) {
$storeEntryid = $row[PR_ENTRYID];
}
}
if(!$storeEntryid) {
exit("Can't find default store\n");
}
// open default store
$store = mapi_openmsgstore($session, $storeEntryid);
if(!$store) {
exit("Unable to open system store\n");
}
// get a userlist
$userList = array();
// for multi company setup
$companyList = mapi_zarafa_getcompanylist($store);
if(mapi_last_hresult() == NOERROR && is_array($companyList)) {
// multi company setup, get all users from all companies
foreach($companyList as $companyName => $companyData) {
$userList = array_merge($userList, mapi_zarafa_getuserlist($store, $companyData["companyid"]));
}
} else {
// single company setup, get list of all zarafa users
$userList = mapi_zarafa_getuserlist($store);
}
if(count($userList) <= 0) {
exit("Unable to get user list\n");
}
// loop over all users
foreach($userList as $userName => $userData) {
// check for valid users
if($userName == "SYSTEM" ||$userName == $ADMINUSERNAME) {
continue;
}
echo "###Getting sync settings for user: " . $userName . "\n";
$userEntryId = mapi_msgstore_createentryid($store, $userName);
$userStore = mapi_openmsgstore($session, $userEntryId);
if(!$userStore) {
echo "Can't open user store\n";
continue;
}
$syncItems = get_user_ics_list($userStore);
if($syncItems != NULL && count($syncItems) > 0) {
foreach($syncItems as $syncItemName => $syncItem) {
//check update intervall
$lastUpdate = strtotime($syncItem["lastsync"]);
$updateIntervall = intval($syncItem["intervall"]) * 60; // we need seconds
$currenttime = time();
if(($lastUpdate + $updateIntervall) <= $currenttime) {
echo "Update intervall OK ($currenttime): " . ($lastUpdate + $updateIntervall) . "\n";
$tmpFilename = $TEMPDIR . uniqid($userName . $syncItem["calendar"], true) . ".ics";
$user = NULL;
$pass= NULL;
if($syncItem["user"] != NULL && !empty($syncItem["user"]))
$user = $syncItem["user"];
if($syncItem["pass"] != NULL && !empty($syncItem["pass"]))
$pass= base64_decode($syncItem["pass"]);
$icsData = curl_get_data($syncItem["icsurl"], $user, $pass);
if($icsData != NULL) {
file_put_contents($tmpFilename, $icsData);
echo "Got valid data for " . $syncItem["icsurl"] . " stored in " . $tmpFilename . "\n";
$result = upload_ics_to_caldav($tmpFilename, $CALDAVURL, $userName, $syncItem["calendarname"], $ADMINUSERNAME, $ADMINPASSWORD);
if(intval($result) == 200) {
echo "Import completed: $result\n";
$result = update_last_sync_date($userStore, $syncItemName);
$res = $result ? "true":"false";
echo "Updated Zarafa settings: " . $res . "\n";
} else {
echo "Uploading failed: " . $result . "\n";
}
}
} else {
echo "Update intervall STOP ($currenttime): " . ($lastUpdate + $updateIntervall) . "\n";
}
}
}
echo "###Done sync for user: " . $userName . "\n\n";
}
#!/usr/bin/php
<?php
/**
* sync.php, zarafa calender to ics im/exporter backend
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
if(php_sapi_name() !== 'cli') {
die("Script must be run from commandline!");
}
/**
* Make sure that the zarafa mapi extension is enabled in cli mode:
* Add: /etc/php5/cli/conf.d/50-mapi.ini
* Content: extension=mapi.so
*/
// MAPI includes
include('/usr/share/php/mapi/mapi.util.php');
include('/usr/share/php/mapi/mapidefs.php');
include('/usr/share/php/mapi/mapicode.php');
include('/usr/share/php/mapi/mapitags.php');
include('/usr/share/php/mapi/mapiguid.php');
include('config.php');
include('functions.php');
// log in to zarafa
$session = mapi_logon_zarafa($ADMINUSERNAME, $ADMINPASSWORD, $SERVER);
if($session === FALSE) {
exit("Logon failed with error " .mapi_last_hresult() . "\n");
}
// load all stores for the admin user
$storeTable = mapi_getmsgstorestable($session);
if($storeTable === FALSE) {
exit("Storetable could not be opened. Error " .mapi_last_hresult() . "\n");
}
$storesList = mapi_table_queryallrows($storeTable, array(PR_ENTRYID, PR_DEFAULT_STORE));
// get admin users default store
foreach ($storesList as $row) {
if($row[PR_DEFAULT_STORE]) {
$storeEntryid = $row[PR_ENTRYID];
}
}
if(!$storeEntryid) {
exit("Can't find default store\n");
}
// open default store
$store = mapi_openmsgstore($session, $storeEntryid);
if(!$store) {
exit("Unable to open system store\n");
}
// get a userlist
$userList = array();
// for multi company setup
$companyList = mapi_zarafa_getcompanylist($store);
if(mapi_last_hresult() == NOERROR && is_array($companyList)) {
// multi company setup, get all users from all companies
foreach($companyList as $companyName => $companyData) {
$userList = array_merge($userList, mapi_zarafa_getuserlist($store, $companyData["companyid"]));
}
} else {
// single company setup, get list of all zarafa users
$userList = mapi_zarafa_getuserlist($store);
}
if(count($userList) <= 0) {
exit("Unable to get user list\n");
}
// loop over all users
foreach($userList as $userName => $userData) {
// check for valid users
if($userName == "SYSTEM" ||$userName == $ADMINUSERNAME) {
continue;
}
echo "###Getting sync settings for user: " . $userName . "\n";
$userEntryId = mapi_msgstore_createentryid($store, $userName);
$userStore = mapi_openmsgstore($session, $userEntryId);
if(!$userStore) {
echo "Can't open user store\n";
continue;
}
$syncItems = get_user_ics_list($userStore);
if($syncItems != NULL && count($syncItems) > 0) {
foreach($syncItems as $syncItemName => $syncItem) {
//check update intervall
$lastUpdate = strtotime($syncItem["lastsync"]);
$updateIntervall = intval($syncItem["intervall"]) * 60; // we need seconds
$currenttime = time();
if(($lastUpdate + $updateIntervall) <= $currenttime) {
echo "Update intervall OK ($currenttime): " . ($lastUpdate + $updateIntervall) . "\n";
$tmpFilename = $TEMPDIR . uniqid($userName . $syncItem["calendar"], true) . ".ics";
$user = NULL;
$pass= NULL;
if($syncItem["user"] != NULL && !empty($syncItem["user"]))
$user = $syncItem["user"];
if($syncItem["pass"] != NULL && !empty($syncItem["pass"]))
$pass= base64_decode($syncItem["pass"]);
$icsData = curl_get_data($syncItem["icsurl"], $user, $pass);
if($icsData != NULL) {
file_put_contents($tmpFilename, $icsData);
echo "Got valid data for " . $syncItem["icsurl"] . " stored in " . $tmpFilename . "\n";
$result = upload_ics_to_caldav($tmpFilename, $CALDAVURL, $userName, $syncItem["calendarname"], $ADMINUSERNAME, $ADMINPASSWORD);
if(intval($result) == 200) {
echo "Import completed: $result\n";
$result = update_last_sync_date($userStore, $syncItemName);
$res = $result ? "true":"false";
echo "Updated Zarafa settings: " . $res . "\n";
} else {
echo "Uploading failed: " . $result . "\n";
}
}
} else {
echo "Update intervall STOP ($currenttime): " . ($lastUpdate + $updateIntervall) . "\n";
}
}
}
echo "###Done sync for user: " . $userName . "\n\n";
}
?>