Branch 'dev/boddie' - 5 commits - pykolab/auth pykolab/plugins pykolab/setup share/templates
Paul Boddie
boddie at kolabsys.com
Thu May 1 19:00:07 CEST 2014
pykolab/auth/ldap/__init__.py | 9 ++
pykolab/plugins/roundcubedb/__init__.py | 69 ++++++++++++++++++
pykolab/setup/setup_roundcube.py | 1
share/templates/roundcubemail/calendar.inc.php.tpl | 1
share/templates/roundcubemail/managesieve.inc.php.tpl | 1
5 files changed, 81 insertions(+)
New commits:
commit 4be0f28d1206999530c72f70f80c7e46ba73908a
Merge: 16f5c7e c7c17c9
Author: Paul Boddie <paul at boddie.org.uk>
Date: Thu May 1 18:59:15 2014 +0200
Merge branch 'master' of git://git.kolab.org/git/pykolab into dev/boddie
Conflicts:
pykolab/setup/setup_roundcube.py
diff --cc pykolab/setup/setup_roundcube.py
index 17592fe,a9d71a2..a7dbbc1
--- a/pykolab/setup/setup_roundcube.py
+++ b/pykolab/setup/setup_roundcube.py
@@@ -57,225 -43,195 +57,226 @@@ def cli_options()
def description():
return _("Setup Roundcube.")
-def execute(*args, **kw):
- print >> sys.stderr, utils.multiline_message(
- _("""
- Please supply a password for the MySQL user 'roundcube'.
- This password will be used by the Roundcube webmail
- interface.
- """)
- )
+def random_digest():
+ return hashlib.md5("%s" % random.random()).digest().encode("base64")
- mysql_roundcube_password = utils.ask_question(
- _("MySQL roundcube password"),
- default=utils.generate_password(),
- password=True,
- confirm=True
- )
+def execute(*args, **kw):
- conf.mysql_roundcube_password = mysql_roundcube_password
-
- rc_settings = {
- 'des_key': re.sub(
- r'[^a-zA-Z0-9]',
- "",
- "%s%s" % (
- hashlib.md5("%s" % random.random()).digest().encode("base64"),
- hashlib.md5("%s" % random.random()).digest().encode("base64")
- )
- )[:24],
-
- 'imap_admin_login': conf.get('cyrus-imap', 'admin_login'),
- 'imap_admin_password': conf.get('cyrus-imap', 'admin_password'),
- 'ldap_base_dn': conf.get('ldap', 'base_dn'),
- 'ldap_group_base_dn': conf.get('ldap', 'group_base_dn'),
- 'ldap_group_filter': conf.get('ldap', 'group_filter'),
- 'ldap_ldap_uri': conf.get('ldap', 'ldap_uri'),
- 'ldap_service_bind_dn': conf.get('ldap', 'service_bind_dn'),
- 'ldap_service_bind_pw': conf.get('ldap', 'service_bind_pw'),
- 'ldap_user_base_dn': conf.get('ldap', 'user_base_dn'),
- 'ldap_user_filter': conf.get('ldap', 'user_filter'),
- 'primary_domain': conf.get('kolab','primary_domain'),
- 'mysql_uri': 'mysqli://roundcube:%s@localhost/roundcube' % (mysql_roundcube_password),
- 'conf': conf
- }
-
-
- want_files = [
- 'acl.inc.php',
- 'calendar.inc.php',
- 'config.inc.php',
- 'kolab_addressbook.inc.php',
- 'kolab_auth.inc.php',
- 'kolab_delegation.inc.php',
- 'kolab_files.inc.php',
- 'kolab_folders.inc.php',
- 'libkolab.inc.php',
- 'managesieve.inc.php',
- 'owncloud.inc.php',
- 'password.inc.php',
- 'recipient_to_contact.inc.php',
- 'terms.html',
- 'terms.inc.php'
- ]
-
- for want_file in want_files:
- template_file = None
- if os.path.isfile('/etc/kolab/templates/roundcubemail/%s.tpl' % (want_file)):
- template_file = '/etc/kolab/templates/roundcubemail/%s.tpl' % (want_file)
- elif os.path.isfile('/usr/share/kolab/templates/roundcubemail/%s.tpl' % (want_file)):
- template_file = '/usr/share/kolab/templates/roundcubemail/%s.tpl' % (want_file)
- elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'roundcubemail', '%s.tpl' % (want_file)))):
- template_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'roundcubemail', '%s.tpl' % (want_file)))
-
- if not template_file == None:
- log.debug(_("Using template file %r") % (template_file), level=8)
- fp = open(template_file, 'r')
- template_definition = fp.read()
- fp.close()
-
- t = Template(template_definition, searchList=[rc_settings])
- log.debug(
- _("Successfully compiled template %r, writing out to %r") % (template_file, want_file),
- level=8
- )
-
- fp = None
- if os.path.isdir('/etc/roundcubemail'):
- fp = open('/etc/roundcubemail/%s' % (want_file), 'w')
- elif os.path.isdir('/etc/roundcube'):
- fp = open('/etc/roundcube/%s' % (want_file), 'w')
-
- if not fp == None:
- fp.write(t.__str__())
- fp.close()
-
- schema_files = []
- for root, directories, filenames in os.walk('/usr/share/doc/'):
- for directory in directories:
- if directory.startswith("roundcubemail"):
- for root, directories, filenames in os.walk(os.path.join(root, directory)):
- for filename in filenames:
- if filename.startswith('mysql.initial') and filename.endswith('.sql'):
- schema_filepath = os.path.join(root,filename)
- if not schema_filepath in schema_files:
- schema_files.append(schema_filepath)
-
- break
- break
-
- if os.path.isdir('/usr/share/roundcubemail'):
- rcpath = '/usr/share/roundcubemail/'
- elif os.path.isdir('/usr/share/roundcube'):
- rcpath = '/usr/share/roundcube/'
- else:
- log.error(_("Roundcube installation path not found."))
- return
-
- for root, directories, filenames in os.walk(rcpath + 'plugins/calendar/drivers/kolab/'):
- for filename in filenames:
- if filename.startswith('mysql') and filename.endswith('.sql'):
- schema_filepath = os.path.join(root,filename)
- if not schema_filepath in schema_files:
- schema_files.append(schema_filepath)
-
- for root, directories, filenames in os.walk(rcpath + 'plugins/libkolab/'):
- for filename in filenames:
- if filename.startswith('mysql') and filename.endswith('.sql'):
- schema_filepath = os.path.join(root,filename)
- if not schema_filepath in schema_files:
- schema_files.append(schema_filepath)
-
- if not os.path.isfile('/tmp/kolab-setup-my.cnf'):
- utils.multiline_message(
- """Please supply the MySQL root password"""
+ # Signal that interaction may occur. This will involve debconf and similar
+ # system-specific mechanisms if available.
+
+ start_interaction("kolab-conf/title-roundcube")
+ try:
+ _execute(*args, **kw)
+ finally:
+ stop_interaction()
+
+def _execute(*args, **kw):
+
+ # Stop if MySQL is not actually installed.
+
+ if not have_mysql():
+ if conf.check_only:
+ utils.setup_status("roundcube", _("needs setup"))
+ return
+ else:
+ print >> sys.stderr, _("MySQL not installed: cannot initialise Roundcube.")
+ sys.exit(1)
+
+ # Obtain an SMTP server.
+
+ smtp_host = conf.get('smtp', 'host')
+
+ if not smtp_host:
+ if conf.check_only:
+ utils.setup_status("roundcube", _("needs setup"))
+ return
+
+ smtp_host = ask_question("kolab-conf/smtp-server-selection",
+ _("""
+ Please indicate the SMTP server to be used by the Kolab
+ components. (If this is a remote server, no attempt will
+ be made to set up server instances or to configure
+ services.)
+ """),
+ _("SMTP server host"),
+ default="localhost"
)
- mysql_root_password = utils.ask_question(
- _("MySQL root password"),
- password=True
- )
+ # Use the existing root credentials.
- data = """
-[mysql]
-user=root
-password='%s'
-""" % (mysql_root_password)
+ defaults_file = get_mysql_defaults()
- fp = open('/tmp/kolab-setup-my.cnf', 'w')
- os.chmod('/tmp/kolab-setup-my.cnf', 0600)
- fp.write(data)
- fp.close()
+ if not isfile(defaults_file):
+ if conf.check_only:
+ utils.setup_status("roundcube", _("needs setup"))
+ return
+ make_mysql_defaults_file(defaults_file)
- p1 = subprocess.Popen(['echo', 'create database roundcube;'], stdout=subprocess.PIPE)
- p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout)
- p1.stdout.close()
- p2.communicate()
+ # Test for a MySQL database.
- p1 = subprocess.Popen(['echo', 'GRANT ALL PRIVILEGES ON roundcube.* TO \'roundcube\'@\'localhost\' IDENTIFIED BY \'%s\';' % (mysql_roundcube_password)], stdout=subprocess.PIPE)
- p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout)
- p1.stdout.close()
- p2.communicate()
+ if not have_mysql_database(defaults_file, 'roundcube'):
+ if conf.check_only:
+ utils.setup_status("roundcube", _("needs setup"))
+ return
- for schema_file in schema_files:
- p1 = subprocess.Popen(['cat', schema_file], stdout=subprocess.PIPE)
- p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf', 'roundcube'], stdin=p1.stdout)
- p1.stdout.close()
- p2.communicate()
+ # Gather schema files for database initialisation.
+
+ rcpath = get_roundcube_resources()
+
+ if not rcpath:
+ log.error(_("Roundcube installation path not found."))
+ return
+
+ # Retain the ordering.
+
+ schema_files = []
+
+ for roundcube_dir in glob('/usr/share/doc/roundcubemail*'):
+ for root, directories, filenames in os.walk(roundcube_dir):
+ for filename in filenames:
+ if filename.startswith('mysql.initial') and filename.endswith('.sql'):
+ schema_files.append(join(root,filename))
- p1 = subprocess.Popen(['echo', 'FLUSH PRIVILEGES;'], stdout=subprocess.PIPE)
- p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout)
- p1.stdout.close()
- p2.communicate()
+ for search_root in [
+ join(rcpath, 'plugins/calendar/drivers/kolab/'),
+ join(rcpath, 'plugins/libkolab/')
+ ]:
- time.sleep(2)
+ for root, directories, filenames in os.walk(search_root):
+ for filename in filenames:
+ if filename.startswith('mysql') and filename.endswith('.sql'):
+ schema_files.append(join(root,filename))
- if os.path.isfile('/bin/systemctl'):
- subprocess.call(['/bin/systemctl', 'restart', 'httpd.service'])
- elif os.path.isfile('/sbin/service'):
- subprocess.call(['/sbin/service', 'httpd', 'restart'])
- elif os.path.isfile('/usr/sbin/service'):
- subprocess.call(['/usr/sbin/service','apache2','restart'])
+ # Create the database.
+
+ call(['mysql', '--defaults-file=%s' % defaults_file, '-e', 'create database roundcube'])
+
+ # Apply each schema file.
+ # MySQL does not have a read-from-file option as such.
+
+ for schema_file in schema_files:
+ p1 = Popen(['cat', schema_file], stdout=PIPE)
+ p2 = Popen(['mysql', '--defaults-file=%s' % defaults_file, 'roundcube'], stdin=p1.stdout)
+ p2.communicate()
+
+ # Test for a MySQL user. Reset the user and configuration if explicitly
+ # requested.
+
+ if have_mysql_user(defaults_file, 'roundcube') and not conf.reset_roundcube_config:
+ if not conf.check_only:
+ print >> sys.stderr, _("Roundcube database account already exists and will not be configured.")
+ log.info(_("A user called %s already exists. Not creating another one.") % 'roundcube')
else:
- log.error(_("Could not start the webserver server service."))
-
- if os.path.isfile('/bin/systemctl'):
- subprocess.call(['/bin/systemctl', 'enable', 'httpd.service'])
- elif os.path.isfile('/sbin/chkconfig'):
- subprocess.call(['/sbin/chkconfig', 'httpd', 'on'])
- elif os.path.isfile('/usr/sbin/update-rc.d'):
- subprocess.call(['/usr/sbin/update-rc.d', 'apache2', 'defaults'])
+ if conf.check_only:
+ utils.setup_status("roundcube", _("needs setup"))
+ return
+
+ mysql_roundcube_password = ask_question("kolab-conf/roundcube-password",
+ _("""
+ Please supply a password for the MySQL user 'roundcube'.
+ This password will be used by the Roundcube webmail
+ interface.
+ """),
+ _("MySQL roundcube password"),
+ default=utils.generate_password(),
+ password=True,
+ confirm=True
+ )
+
+ conf.mysql_roundcube_password = mysql_roundcube_password
+
+ # Send the password details via a pipe to avoid leakage via the process list.
+
+ p1 = Popen(['echo', "grant all privileges on roundcube.* to 'roundcube'@'localhost' identified by '%s'" %
+ mysql_roundcube_password.replace("'", "''")], stdout=PIPE)
+ p2 = Popen(['mysql', '--defaults-file=%s' % defaults_file], stdin=p1.stdout)
+ p2.communicate()
+
+ call(['mysql', '--defaults-file=%s' % defaults_file, '-e', 'flush privileges'])
+
+ # Write out the settings including the password details.
+
+ rc_settings = {
+ 'des_key': re.sub(
+ r'[^a-zA-Z0-9]',
+ "",
+ "%s%s" % (random_digest(), random_digest())
+ )[:24],
+
+ 'imap_admin_login': conf.get('cyrus-imap', 'admin_login'),
+ 'imap_admin_password': conf.get('cyrus-imap', 'admin_password'),
+ 'ldap_base_dn': conf.get('ldap', 'base_dn'),
+ 'ldap_group_base_dn': conf.get('ldap', 'group_base_dn'),
+ 'ldap_group_filter': conf.get('ldap', 'group_filter'),
+ 'ldap_ldap_uri': conf.get('ldap', 'ldap_uri'),
+ 'ldap_service_bind_dn': conf.get('ldap', 'service_bind_dn'),
+ 'ldap_service_bind_pw': conf.get('ldap', 'service_bind_pw'),
+ 'ldap_user_base_dn': conf.get('ldap', 'user_base_dn'),
+ 'ldap_user_filter': conf.get('ldap', 'user_filter'),
+ 'primary_domain': conf.get('kolab','primary_domain'),
+ 'mysql_uri': 'mysqli://roundcube:%s@localhost/roundcube' % (mysql_roundcube_password),
+ 'ldap_host': get_host_from_url(conf.get('ldap', 'ldap_uri')),
+ 'imap_host': get_host_from_url(conf.get('cyrus-imap', 'uri')),
+ 'smtp_host': smtp_host,
+ 'conf': conf,
+ }
+
+ want_files = [
+ 'acl.inc.php',
+ 'calendar.inc.php',
+ 'config.inc.php',
++ 'kolab_addressbook.inc.php',
+ 'kolab_auth.inc.php',
+ 'kolab_delegation.inc.php',
+ 'kolab_files.inc.php',
+ 'kolab_folders.inc.php',
+ 'libkolab.inc.php',
+ 'managesieve.inc.php',
+ 'owncloud.inc.php',
+ 'password.inc.php',
+ 'recipient_to_contact.inc.php',
+ 'terms.html',
+ 'terms.inc.php'
+ ]
+
+ for want_file in want_files:
+ template_file = get_template_path('roundcubemail/%s.tpl' % want_file)
+ roundcube_dir = get_roundcube_config()
+
+ if roundcube_dir:
+ output_file = join(roundcube_dir, want_file)
+ else:
+ output_file = None
+
+ if template_file is not None and output_file is not None:
+ log.debug(_("Using template file %r") % (template_file), level=8)
+ instantiate_template(template_file, output_file, [rc_settings])
+
+ # If nothing needed updating, assume that the setup was done.
+
+ if conf.check_only:
+ utils.setup_status("roundcube", _("setup done"))
+
else:
- log.error(_("Could not configure to start on boot, the " + \
- "webserver server service."))
+ # Update the configuration file.
+
+ if not conf.has_section('smtp'):
+ conf.add_section('smtp')
+ conf.command_set('smtp', 'host', smtp_host)
+
+ fp = open(conf.defaults.config_file, "w+")
+ conf.cfg_parser.write(fp)
+ fp.close()
+
+ # Restart the Web server.
+
+ time.sleep(2)
+
+ apache = is_debian() and "apache2" or "httpd"
+ if not control_service(apache, 'restart'):
+ log.error(_("Could not start the webserver service."))
+ if not configure_service(apache, True):
+ log.error(_("Could not configure to start on boot, the " + \
+ "webserver service."))
commit c7c17c997481b817a42cc8c44d62f4c77d231f22
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Apr 23 17:54:57 2014 -0400
Add kolabd plugin to cleanup Roundcube's database after deleting a Kolab user from LDAP
diff --git a/pykolab/auth/ldap/__init__.py b/pykolab/auth/ldap/__init__.py
index c0c3297..8379c0c 100644
--- a/pykolab/auth/ldap/__init__.py
+++ b/pykolab/auth/ldap/__init__.py
@@ -1436,6 +1436,15 @@ class LDAP(pykolab.base.Base):
self.imap.user_mailbox_delete(entry[result_attribute])
self.imap.cleanup_acls(entry[result_attribute])
+ # let plugins act upon this deletion
+ conf.plugins.exec_hook(
+ 'user_delete',
+ kw = {
+ 'user': entry,
+ 'domain': self.domain
+ }
+ )
+
def _change_moddn_group(self, entry, change):
# TODO: If the rdn attribute is the same as the result attribute...
pass
diff --git a/pykolab/plugins/roundcubedb/__init__.py b/pykolab/plugins/roundcubedb/__init__.py
new file mode 100644
index 0000000..a7f289e
--- /dev/null
+++ b/pykolab/plugins/roundcubedb/__init__.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+# Copyright 2014 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Thomas Bruederli (Kolab Systems) <bruederli(a)kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 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 Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import os
+import pykolab
+import subprocess
+
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.plugins.roundcubedb')
+conf = pykolab.getConf()
+
+class KolabRoundcubedb(object):
+ """
+ Pykolab plugin to update Roundcube's database on Kolab users db changes
+ """
+
+ def __init__(self):
+ pass
+
+ def add_options(self, *args, **kw):
+ pass
+
+ def user_delete(self, *args, **kw):
+ """
+ The arguments passed to the 'user_delete' hook:
+
+ user - full user entry from LDAP
+ domain - domain name
+ """
+
+ log.debug(_("user_delete: %r") % (kw), level=9)
+
+ if os.path.isdir('/usr/share/roundcubemail'):
+ rcpath = '/usr/share/roundcubemail/'
+ elif os.path.isdir('/usr/share/roundcube'):
+ rcpath = '/usr/share/roundcube/'
+ else:
+ log.error(_("Roundcube installation path not found."))
+ return False
+
+ result_attribute = conf.get('cyrus-sasl', 'result_attribute')
+
+ # execute Roundcube's bin/deluser.sh script to do the work
+ if kw.has_key('user') and kw['user'].has_key(result_attribute) and os.path.exists(rcpath + 'bin/deluser.sh'):
+ proc = subprocess.Popen([ 'sudo -u apache', rcpath + 'bin/deluser.sh', kw['user'][result_attribute] ], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+ procout, procerr = proc.communicate()
+ if proc.returncode != 0:
+ log.error(rcpath + "bin/deluser.sh exited with error %d: %r" % (proc.returncode, procerr))
+ else:
+ log.debug(rcpath + "bin/deluser.sh success: %r; %r" % (procout, procerr), level=9)
+
+ return None
commit fa3076751a06dc0b9d648719e517619d61e9e03d
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date: Sat Apr 5 18:39:13 2014 +0200
Add CardDAV URL to Kolab address books by default
diff --git a/pykolab/setup/setup_roundcube.py b/pykolab/setup/setup_roundcube.py
index 4e14ee2..a9d71a2 100644
--- a/pykolab/setup/setup_roundcube.py
+++ b/pykolab/setup/setup_roundcube.py
@@ -91,6 +91,7 @@ def execute(*args, **kw):
'acl.inc.php',
'calendar.inc.php',
'config.inc.php',
+ 'kolab_addressbook.inc.php',
'kolab_auth.inc.php',
'kolab_delegation.inc.php',
'kolab_files.inc.php',
commit 5be79d51d78fbf9a7c3c9ab60a6fe23d9660e309
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date: Sat Apr 5 18:37:03 2014 +0200
Add CalDAV URL to calendars by default
diff --git a/share/templates/roundcubemail/calendar.inc.php.tpl b/share/templates/roundcubemail/calendar.inc.php.tpl
index b119f7b..4761566 100644
--- a/share/templates/roundcubemail/calendar.inc.php.tpl
+++ b/share/templates/roundcubemail/calendar.inc.php.tpl
@@ -7,6 +7,7 @@
\$config['calendar_work_start'] = 6;
\$config['calendar_work_end'] = 18;
\$config['calendar_event_coloring'] = 0;
+ \$config['calendar_caldav_url'] = 'http://' . \$_SERVER['HTTP_HOST'] . '/iRony/calendars/%u/%i';
if (file_exists(RCUBE_CONFIG_DIR . '/' . \$_SERVER["HTTP_HOST"] . '/' . basename(__FILE__))) {
include_once(RCUBE_CONFIG_DIR . '/' . \$_SERVER["HTTP_HOST"] . '/' . basename(__FILE__));
commit 380315b1d8b4b29cbf97b8aff9f59b78335849e1
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date: Sat Apr 5 18:35:57 2014 +0200
Add vacation interface by default
diff --git a/share/templates/roundcubemail/managesieve.inc.php.tpl b/share/templates/roundcubemail/managesieve.inc.php.tpl
index c05a096..0e44079 100644
--- a/share/templates/roundcubemail/managesieve.inc.php.tpl
+++ b/share/templates/roundcubemail/managesieve.inc.php.tpl
@@ -10,6 +10,7 @@
\$config['managesieve_replace_delimiter'] = '';
\$config['managesieve_disabled_extensions'] = array();
\$config['managesieve_debug'] = true;
+ \$config['managesieve_vacation'] = 1;
if (file_exists(RCUBE_CONFIG_DIR . '/' . \$_SERVER["HTTP_HOST"] . '/' . basename(__FILE__))) {
include_once(RCUBE_CONFIG_DIR . '/' . \$_SERVER["HTTP_HOST"] . '/' . basename(__FILE__));
More information about the commits
mailing list