(merge) CardDAV, CalDAV via ownCloud and move to z-push fork fork
Merges branch 'owncloud' of github.com:jkaberg/mailinabox which is pull request #135, closes #135 thanks @jkaberg, @fmbiete, @owncloud
This commit is contained in:
commit
04454b35c6
|
@ -27,6 +27,12 @@ In short, it's like this:
|
||||||
cd mailinabox
|
cd mailinabox
|
||||||
sudo setup/start.sh
|
sudo setup/start.sh
|
||||||
|
|
||||||
|
Then run the post-install checklist command to see what you need to do next:
|
||||||
|
|
||||||
|
sudo management/whats_next.py
|
||||||
|
|
||||||
|
Congratulations! You should now have a working setup. Feel free to login with your mail credentials created earlier in the setup
|
||||||
|
|
||||||
**Status**: This is a work in progress. It works for what it is, but it is missing such things as quotas, backup/restore, etc.
|
**Status**: This is a work in progress. It works for what it is, but it is missing such things as quotas, backup/restore, etc.
|
||||||
|
|
||||||
The Goals
|
The Goals
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
# ownCloud configuration.
|
||||||
|
rewrite ^/cloud$ /cloud/ redirect;
|
||||||
|
rewrite ^/cloud/$ /cloud/index.php;
|
||||||
|
rewrite ^(/cloud/core/doc/[^\/]+/)$ $1/index.html;
|
||||||
|
location /cloud/ {
|
||||||
|
alias /usr/local/lib/owncloud/;
|
||||||
|
location ~ ^/(data|config|\.ht|db_structure\.xml|README) {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
location ~ ^(/cloud)(/[^/]+\.php)(/.*)?$ {
|
||||||
|
# note: ~ has precendence over a regular location block
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_param SCRIPT_FILENAME /usr/local/lib/owncloud/$2;
|
||||||
|
fastcgi_param SCRIPT_NAME $1$2;
|
||||||
|
fastcgi_param PATH_INFO $3;
|
||||||
|
fastcgi_param MOD_X_ACCEL_REDIRECT_ENABLED on;
|
||||||
|
fastcgi_read_timeout 630;
|
||||||
|
fastcgi_pass php-fpm;
|
||||||
|
error_page 403 /cloud/core/templates/403.php;
|
||||||
|
error_page 404 /cloud/core/templates/404.php;
|
||||||
|
client_max_body_size 1G;
|
||||||
|
fastcgi_buffers 64 4K;
|
||||||
|
}
|
||||||
|
location ^~ /cloud/data {
|
||||||
|
# In order to support MOD_X_ACCEL_REDIRECT_ENABLED, we need to expose
|
||||||
|
# the data directory but only allow 'internal' redirects within nginx
|
||||||
|
# so that this is not exposed to the world.
|
||||||
|
internal;
|
||||||
|
alias $STORAGE_ROOT/owncloud;
|
||||||
|
}
|
||||||
|
location ~ ^/((caldav|carddav|webdav).*)$ {
|
||||||
|
# Z-Push doesn't like getting a redirect, and a plain rewrite didn't work either.
|
||||||
|
# Properly proxying like this seems to work fine.
|
||||||
|
proxy_pass https://$HOSTNAME/cloud/remote.php/$1;
|
||||||
|
}
|
||||||
|
rewrite ^/.well-known/host-meta /cloud/public.php?service=host-meta last;
|
||||||
|
rewrite ^/.well-known/host-meta.json /cloud/public.php?service=host-meta-json last;
|
||||||
|
rewrite ^/.well-known/carddav /cloud/remote.php/carddav/ redirect;
|
||||||
|
rewrite ^/.well-known/caldav /cloud/remote.php/caldav/ redirect;
|
||||||
|
|
|
@ -36,6 +36,7 @@ server {
|
||||||
return 403;
|
return 403;
|
||||||
}
|
}
|
||||||
location ~ /mail/.*\.php {
|
location ~ /mail/.*\.php {
|
||||||
|
# note: ~ has precendence over a regular location block
|
||||||
include fastcgi_params;
|
include fastcgi_params;
|
||||||
fastcgi_split_path_info ^/mail(/.*)()$;
|
fastcgi_split_path_info ^/mail(/.*)()$;
|
||||||
fastcgi_index index.php;
|
fastcgi_index index.php;
|
||||||
|
@ -60,8 +61,9 @@ server {
|
||||||
|
|
||||||
# Z-Push (Microsoft Exchange ActiveSync)
|
# Z-Push (Microsoft Exchange ActiveSync)
|
||||||
location /Microsoft-Server-ActiveSync {
|
location /Microsoft-Server-ActiveSync {
|
||||||
include /etc/nginx/fastcgi_params;
|
include /etc/nginx/fastcgi_params;
|
||||||
fastcgi_param SCRIPT_FILENAME /usr/local/lib/z-push/index.php;
|
fastcgi_param SCRIPT_FILENAME /usr/local/lib/z-push/index.php;
|
||||||
|
fastcgi_read_timeout 630;
|
||||||
fastcgi_pass php-fpm;
|
fastcgi_pass php-fpm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
/***********************************************
|
||||||
|
* File : config.php
|
||||||
|
* Project : Z-Push
|
||||||
|
* Descr : CalDAV backend configuration file
|
||||||
|
************************************************/
|
||||||
|
|
||||||
|
define('CALDAV_SERVER', 'https://localhost');
|
||||||
|
define('CALDAV_PORT', '443');
|
||||||
|
define('CALDAV_PATH', '/caldav/calendars/%u/');
|
||||||
|
define('CALDAV_PERSONAL', '');
|
||||||
|
|
||||||
|
// If the CalDAV server supports the sync-collection operation
|
||||||
|
// DAViCal and SOGo support it
|
||||||
|
// Setting this to false will work with most servers, but it will be slower
|
||||||
|
define('CALDAV_SUPPORTS_SYNC', false);
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
/***********************************************
|
||||||
|
* File : config.php
|
||||||
|
* Project : Z-Push
|
||||||
|
* Descr : CardDAV backend configuration file
|
||||||
|
************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
define('CARDDAV_PROTOCOL', 'https'); /* http or https */
|
||||||
|
define('CARDDAV_SERVER', 'localhost');
|
||||||
|
define('CARDDAV_PORT', '443');
|
||||||
|
define('CARDDAV_PATH', '/carddav/addressbooks/%u/');
|
||||||
|
define('CARDDAV_DEFAULT_PATH', '/carddav/addressbooks/%u/contacts/'); /* subdirectory of the main path */
|
||||||
|
define('CARDDAV_GAL_PATH', ''); /* readonly, searchable, not syncd */
|
||||||
|
define('CARDDAV_GAL_MIN_LENGTH', 5);
|
||||||
|
define('CARDDAV_CONTACTS_FOLDER_NAME', '%u Addressbook');
|
||||||
|
|
||||||
|
|
||||||
|
// If the CardDAV server supports the sync-collection operation
|
||||||
|
// DAViCal supports it, but SabreDav, Owncloud, SOGo don't
|
||||||
|
// Setting this to false will work with most servers, but it will be slower: 1 petition for the href of vcards, and 1 petition for each vcard
|
||||||
|
define('CARDDAV_SUPPORTS_SYNC', false);
|
||||||
|
|
||||||
|
|
||||||
|
// If the CardDAV server supports the FN attribute for searches
|
||||||
|
// DAViCal supports it, but SabreDav, Owncloud and SOGo don't
|
||||||
|
// Setting this to true will search by FN. If false will search by sn, givenName and email
|
||||||
|
// It's safe to leave it as false
|
||||||
|
define('CARDDAV_SUPPORTS_FN_SEARCH', false);
|
||||||
|
|
||||||
|
|
||||||
|
// If your carddav server needs to use file extension to recover a vcard.
|
||||||
|
// Davical needs it
|
||||||
|
// SOGo official demo online needs it, but some SOGo installation don't need it, so test it
|
||||||
|
define('CARDDAV_URL_VCARD_EXTENSION', '.vcf');
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
/***********************************************
|
||||||
|
* File : backend/combined/config.php
|
||||||
|
* Project : Z-Push
|
||||||
|
* Descr : configuration file for the
|
||||||
|
* combined backend.
|
||||||
|
************************************************/
|
||||||
|
|
||||||
|
class BackendCombinedConfig {
|
||||||
|
public static function GetBackendCombinedConfig() {
|
||||||
|
return array(
|
||||||
|
'backends' => array(
|
||||||
|
'i' => array(
|
||||||
|
'name' => 'BackendIMAP',
|
||||||
|
),
|
||||||
|
'c' => array(
|
||||||
|
'name' => 'BackendCalDAV',
|
||||||
|
),
|
||||||
|
'd' => array(
|
||||||
|
'name' => 'BackendCardDAV',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'delimiter' => '/',
|
||||||
|
'folderbackend' => array(
|
||||||
|
SYNC_FOLDER_TYPE_INBOX => 'i',
|
||||||
|
SYNC_FOLDER_TYPE_DRAFTS => 'i',
|
||||||
|
SYNC_FOLDER_TYPE_WASTEBASKET => 'i',
|
||||||
|
SYNC_FOLDER_TYPE_SENTMAIL => 'i',
|
||||||
|
SYNC_FOLDER_TYPE_OUTBOX => 'i',
|
||||||
|
SYNC_FOLDER_TYPE_TASK => 'c',
|
||||||
|
SYNC_FOLDER_TYPE_APPOINTMENT => 'c',
|
||||||
|
SYNC_FOLDER_TYPE_CONTACT => 'd',
|
||||||
|
SYNC_FOLDER_TYPE_NOTE => 'c',
|
||||||
|
SYNC_FOLDER_TYPE_JOURNAL => 'c',
|
||||||
|
SYNC_FOLDER_TYPE_OTHER => 'i',
|
||||||
|
SYNC_FOLDER_TYPE_USER_MAIL => 'i',
|
||||||
|
SYNC_FOLDER_TYPE_USER_APPOINTMENT => 'c',
|
||||||
|
SYNC_FOLDER_TYPE_USER_CONTACT => 'd',
|
||||||
|
SYNC_FOLDER_TYPE_USER_TASK => 'c',
|
||||||
|
SYNC_FOLDER_TYPE_USER_JOURNAL => 'c',
|
||||||
|
SYNC_FOLDER_TYPE_USER_NOTE => 'c',
|
||||||
|
SYNC_FOLDER_TYPE_UNKNOWN => 'i',
|
||||||
|
),
|
||||||
|
'rootcreatefolderbackend' => 'i',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
/***********************************************
|
||||||
|
* File : config.php
|
||||||
|
* Project : Z-Push
|
||||||
|
* Descr : IMAP backend configuration file
|
||||||
|
************************************************/
|
||||||
|
|
||||||
|
define('IMAP_SERVER', 'localhost');
|
||||||
|
define('IMAP_PORT', 993);
|
||||||
|
define('IMAP_OPTIONS', '/ssl/norsh/novalidate-cert');
|
||||||
|
define('IMAP_DEFAULTFROM', '');
|
||||||
|
|
||||||
|
// not used
|
||||||
|
define('IMAP_FROM_SQL_DSN', '');
|
||||||
|
define('IMAP_FROM_SQL_USER', '');
|
||||||
|
define('IMAP_FROM_SQL_PASSWORD', '');
|
||||||
|
define('IMAP_FROM_SQL_OPTIONS', serialize(array(PDO::ATTR_PERSISTENT => true)));
|
||||||
|
define('IMAP_FROM_SQL_QUERY', "select first_name, last_name, mail_address from users where mail_address = '#username@#domain'");
|
||||||
|
define('IMAP_FROM_SQL_FIELDS', serialize(array('first_name', 'last_name', 'mail_address')));
|
||||||
|
define('IMAP_FROM_SQL_FROM', '#first_name #last_name <#mail_address>');
|
||||||
|
define('IMAP_FROM_LDAP_SERVER', '');
|
||||||
|
define('IMAP_FROM_LDAP_SERVER_PORT', '389');
|
||||||
|
define('IMAP_FROM_LDAP_USER', 'cn=zpush,ou=servers,dc=zpush,dc=org');
|
||||||
|
define('IMAP_FROM_LDAP_PASSWORD', 'password');
|
||||||
|
define('IMAP_FROM_LDAP_BASE', 'dc=zpush,dc=org');
|
||||||
|
define('IMAP_FROM_LDAP_QUERY', '(mail=#username@#domain)');
|
||||||
|
define('IMAP_FROM_LDAP_FIELDS', serialize(array('givenname', 'sn', 'mail')));
|
||||||
|
define('IMAP_FROM_LDAP_FROM', '#givenname #sn <#mail>');
|
||||||
|
|
||||||
|
|
||||||
|
// copy outgoing mail to this folder. If not set z-push will try the default folders
|
||||||
|
define('IMAP_SENTFOLDER', '');
|
||||||
|
define('IMAP_INLINE_FORWARD', true);
|
||||||
|
define('IMAP_EXCLUDED_FOLDERS', '');
|
||||||
|
define('IMAP_SMTP_METHOD', 'sendmail');
|
||||||
|
|
||||||
|
global $imap_smtp_params;
|
||||||
|
$imap_smtp_params = array('host' => 'ssl://localhost', 'port' => 587, 'auth' => true, 'username' => 'imap_username', 'password' => 'imap_password');
|
||||||
|
|
||||||
|
define('MAIL_MIMEPART_CRLF', "\r\n");
|
||||||
|
|
||||||
|
?>
|
|
@ -43,9 +43,10 @@ def do_web_update(env):
|
||||||
nginx_conf = open(os.path.join(os.path.dirname(__file__), "../conf/nginx-top.conf")).read()
|
nginx_conf = open(os.path.join(os.path.dirname(__file__), "../conf/nginx-top.conf")).read()
|
||||||
|
|
||||||
# Add configuration for each web domain.
|
# Add configuration for each web domain.
|
||||||
template = open(os.path.join(os.path.dirname(__file__), "../conf/nginx.conf")).read()
|
template1 = open(os.path.join(os.path.dirname(__file__), "../conf/nginx.conf")).read()
|
||||||
|
template2 = open(os.path.join(os.path.dirname(__file__), "../conf/nginx-primaryonly.conf")).read()
|
||||||
for domain in get_web_domains(env):
|
for domain in get_web_domains(env):
|
||||||
nginx_conf += make_domain_config(domain, template, env)
|
nginx_conf += make_domain_config(domain, template1, template2, env)
|
||||||
|
|
||||||
# Did the file change? If not, don't bother writing & restarting nginx.
|
# Did the file change? If not, don't bother writing & restarting nginx.
|
||||||
nginx_conf_fn = "/etc/nginx/conf.d/local.conf"
|
nginx_conf_fn = "/etc/nginx/conf.d/local.conf"
|
||||||
|
@ -63,7 +64,7 @@ def do_web_update(env):
|
||||||
|
|
||||||
return "web updated\n"
|
return "web updated\n"
|
||||||
|
|
||||||
def make_domain_config(domain, template, env):
|
def make_domain_config(domain, template, template_for_primaryhost, env):
|
||||||
# How will we configure this domain.
|
# How will we configure this domain.
|
||||||
|
|
||||||
# Where will its root directory be for static files?
|
# Where will its root directory be for static files?
|
||||||
|
@ -77,25 +78,30 @@ def make_domain_config(domain, template, env):
|
||||||
# available. Make a self-signed one now if one doesn't exist.
|
# available. Make a self-signed one now if one doesn't exist.
|
||||||
ensure_ssl_certificate_exists(domain, ssl_key, ssl_certificate, csr_path, env)
|
ensure_ssl_certificate_exists(domain, ssl_key, ssl_certificate, csr_path, env)
|
||||||
|
|
||||||
|
# Put pieces together.
|
||||||
|
nginx_conf_parts = re.split("\s*# ADDITIONAL DIRECTIVES HERE\s*", template)
|
||||||
|
nginx_conf = nginx_conf_parts[0] + "\n"
|
||||||
|
if domain == env['PRIMARY_HOSTNAME']:
|
||||||
|
nginx_conf += template_for_primaryhost + "\n"
|
||||||
|
|
||||||
# Replace substitution strings in the template & return.
|
# Replace substitution strings in the template & return.
|
||||||
nginx_conf = template
|
nginx_conf = nginx_conf.replace("$STORAGE_ROOT", env['STORAGE_ROOT'])
|
||||||
nginx_conf = nginx_conf.replace("$HOSTNAME", domain)
|
nginx_conf = nginx_conf.replace("$HOSTNAME", domain)
|
||||||
nginx_conf = nginx_conf.replace("$ROOT", root)
|
nginx_conf = nginx_conf.replace("$ROOT", root)
|
||||||
nginx_conf = nginx_conf.replace("$SSL_KEY", ssl_key)
|
nginx_conf = nginx_conf.replace("$SSL_KEY", ssl_key)
|
||||||
nginx_conf = nginx_conf.replace("$SSL_CERTIFICATE", ssl_certificate)
|
nginx_conf = nginx_conf.replace("$SSL_CERTIFICATE", ssl_certificate)
|
||||||
|
|
||||||
# Add in any user customizations.
|
# Add in any user customizations.
|
||||||
nginx_conf_parts = re.split("(# ADDITIONAL DIRECTIVES HERE\n)", nginx_conf)
|
|
||||||
nginx_conf_custom_fn = os.path.join(env["STORAGE_ROOT"], "www/custom.yaml")
|
nginx_conf_custom_fn = os.path.join(env["STORAGE_ROOT"], "www/custom.yaml")
|
||||||
if os.path.exists(nginx_conf_custom_fn):
|
if os.path.exists(nginx_conf_custom_fn):
|
||||||
yaml = rtyaml.load(open(nginx_conf_custom_fn))
|
yaml = rtyaml.load(open(nginx_conf_custom_fn))
|
||||||
if domain in yaml:
|
if domain in yaml:
|
||||||
yaml = yaml[domain]
|
yaml = yaml[domain]
|
||||||
if "proxy" in yaml:
|
if "proxy" in yaml:
|
||||||
nginx_conf_parts[1] += "\tlocation / {\n\t\tproxy_pass %s;\n\t}\n" % yaml["proxy"]
|
nginx_conf += "\tlocation / {\n\t\tproxy_pass %s;\n\t}\n" % yaml["proxy"]
|
||||||
|
|
||||||
# Put it all together.
|
# Ending.
|
||||||
nginx_conf = "".join(nginx_conf_parts)
|
nginx_conf += nginx_conf_parts[1]
|
||||||
|
|
||||||
return nginx_conf
|
return nginx_conf
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Owncloud
|
||||||
|
##########################
|
||||||
|
|
||||||
|
source setup/functions.sh # load our functions
|
||||||
|
source /etc/mailinabox.conf # load global vars
|
||||||
|
|
||||||
|
apt_install \
|
||||||
|
dbconfig-common \
|
||||||
|
php5-cli php5-sqlite php5-gd php5-imap php5-curl php-pear php-apc curl libapr1 libtool libcurl4-openssl-dev php-xml-parser \
|
||||||
|
php5 php5-dev php5-gd php5-fpm memcached php5-memcache unzip
|
||||||
|
|
||||||
|
apt-get purge -qq -y owncloud*
|
||||||
|
|
||||||
|
# Install ownCloud from source if it is not already present
|
||||||
|
# TODO: Check version?
|
||||||
|
if [ ! -d /usr/local/lib/owncloud ]; then
|
||||||
|
echo installing ownCloud...
|
||||||
|
rm -f /tmp/owncloud.zip
|
||||||
|
wget -qO /tmp/owncloud.zip https://download.owncloud.org/community/owncloud-7.0.1.zip
|
||||||
|
unzip -q /tmp/owncloud.zip -d /usr/local/lib
|
||||||
|
rm -f /tmp/owncloud.zip
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Setup ownCloud if the ownCloud database does not yet exist. Running setup when
|
||||||
|
# the database does exist wipes the database and user data.
|
||||||
|
if [ ! -f $STORAGE_ROOT/owncloud/owncloud.db ]; then
|
||||||
|
# Create a configuration file.
|
||||||
|
TIMEZONE=`cat /etc/timezone`
|
||||||
|
instanceid=oc$(echo $PRIMARY_HOSTNAME | sha1sum | fold -w 10 | head -n 1)
|
||||||
|
cat - > /usr/local/lib/owncloud/config/config.php <<EOF;
|
||||||
|
<?php
|
||||||
|
\$CONFIG = array (
|
||||||
|
'datadirectory' => '$STORAGE_ROOT/owncloud',
|
||||||
|
|
||||||
|
'instanceid' => '$instanceid',
|
||||||
|
|
||||||
|
'trusted_domains' =>
|
||||||
|
array (
|
||||||
|
0 => '$PRIMARY_HOSTNAME',
|
||||||
|
),
|
||||||
|
'forcessl' => true, # if unset/false, ownCloud sends a HSTS=0 header, which conflicts with nginx config
|
||||||
|
|
||||||
|
'overwritewebroot' => '/cloud',
|
||||||
|
'user_backends' => array(
|
||||||
|
array(
|
||||||
|
'class'=>'OC_User_IMAP',
|
||||||
|
'arguments'=>array('{localhost:993/imap/ssl/novalidate-cert}')
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"memcached_servers" => array (
|
||||||
|
array('localhost', 11211),
|
||||||
|
),
|
||||||
|
'mail_smtpmode' => 'sendmail',
|
||||||
|
'mail_smtpsecure' => '',
|
||||||
|
'mail_smtpauthtype' => 'LOGIN',
|
||||||
|
'mail_smtpauth' => false,
|
||||||
|
'mail_smtphost' => '',
|
||||||
|
'mail_smtpport' => '',
|
||||||
|
'mail_smtpname' => '',
|
||||||
|
'mail_smtppassword' => '',
|
||||||
|
'mail_from_address' => 'owncloud',
|
||||||
|
'mail_domain' => '$PRIMARY_HOSTNAME',
|
||||||
|
'logtimezone' => '$TIMEZONE',
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create an auto-configuration file to fill in database settings
|
||||||
|
# when the install script is run. Make an administrator account
|
||||||
|
# here or else the install can't finish.
|
||||||
|
adminpassword=$(dd if=/dev/random bs=40 count=1 2>/dev/null | sha1sum | fold -w 30 | head -n 1)
|
||||||
|
cat - > /usr/local/lib/owncloud/config/autoconfig.php <<EOF;
|
||||||
|
<?php
|
||||||
|
\$AUTOCONFIG = array (
|
||||||
|
# storage/database
|
||||||
|
'directory' => '$STORAGE_ROOT/owncloud',
|
||||||
|
'dbtype' => 'sqlite3',
|
||||||
|
|
||||||
|
# create an administrator account with a random password so that
|
||||||
|
# the user does not have to enter anything on first load of ownCloud
|
||||||
|
'adminlogin' => 'root',
|
||||||
|
'adminpass' => '$adminpassword',
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create user data directory and set permissions
|
||||||
|
mkdir -p $STORAGE_ROOT/owncloud
|
||||||
|
chown -R www-data.www-data $STORAGE_ROOT/owncloud /usr/local/lib/owncloud
|
||||||
|
|
||||||
|
# Execute ownCloud's setup step, which creates the ownCloud sqlite database.
|
||||||
|
# It also wipes it if it exists. And it deletes the autoconfig.php file.
|
||||||
|
(cd /usr/local/lib/owncloud; sudo -u www-data php /usr/local/lib/owncloud/index.php;)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Enable/disable apps. Note that this must be done after the ownCloud setup.
|
||||||
|
# The firstrunwizard gave Josh all sorts of problems, so disabling that.
|
||||||
|
# user_external is what allows ownCloud to use IMAP for login.
|
||||||
|
hide_output php /usr/local/lib/owncloud/console.php app:disable firstrunwizard
|
||||||
|
hide_output php /usr/local/lib/owncloud/console.php app:enable user_external
|
||||||
|
|
||||||
|
# Set PHP FPM values to support large file uploads
|
||||||
|
# (semicolon is the comment character in this file, hashes produce deprecation warnings)
|
||||||
|
tools/editconf.py /etc/php5/fpm/php.ini -c ';' \
|
||||||
|
upload_max_filesize=16G \
|
||||||
|
post_max_size=16G \
|
||||||
|
output_buffering=16384 \
|
||||||
|
memory_limit=512M \
|
||||||
|
max_execution_time=600 \
|
||||||
|
short_open_tag=On
|
||||||
|
|
||||||
|
# Set up a cron job for owncloud.
|
||||||
|
cat > /etc/cron.hourly/mailinabox-owncloud << EOF;
|
||||||
|
#!/bin/bash
|
||||||
|
# Mail-in-a-Box
|
||||||
|
sudo -u www-data php -f /usr/local/lib/owncloud/cron.php
|
||||||
|
EOF
|
||||||
|
chmod +x /etc/cron.hourly/mailinabox-owncloud
|
||||||
|
|
||||||
|
## Ensure all system admins are ownCloud admins.
|
||||||
|
## Actually we don't do this. There's nothing much of interest that the user could
|
||||||
|
## change from the ownCloud admin, and there's a lot they could mess up.
|
||||||
|
#for user in $(tools/mail.py user admins); do
|
||||||
|
# sqlite3 $STORAGE_ROOT/owncloud/owncloud.db "INSERT OR IGNORE INTO oc_group_user VALUES ('admin', '$user')"
|
||||||
|
#done
|
||||||
|
|
||||||
|
# Finished.
|
||||||
|
php5enmod imap
|
||||||
|
restart_service php5-fpm
|
|
@ -274,6 +274,7 @@ EOF
|
||||||
. setup/spamassassin.sh
|
. setup/spamassassin.sh
|
||||||
. setup/web.sh
|
. setup/web.sh
|
||||||
. setup/webmail.sh
|
. setup/webmail.sh
|
||||||
|
. setup/owncloud.sh
|
||||||
. setup/zpush.sh
|
. setup/zpush.sh
|
||||||
. setup/management.sh
|
. setup/management.sh
|
||||||
|
|
||||||
|
|
|
@ -14,30 +14,51 @@ source /etc/mailinabox.conf # load global vars
|
||||||
# Prereqs.
|
# Prereqs.
|
||||||
|
|
||||||
apt_install \
|
apt_install \
|
||||||
php-soap php5-imap
|
php-soap php5-imap libawl-php php5-xsl
|
||||||
|
|
||||||
php5enmod imap
|
php5enmod imap
|
||||||
|
|
||||||
# Copy Z-Push into place.
|
# Copy Z-Push into place.
|
||||||
|
needs_update=0
|
||||||
if [ ! -d /usr/local/lib/z-push ]; then
|
if [ ! -f /usr/local/lib/z-push/version ]; then
|
||||||
ZPUSH=z-push-2.1.3-1892
|
needs_update=1
|
||||||
wget -qO /tmp/zpush.tgz http://download.z-push.org/final/2.1/$ZPUSH.tar.gz
|
elif [[ `curl -s https://api.github.com/repos/fmbiete/Z-Push-contrib/git/refs/heads/master` != `cat /usr/local/lib/z-push/version` ]]; then
|
||||||
tar -C /tmp -zxf /tmp/zpush.tgz
|
# checks if the version
|
||||||
mv /tmp/$ZPUSH /usr/local/lib/z-push
|
needs_update=1
|
||||||
|
fi
|
||||||
|
if [ $needs_update == 1 ]; then
|
||||||
|
rm -rf /usr/local/lib/z-push
|
||||||
|
rm -f /tmp/zpush.zip
|
||||||
|
echo installing z-push \(fmbiete fork\)...
|
||||||
|
wget -qO /tmp/zpush.zip https://github.com/fmbiete/Z-Push-contrib/archive/master.zip
|
||||||
|
unzip -q /tmp/zpush.zip -d /usr/local/lib/
|
||||||
|
mv /usr/local/lib/Z-Push-contrib-master /usr/local/lib/z-push
|
||||||
|
rm -f /usr/sbin/z-push-{admin,top}
|
||||||
ln -s /usr/local/lib/z-push/z-push-admin.php /usr/sbin/z-push-admin
|
ln -s /usr/local/lib/z-push/z-push-admin.php /usr/sbin/z-push-admin
|
||||||
ln -s /usr/local/lib/z-push/z-push-top.php /usr/sbin/z-push-top
|
ln -s /usr/local/lib/z-push/z-push-top.php /usr/sbin/z-push-top
|
||||||
rm /tmp/zpush.tgz;
|
rm /tmp/zpush.zip;
|
||||||
|
curl -s https://api.github.com/repos/fmbiete/Z-Push-contrib/git/refs/heads/master > /usr/local/lib/z-push/version
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Configure. Tell is to connect to email via IMAP using SSL. Since we connect on
|
# Configure default config.
|
||||||
# localhost, the certificate won't match (it may be self-signed and invalid anyway)
|
sed -i "s/define('TIMEZONE', .*/define('TIMEZONE', 'Etc\/UTC');/" /usr/local/lib/z-push/config.php
|
||||||
# so don't check the cert.
|
sed -i "s/define('BACKEND_PROVIDER', .*/define('BACKEND_PROVIDER', 'BackendCombined');/" /usr/local/lib/z-push/config.php
|
||||||
sed -i "s/define('BACKEND_PROVIDER', .*/define('BACKEND_PROVIDER', 'BackendIMAP');/" /usr/local/lib/z-push/config.php
|
|
||||||
#sed -i "s/define('IMAP_SERVER', .*/define('IMAP_SERVER', '$PRIMARY_HOSTNAME');/" /usr/local/lib/z-push/backend/imap/config.php
|
|
||||||
sed -i "s/define('IMAP_PORT', .*/define('IMAP_PORT', 993);/" /usr/local/lib/z-push/backend/imap/config.php
|
|
||||||
sed -i "s/define('IMAP_OPTIONS', .*/define('IMAP_OPTIONS', '\/ssl\/norsh\/novalidate-cert');/" /usr/local/lib/z-push/backend/imap/config.php
|
|
||||||
|
|
||||||
|
# Configure BACKEND
|
||||||
|
rm -f /usr/local/lib/z-push/backend/combined/config.php
|
||||||
|
cp conf/zpush/backend_combined.php /usr/local/lib/z-push/backend/combined/config.php
|
||||||
|
|
||||||
|
# Configure IMAP
|
||||||
|
rm -f /usr/local/lib/z-push/backend/imap/config.php
|
||||||
|
cp conf/zpush/backend_imap.php /usr/local/lib/z-push/backend/imap/config.php
|
||||||
|
|
||||||
|
# Configure CardDav
|
||||||
|
rm -f /usr/local/lib/z-push/backend/carddav/config.php
|
||||||
|
cp conf/zpush/backend_carddav.php /usr/local/lib/z-push/backend/carddav/config.php
|
||||||
|
|
||||||
|
# Configure CalDav
|
||||||
|
rm -f /usr/local/lib/z-push/backend/caldav/config.php
|
||||||
|
cp conf/zpush/backend_caldav.php /usr/local/lib/z-push/backend/caldav/config.php
|
||||||
|
|
||||||
# Some directories it will use.
|
# Some directories it will use.
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ settings = sys.argv[2:]
|
||||||
|
|
||||||
delimiter = "="
|
delimiter = "="
|
||||||
delimiter_re = r"\s*=\s*"
|
delimiter_re = r"\s*=\s*"
|
||||||
|
comment_char = "#"
|
||||||
folded_lines = False
|
folded_lines = False
|
||||||
testing = False
|
testing = False
|
||||||
while settings[0][0] == "-" and settings[0] != "--":
|
while settings[0][0] == "-" and settings[0] != "--":
|
||||||
|
@ -42,7 +43,11 @@ while settings[0][0] == "-" and settings[0] != "--":
|
||||||
delimiter = " "
|
delimiter = " "
|
||||||
delimiter_re = r"\s+"
|
delimiter_re = r"\s+"
|
||||||
elif opt == "-w":
|
elif opt == "-w":
|
||||||
|
# Line folding is possible in this file.
|
||||||
folded_lines = True
|
folded_lines = True
|
||||||
|
elif opt == "-c":
|
||||||
|
# Specifies a different comment character.
|
||||||
|
comment_char = settings.pop(0)
|
||||||
elif opt == "-t":
|
elif opt == "-t":
|
||||||
testing = True
|
testing = True
|
||||||
else:
|
else:
|
||||||
|
@ -60,7 +65,7 @@ while len(input_lines) > 0:
|
||||||
|
|
||||||
# If this configuration file uses folded lines, append any folded lines
|
# If this configuration file uses folded lines, append any folded lines
|
||||||
# into our input buffer.
|
# into our input buffer.
|
||||||
if folded_lines and line[0] not in ("#", " ", ""):
|
if folded_lines and line[0] not in (comment_char, " ", ""):
|
||||||
while len(input_lines) > 0 and input_lines[0][0] in " \t":
|
while len(input_lines) > 0 and input_lines[0][0] in " \t":
|
||||||
line += input_lines.pop(0)
|
line += input_lines.pop(0)
|
||||||
|
|
||||||
|
@ -68,7 +73,11 @@ while len(input_lines) > 0:
|
||||||
for i in range(len(settings)):
|
for i in range(len(settings)):
|
||||||
# Check that this line contain this setting from the command-line arguments.
|
# Check that this line contain this setting from the command-line arguments.
|
||||||
name, val = settings[i].split("=", 1)
|
name, val = settings[i].split("=", 1)
|
||||||
m = re.match("(\s*)(#\s*)?" + re.escape(name) + delimiter_re + "(.*?)\s*$", line, re.S)
|
m = re.match(
|
||||||
|
"(\s*)"
|
||||||
|
+ "(" + re.escape(comment_char) + "\s*)?"
|
||||||
|
+ re.escape(name) + delimiter_re + "(.*?)\s*$",
|
||||||
|
line, re.S)
|
||||||
if not m: continue
|
if not m: continue
|
||||||
indent, is_comment, existing_val = m.groups()
|
indent, is_comment, existing_val = m.groups()
|
||||||
|
|
||||||
|
@ -83,7 +92,7 @@ while len(input_lines) > 0:
|
||||||
|
|
||||||
# comment-out the existing line (also comment any folded lines)
|
# comment-out the existing line (also comment any folded lines)
|
||||||
if is_comment is None:
|
if is_comment is None:
|
||||||
buf += "#" + line.rstrip().replace("\n", "\n#") + "\n"
|
buf += comment_char + line.rstrip().replace("\n", "\n" + comment_char) + "\n"
|
||||||
else:
|
else:
|
||||||
# the line is already commented, pass it through
|
# the line is already commented, pass it through
|
||||||
buf += line
|
buf += line
|
||||||
|
|
|
@ -51,6 +51,7 @@ if len(sys.argv) < 2:
|
||||||
print(" tools/mail.py user remove user@domain.com")
|
print(" tools/mail.py user remove user@domain.com")
|
||||||
print(" tools/mail.py user make-admin user@domain.com")
|
print(" tools/mail.py user make-admin user@domain.com")
|
||||||
print(" tools/mail.py user remove-admin user@domain.com")
|
print(" tools/mail.py user remove-admin user@domain.com")
|
||||||
|
print(" tools/mail.py user admins (lists admins)")
|
||||||
print(" tools/mail.py alias (lists aliases)")
|
print(" tools/mail.py alias (lists aliases)")
|
||||||
print(" tools/mail.py alias add incoming.name@domain.com sent.to@other.domain.com")
|
print(" tools/mail.py alias add incoming.name@domain.com sent.to@other.domain.com")
|
||||||
print(" tools/mail.py alias remove incoming.name@domain.com")
|
print(" tools/mail.py alias remove incoming.name@domain.com")
|
||||||
|
@ -92,6 +93,13 @@ elif sys.argv[1] == "user" and sys.argv[2] in ("make-admin", "remove-admin") and
|
||||||
action = "remove"
|
action = "remove"
|
||||||
print(mgmt("/mail/users/privileges/" + action, { "email": sys.argv[3], "privilege": "admin" }))
|
print(mgmt("/mail/users/privileges/" + action, { "email": sys.argv[3], "privilege": "admin" }))
|
||||||
|
|
||||||
|
elif sys.argv[1] == "user" and sys.argv[2] == "admins":
|
||||||
|
# Dump a list of admin users.
|
||||||
|
users = mgmt("/mail/users?format=json", is_json=True)
|
||||||
|
for user in users:
|
||||||
|
if "admin" in user['privileges']:
|
||||||
|
print(user['email'])
|
||||||
|
|
||||||
elif sys.argv[1] == "alias" and len(sys.argv) == 2:
|
elif sys.argv[1] == "alias" and len(sys.argv) == 2:
|
||||||
print(mgmt("/mail/aliases"))
|
print(mgmt("/mail/aliases"))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue