diff --git a/docker-compose.yml b/docker-compose.yml index 40e69af9..2fa88e70 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,244 +1,295 @@ version: '3' services: coturn: build: context: ./docker/coturn/ container_name: kolab-coturn healthcheck: interval: 10s test: "kill -0 $$(cat /tmp/turnserver.pid)" timeout: 5s retries: 30 environment: - TURN_PUBLIC_IP=${COTURN_PUBLIC_IP} - TURN_LISTEN_PORT=3478 - TURN_STATIC_SECRET=${COTURN_STATIC_SECRET} hostname: sturn.mgmt.com image: kolab-coturn network_mode: host restart: on-failure tty: true kolab: build: context: ./docker/kolab/ args: DB_KOLAB_DATABASE: kolab DB_KOLAB_USERNAME: kolab DB_KOLAB_PASSWORD: ${DB_PASSWORD:?"DB_PASSWORD is missing"} container_name: kolab privileged: true depends_on: mariadb: condition: service_healthy pdns: condition: service_healthy extra_hosts: - "kolab.mgmt.com:127.0.0.1" - "services.${APP_DOMAIN}:172.18.0.4" environment: - APP_DOMAIN=${APP_DOMAIN} - LDAP_HOST=127.0.0.1 - LDAP_ADMIN_BIND_DN=${LDAP_ADMIN_BIND_DN} - LDAP_ADMIN_BIND_PW=${LDAP_ADMIN_BIND_PW} - LDAP_SERVICE_BIND_PW=${LDAP_SERVICE_BIND_PW} - LDAP_HOSTED_BIND_PW=${LDAP_HOSTED_BIND_PW} - DB_HOST=mariadb - DB_ROOT_PASSWORD=${DB_ROOT_PASSWORD} - DB_HKCCP_DATABASE=${DB_DATABASE} - DB_HKCCP_USERNAME=${DB_USERNAME} - DB_HKCCP_PASSWORD=${DB_PASSWORD:?"DB_PASSWORD is missing"} - DB_KOLAB_DATABASE=kolab - DB_KOLAB_USERNAME=kolab - DB_KOLAB_PASSWORD=${DB_PASSWORD:?"DB_PASSWORD is missing"} - - DB_RC_USERNAME=roundcube - - DB_RC_PASSWORD=${DB_PASSWORD:?"DB_PASSWORD is missing"} - SSL_CERTIFICATE=${KOLAB_SSL_CERTIFICATE:?"KOLAB_SSL_CERTIFICATE is missing"} - SSL_CERTIFICATE_FULLCHAIN=${KOLAB_SSL_CERTIFICATE_FULLCHAIN:?"KOLAB_SSL_CERTIFICATE_FULLCHAIN is missing"} - SSL_CERTIFICATE_KEY=${KOLAB_SSL_CERTIFICATE_KEY:?"KOLAB_SSL_CERTIFICATE_KEY is missing"} - IMAP_HOST=127.0.0.1 - IMAP_PORT=11993 - IMAP_ADMIN_LOGIN=${IMAP_ADMIN_LOGIN} - IMAP_ADMIN_PASSWORD=${IMAP_ADMIN_PASSWORD} - MAIL_HOST=127.0.0.1 - MAIL_PORT=10587 healthcheck: interval: 10s test: "systemctl is-active kolab-init || exit 1" timeout: 5s retries: 30 start_period: 5m # This makes docker's dns, resolve via pdns for this container. # Please note it does not affect /etc/resolv.conf dns: 172.18.0.11 hostname: kolab.mgmt.com image: kolab networks: kolab: ipv4_address: 172.18.0.5 ports: - "12143:12143" tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - ./ext/:/src/:ro - /etc/letsencrypt/:/etc/letsencrypt/:ro - ./docker/certs/ca.cert:/etc/pki/tls/certs/ca.cert:ro - ./docker/certs/ca.cert:/etc/pki/ca-trust/source/anchors/ca.cert:ro - ./docker/certs/kolab.hosted.com.cert:${KOLAB_SSL_CERTIFICATE:?err} - ./docker/certs/kolab.hosted.com.chain.pem:${KOLAB_SSL_CERTIFICATE_FULLCHAIN:?err} - ./docker/certs/kolab.hosted.com.key:${KOLAB_SSL_CERTIFICATE_KEY:?err} - ./docker/kolab/utils:/root/utils:ro - /sys/fs/cgroup:/sys/fs/cgroup:ro - imap:/imapdata - ldap:/ldapdata + roundcube: + build: + context: ./docker/roundcube/ + container_name: roundcube + hostname: roundcube.hosted.com + depends_on: + mariadb: + condition: service_healthy + pdns: + condition: service_healthy + kolab: + condition: service_healthy + environment: + - APP_DOMAIN=${APP_DOMAIN} + - LDAP_HOST=kolab + - LDAP_ADMIN_BIND_DN=${LDAP_ADMIN_BIND_DN} + - LDAP_ADMIN_BIND_PW=${LDAP_ADMIN_BIND_PW} + - LDAP_SERVICE_BIND_PW=${LDAP_SERVICE_BIND_PW} + - LDAP_HOSTED_BIND_PW=${LDAP_HOSTED_BIND_PW} + - DB_HOST=mariadb + - DB_ROOT_PASSWORD=${DB_ROOT_PASSWORD} + - DB_RC_DATABASE=roundcube + - DB_RC_USERNAME=roundcube + - DB_RC_PASSWORD=${DB_PASSWORD:?"DB_PASSWORD is missing"} + - IMAP_HOST=tls://haproxy + - IMAP_PORT=145 + - IMAP_ADMIN_LOGIN=${IMAP_ADMIN_LOGIN} + - IMAP_ADMIN_PASSWORD=${IMAP_ADMIN_PASSWORD} + - MAIL_HOST=tls://kolab + - MAIL_PORT=10587 + healthcheck: + interval: 10s + test: "kill -0 $$(cat /run/httpd/httpd.pid)" + timeout: 5s + retries: 30 + # This makes docker's dns, resolve via pdns for this container. + # Please note it does not affect /etc/resolv.conf + dns: 172.18.0.11 + image: roundcube + networks: + kolab: + ipv4_address: 172.18.0.9 + ports: + - "8001:80" + tmpfs: + - /run + - /tmp + - /var/run + - /var/tmp + volumes: + - ./ext/:/src.orig/:ro mariadb: container_name: kolab-mariadb environment: - MARIADB_ROOT_PASSWORD=${DB_ROOT_PASSWORD} - TZ="+02:00" - DB_HKCCP_DATABASE=${DB_DATABASE} - DB_HKCCP_USERNAME=${DB_USERNAME} - DB_HKCCP_PASSWORD=${DB_PASSWORD} healthcheck: interval: 10s test: test -e /var/run/mysqld/mysqld.sock timeout: 5s retries: 30 image: mariadb:latest networks: - kolab volumes: - ./docker/mariadb/mysql-init/:/docker-entrypoint-initdb.d/ - mariadb:/var/lib/mysql haproxy: build: context: ./docker/haproxy/ healthcheck: interval: 10s test: "kill -0 $$(cat /var/run/haproxy.pid)" timeout: 5s retries: 30 container_name: kolab-haproxy hostname: haproxy.hosted.com image: kolab-haproxy networks: - kolab tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - ./docker/certs/:/etc/certs/:ro - /etc/letsencrypt/:/etc/letsencrypt/:ro pdns: build: context: ./docker/pdns/ args: DB_HOST: mariadb DB_DATABASE: ${DB_DATABASE:?DB_DATABASE} DB_USERNAME: ${DB_USERNAME:?DB_USERNAME} DB_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD} container_name: kolab-pdns hostname: pdns depends_on: mariadb: condition: service_healthy healthcheck: interval: 10s test: "systemctl status pdns || exit 1" timeout: 5s retries: 30 image: kolab-pdns networks: kolab: ipv4_address: 172.18.0.11 tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - /sys/fs/cgroup:/sys/fs/cgroup:ro redis: build: context: ./docker/redis/ healthcheck: interval: 10s test: "redis-cli ping || exit 1" timeout: 5s retries: 30 container_name: kolab-redis hostname: redis image: redis networks: - kolab volumes: - ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro webapp: build: context: ./docker/webapp/ container_name: kolab-webapp image: kolab-webapp healthcheck: interval: 10s test: "/src/kolabsrc/artisan octane:status || exit 1" timeout: 5s retries: 30 start_period: 5m depends_on: kolab: condition: service_healthy redis: condition: service_healthy + roundcube: + condition: service_healthy networks: kolab: ipv4_address: 172.18.0.4 volumes: - ./src:/src/kolabsrc.orig:ro ports: - "8000:8000" meet: build: context: ./docker/meet/ healthcheck: interval: 10s test: "curl --insecure -H 'X-AUTH-TOKEN: ${MEET_SERVER_TOKEN}' --fail https://${MEET_LISTENING_HOST}:12443/meetmedia/api/health || exit 1" timeout: 5s retries: 30 start_period: 5m environment: - WEBRTC_LISTEN_IP=${MEET_WEBRTC_LISTEN_IP:?err} - PUBLIC_DOMAIN=${MEET_PUBLIC_DOMAIN:?err} - LISTENING_HOST=${MEET_LISTENING_HOST:?err} - LISTENING_PORT=12443 - TURN_SERVER=${MEET_TURN_SERVER} - TURN_STATIC_SECRET=${COTURN_STATIC_SECRET} - AUTH_TOKEN=${MEET_SERVER_TOKEN:?err} - WEBHOOK_TOKEN=${MEET_WEBHOOK_TOKEN:?err} - WEBHOOK_URL=${APP_PUBLIC_URL:?err}/api/webhooks/meet - SSL_CERT=/etc/pki/tls/certs/meet.${APP_WEBSITE_DOMAIN:?err}.cert - SSL_KEY=/etc/pki/tls/private/meet.${APP_WEBSITE_DOMAIN:?err}.key network_mode: host container_name: kolab-meet image: kolab-meet volumes: - ./meet/server:/src/meet/:ro - ./docker/certs/meet.${APP_WEBSITE_DOMAIN}.cert:/etc/pki/tls/certs/meet.${APP_WEBSITE_DOMAIN}.cert - ./docker/certs/meet.${APP_WEBSITE_DOMAIN}.key:/etc/pki/tls/private/meet.${APP_WEBSITE_DOMAIN}.key networks: kolab: driver: bridge ipam: config: - subnet: "172.18.0.0/24" volumes: mariadb: imap: ldap: diff --git a/docker/roundcube/Dockerfile b/docker/roundcube/Dockerfile new file mode 100644 index 00000000..a229c9d1 --- /dev/null +++ b/docker/roundcube/Dockerfile @@ -0,0 +1,79 @@ +FROM quay.io/centos/centos:stream9 + +MAINTAINER Christian Mollekopf + +ENV HOME=/opt/app-root/src + +LABEL io.k8s.description="Platform for serving PHP roundcube applications" \ + io.k8s.display-name="Roundcube" \ + io.openshift.expose-services="80:http" \ + io.openshift.tags="builder,php,apache" + +#FIXME switch to centos9 because we need the php extensions for libkolabxml and libkolab +RUN dnf -y update + +# Add EPEL. +RUN dnf -y install 'dnf-command(config-manager)' && \ + dnf config-manager --set-enabled crb && \ + dnf -y install \ + epel-release epel-next-release && \ + dnf clean all + +# Add the EPEL key. +RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9 + + +# Add kolab +RUN rpm --import https://mirror.apheleia-it.ch/repos/Kolab:/16/key.asc && \ + rpm -Uvh https://mirror.apheleia-it.ch/repos/Kolab:/16/kolab-16-for-el9stream.rpm + +# Install php modules +RUN sed -i -e '/^ssl/d' /etc/yum.repos.d/kolab*.repo && \ + dnf config-manager --enable kolab-16-testing &&\ + dnf -y --setopt tsflags= install php-kolab php-kolabformat &&\ + dnf clean all + +RUN dnf -y install \ + composer \ + diffutils \ + file \ + git \ + make \ + unzip \ + curl-minimal \ + mariadb \ + which \ + rsync \ + openssl-devel \ + httpd \ + patch \ + php-cli \ + php-common \ + php-devel \ + php-ldap \ + php-opcache \ + php-pecl-apcu \ + php-mysqlnd \ + php-gd \ + php-fpm \ + php-pear \ + ImageMagick \ + re2c \ + npm \ + wget && \ + dnf clean all + + +RUN npm install -g less less-plugin-clean-css + +WORKDIR ${HOME} + +COPY /rootfs / +RUN /opt/app-root/src/build.sh + +EXPOSE 80 + +# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop +STOPSIGNAL SIGWINCH + +CMD [ "/opt/app-root/src/init.sh" ] diff --git a/docker/roundcube/rootfs/etc/httpd/conf.d/chwala.conf b/docker/roundcube/rootfs/etc/httpd/conf.d/chwala.conf new file mode 100644 index 00000000..2ef5d6ae --- /dev/null +++ b/docker/roundcube/rootfs/etc/httpd/conf.d/chwala.conf @@ -0,0 +1,33 @@ +Alias /chwala /opt/app-root/src/chwala/public_html + + + AllowOverride None + +# php_flag session.auto_start Off +# php_flag display_errors Off +# php_flag log_errors On +# php_flag suhosin.session.encrypt Off +# php_value error_log /var/log/chwala/errors + + + # Apache 2.4 + Require all granted + + + # Apache 2.2 + Order Allow,Deny + Allow from All + + + + RewriteEngine on + # NOTE: This needs to point to the base uri of your installation. + RewriteBase /chwala/ + + # Rewrite document URLs of the form api/document/:id to api/index.php?method=document&id=:id + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^api/document/(.*)$ api/index.php?method=document&id=$1 [L,QSA] + RewriteRule ^api/wopi/(.*)$ api/index.php?wopi=1&method=$1 [L,QSA] + + diff --git a/docker/roundcube/rootfs/etc/httpd/conf.d/freebusy.conf b/docker/roundcube/rootfs/etc/httpd/conf.d/freebusy.conf new file mode 100644 index 00000000..abf30797 --- /dev/null +++ b/docker/roundcube/rootfs/etc/httpd/conf.d/freebusy.conf @@ -0,0 +1,13 @@ +ScriptAlias /freebusy /opt/app-root/src/freebusy/public_html/index.php + + + AllowOverride All + + + Require all granted + + + Order Allow,Deny + Allow from All + + diff --git a/docker/roundcube/rootfs/etc/httpd/conf.d/iRony.conf b/docker/roundcube/rootfs/etc/httpd/conf.d/iRony.conf new file mode 100644 index 00000000..25e9183a --- /dev/null +++ b/docker/roundcube/rootfs/etc/httpd/conf.d/iRony.conf @@ -0,0 +1,25 @@ +Alias /iRony /opt/app-root/src/iRony/public_html + + + AllowOverride All + + + # Apache 2.4 + Require all granted + + + # Apache 2.2 + Order Allow,Deny + Allow from All + + + RewriteEngine On + RewriteBase /iRony/ + RewriteRule ^\.well-known/caldav / [R,L] + RewriteRule ^\.well-known/carddav / [R,L] + + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule (.*) index.php [qsappend,last] + + diff --git a/docker/roundcube/rootfs/etc/httpd/conf.d/kolab-autoconf.conf b/docker/roundcube/rootfs/etc/httpd/conf.d/kolab-autoconf.conf new file mode 100644 index 00000000..abf32a2b --- /dev/null +++ b/docker/roundcube/rootfs/etc/httpd/conf.d/kolab-autoconf.conf @@ -0,0 +1,19 @@ +# for https://domain.tld (and https://autodiscover.domain.tld) +Alias /autodiscover/autodiscover.xml /opt/app-root/src/autoconf/public_html/index.php +Alias /Autodiscover/Autodiscover.xml /opt/app-root/src/autoconf/public_html/index.php +Alias /AutoDiscover/AutoDiscover.xml /opt/app-root/src/autoconf/public_html/index.php +# for http://autoconfig.domain.tld +Alias /mail/config-v1.1.xml /opt/app-root/src/autoconf/public_html/index.php +# for http://domain.tld +Alias /.well-known/autoconfig/mail/config-v1.1.xml /opt/app-root/src/autoconf/public_html/index.php + + + AllowOverride None + + Require all granted + + + Order Allow,Deny + Allow from All + + diff --git a/docker/roundcube/rootfs/etc/httpd/conf.d/kolab-syncroton.conf b/docker/roundcube/rootfs/etc/httpd/conf.d/kolab-syncroton.conf new file mode 100644 index 00000000..11e95fda --- /dev/null +++ b/docker/roundcube/rootfs/etc/httpd/conf.d/kolab-syncroton.conf @@ -0,0 +1,44 @@ +ScriptAlias /Microsoft-Server-ActiveSync /opt/app-root/src/syncroton/index.php + + + AllowOverride All + + Require all granted + + + Order Allow,Deny + Allow from All + + + + + Options -FollowSymLinks + + Require all denied + + + Order Deny,Allow + Deny from All + + + + + + Require all denied + + + Order Deny,Allow + Deny from All + + + + + Options -FollowSymLinks + + Require all denied + + + Order Deny,Allow + Deny from All + + diff --git a/docker/roundcube/rootfs/etc/httpd/conf.d/roundcubemail.conf b/docker/roundcube/rootfs/etc/httpd/conf.d/roundcubemail.conf new file mode 100644 index 00000000..ec5b8e36 --- /dev/null +++ b/docker/roundcube/rootfs/etc/httpd/conf.d/roundcubemail.conf @@ -0,0 +1,30 @@ +Alias /roundcubemail /opt/app-root/src/roundcubemail/public_html/ +Alias /webmail /opt/app-root/src/roundcubemail/public_html/ + + + + SetEnv no-gzip + + + ExpiresActive On + ExpiresDefault "access plus 1 month" + + + + + Options +FollowSymLinks + AllowOverride None + + + RewriteEngine On + RewriteCond %{REQUEST_URI} ^/(roundcubemail|webmail) + RewriteRule ^[a-zA-Z0-9]{16}/(.*) /%1/$1 [PT,L] + + + Require all granted + + + Order Allow,Deny + Allow from All + + diff --git a/docker/roundcube/rootfs/etc/httpd/conf/httpd.conf b/docker/roundcube/rootfs/etc/httpd/conf/httpd.conf new file mode 100644 index 00000000..be4e3b53 --- /dev/null +++ b/docker/roundcube/rootfs/etc/httpd/conf/httpd.conf @@ -0,0 +1,358 @@ +# +# This is the main Apache HTTP server configuration file. It contains the +# configuration directives that give the server its instructions. +# See for detailed information. +# In particular, see +# +# for a discussion of each configuration directive. +# +# See the httpd.conf(5) man page for more information on this configuration, +# and httpd.service(8) on using and configuring the httpd service. +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# +# Configuration and logfile names: If the filenames you specify for many +# of the server's control files begin with "/" (or "drive:/" for Win32), the +# server will use that explicit path. If the filenames do *not* begin +# with "/", the value of ServerRoot is prepended -- so 'log/access_log' +# with ServerRoot set to '/www' will be interpreted by the +# server as '/www/log/access_log', where as '/log/access_log' will be +# interpreted as '/log/access_log'. + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# Do not add a slash at the end of the directory path. If you point +# ServerRoot at a non-local disk, be sure to specify a local disk on the +# Mutex directive, if file-based mutexes are used. If you wish to share the +# same ServerRoot for multiple httpd daemons, you will need to change at +# least PidFile. +# +ServerRoot "/etc/httpd" + +# +# Listen: Allows you to bind Apache to specific IP addresses and/or +# ports, instead of the default. See also the +# directive. +# +# Change this to Listen on a specific IP address, but note that if +# httpd.service is enabled to run at boot time, the address may not be +# available when the service starts. See the httpd.service(8) man +# page for more information. +# +#Listen 12.34.56.78:80 +Listen 80 + +# +# Dynamic Shared Object (DSO) Support +# +# To be able to use the functionality of a module which was built as a DSO you +# have to place corresponding `LoadModule' lines at this location so the +# directives contained in it are actually available _before_ they are used. +# Statically compiled modules (those listed by `httpd -l') do not need +# to be loaded here. +# +# Example: +# LoadModule foo_module modules/mod_foo.so +# +Include conf.modules.d/*.conf + +# +# If you wish httpd to run as a different user or group, you must run +# httpd as root initially and it will switch. +# +# User/Group: The name (or #number) of the user/group to run httpd as. +# It is usually good practice to create a dedicated user and group for +# running httpd, as with most system services. +# +User apache +Group apache + +# 'Main' server configuration +# +# The directives in this section set up the values used by the 'main' +# server, which responds to any requests that aren't handled by a +# definition. These values also provide defaults for +# any containers you may define later in the file. +# +# All of these directives may appear inside containers, +# in which case these default settings will be overridden for the +# virtual host being defined. +# + +# +# ServerAdmin: Your address, where problems with the server should be +# e-mailed. This address appears on some server-generated pages, such +# as error documents. e.g. admin@your-domain.com +# +ServerAdmin root@localhost + +# +# ServerName gives the name and port that the server uses to identify itself. +# This can often be determined automatically, but we recommend you specify +# it explicitly to prevent problems during startup. +# +# If your host doesn't have a registered DNS name, enter its IP address here. +# +#ServerName www.example.com:80 + +# +# Deny access to the entirety of your server's filesystem. You must +# explicitly permit access to web content directories in other +# blocks below. +# + + AllowOverride none + Require all denied + + +# +# Note that from this point forward you must specifically allow +# particular features to be enabled - so if something's not working as +# you might expect, make sure that you have specifically enabled it +# below. +# + +# +# DocumentRoot: The directory out of which you will serve your +# documents. By default, all requests are taken from this directory, but +# symbolic links and aliases may be used to point to other locations. +# +DocumentRoot "/var/www/html" + +# +# Relax access to content within /var/www. +# + + AllowOverride None + # Allow open access: + Require all granted + + +# Further relax access to the default document root: + + # + # Possible values for the Options directive are "None", "All", + # or any combination of: + # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews + # + # Note that "MultiViews" must be named *explicitly* --- "Options All" + # doesn't give it to you. + # + # The Options directive is both complicated and important. Please see + # http://httpd.apache.org/docs/2.4/mod/core.html#options + # for more information. + # + Options Indexes FollowSymLinks + + # + # AllowOverride controls what directives may be placed in .htaccess files. + # It can be "All", "None", or any combination of the keywords: + # Options FileInfo AuthConfig Limit + # + AllowOverride None + + # + # Controls who can get stuff from this server. + # + Require all granted + + +# +# DirectoryIndex: sets the file that Apache will serve if a directory +# is requested. +# + + DirectoryIndex index.html + + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Require all denied + + +# +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog "logs/error_log" + +# +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + + + # + # The following directives define some format nicknames for use with + # a CustomLog directive (see below). + # + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%h %l %u %t \"%r\" %>s %b" common + + + # You need to enable mod_logio.c to use %I and %O + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + + + # + # The location and format of the access logfile (Common Logfile Format). + # If you do not define any access logfiles within a + # container, they will be logged here. Contrariwise, if you *do* + # define per- access logfiles, transactions will be + # logged therein and *not* in this file. + # + #CustomLog "logs/access_log" common + + # + # If you prefer a logfile with access, agent, and referer information + # (Combined Logfile Format) you can use the following directive. + # + CustomLog "logs/access_log" combined + + + + # + # Redirect: Allows you to tell clients about documents that used to + # exist in your server's namespace, but do not anymore. The client + # will make a new request for the document at its new location. + # Example: + # Redirect permanent /foo http://www.example.com/bar + + # + # Alias: Maps web paths into filesystem paths and is used to + # access content that does not live under the DocumentRoot. + # Example: + # Alias /webpath /full/filesystem/path + # + # If you include a trailing / on /webpath then the server will + # require it to be present in the URL. You will also likely + # need to provide a section to allow access to + # the filesystem path. + + # + # ScriptAlias: This controls which directories contain server scripts. + # ScriptAliases are essentially the same as Aliases, except that + # documents in the target directory are treated as applications and + # run by the server when requested rather than as documents sent to the + # client. The same rules about trailing "/" apply to ScriptAlias + # directives as to Alias. + # + ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" + + + +# +# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased +# CGI directory exists, if you have that configured. +# + + AllowOverride None + Options None + Require all granted + + + + # + # TypesConfig points to the file containing the list of mappings from + # filename extension to MIME-type. + # + TypesConfig /etc/mime.types + + # + # AddType allows you to add to or override the MIME configuration + # file specified in TypesConfig for specific file types. + # + #AddType application/x-gzip .tgz + # + # AddEncoding allows you to have certain browsers uncompress + # information on the fly. Note: Not all browsers support this. + # + #AddEncoding x-compress .Z + #AddEncoding x-gzip .gz .tgz + # + # If the AddEncoding directives above are commented-out, then you + # probably should define those extensions to indicate media types: + # + AddType application/x-compress .Z + AddType application/x-gzip .gz .tgz + + # + # AddHandler allows you to map certain file extensions to "handlers": + # actions unrelated to filetype. These can be either built into the server + # or added with the Action directive (see below) + # + # To use CGI scripts outside of ScriptAliased directories: + # (You will also need to add "ExecCGI" to the "Options" directive.) + # + #AddHandler cgi-script .cgi + + # For type maps (negotiated resources): + #AddHandler type-map var + + # + # Filters allow you to process content before it is sent to the client. + # + # To parse .shtml files for server-side includes (SSI): + # (You will also need to add "Includes" to the "Options" directive.) + # + AddType text/html .shtml + AddOutputFilter INCLUDES .shtml + + +# +# Specify a default charset for all content served; this enables +# interpretation of all content as UTF-8 by default. To use the +# default browser choice (ISO-8859-1), or to allow the META tags +# in HTML content to override this choice, comment out this +# directive: +# +AddDefaultCharset UTF-8 + + + # + # The mod_mime_magic module allows the server to use various hints from the + # contents of the file itself to determine its type. The MIMEMagicFile + # directive tells the module where the hint definitions are located. + # + MIMEMagicFile conf/magic + + +# +# Customizable error responses come in three flavors: +# 1) plain text 2) local redirects 3) external redirects +# +# Some examples: +#ErrorDocument 500 "The server made a boo boo." +#ErrorDocument 404 /missing.html +#ErrorDocument 404 "/cgi-bin/missing_handler.pl" +#ErrorDocument 402 http://www.example.com/subscription_info.html +# + +# +# EnableMMAP and EnableSendfile: On systems that support it, +# memory-mapping or the sendfile syscall may be used to deliver +# files. This usually improves server performance, but must +# be turned off when serving from networked-mounted +# filesystems or if support for these functions is otherwise +# broken on your system. +# Defaults if commented: EnableMMAP On, EnableSendfile Off +# +#EnableMMAP off +EnableSendfile on + +# Supplemental configuration +# +# Load config files in the "/etc/httpd/conf.d" directory, if any. +IncludeOptional conf.d/*.conf diff --git a/docker/roundcube/rootfs/etc/kolab/kolab.conf b/docker/roundcube/rootfs/etc/kolab/kolab.conf new file mode 100644 index 00000000..f9010e1c --- /dev/null +++ b/docker/roundcube/rootfs/etc/kolab/kolab.conf @@ -0,0 +1,21 @@ +[autodiscover] +activesync = %d +imap = ssl://%d:993 +smtp = ssl://%d:465 + +; LDAP attribute used as login +login_attribute = mail + +; optional service name +service_name = Kolab Groupware +service_short = Kolab + +; enables HTTP/LDAP debugging +;debug_mode = trace + +[ldap] +service_bind_dn = uid=kolab-service,ou=Special Users,dc=example,dc=org +service_bind_pw = Welcome2KolabSystems +domain_name_attribute = associateddomain +domain_filter = (&(associatedDomain=*)) +domain_base_dn = cn=kolab,cn=config diff --git a/docker/roundcube/rootfs/etc/roundcubemail/acl.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/acl.inc.php new file mode 100644 index 00000000..e6a6a017 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/acl.inc.php @@ -0,0 +1,14 @@ + diff --git a/docker/roundcube/rootfs/etc/roundcubemail/calendar.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/calendar.inc.php new file mode 100644 index 00000000..1a97b475 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/calendar.inc.php @@ -0,0 +1,73 @@ + 'Kolab Resources', + 'hosts' => getenv('LDAP_HOST'), + 'port' => 389, + 'use_tls' => false, + 'base_dn' => 'dc=hosted,dc=com', + 'user_specific' => true, + 'bind_dn' => '%dn', + 'bind_pass' => '', + 'search_base_dn' => 'dc=hosted,dc=com', + 'search_bind_dn' => 'uid=kolab-service,ou=Special Users,dc=mgmt,dc=com', + 'search_bind_pw' => getenv('LDAP_SERVICE_BIND_PW'), + 'search_filter' => '(&(objectClass=inetorgperson)(mail=%fu))', + 'ldap_version' => 3, + 'filter' => '(|(|(objectclass=groupofuniquenames)(objectclass=groupofurls))(objectclass=kolabsharedfolder))', + 'search_fields' => array('cn'), + 'sort' => array('cn'), + 'scope' => 'sub', + 'fuzzy_search' => true, + 'fieldmap' => array( + // Internal => LDAP + 'name' => 'cn', + 'email' => 'mail', + 'owner' => 'owner', + 'description' => 'description', + 'attributes' => 'kolabdescattribute', + 'members' => 'uniquemember', + // these mappings are required for owner display + 'phone' => 'telephoneNumber', + 'mobile' => 'mobile', + ), + + 'class_type_map' => array( + 'kolabsharedfolder' => 'resource', + 'groupofuniquenames' => 'collection', + ), + + 'groups' => array( + 'name_attr' => 'cn', + ), + ); + + if (file_exists(RCUBE_CONFIG_DIR . '/' . ($_SERVER["HTTP_HOST"] ?? null) . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . ($_SERVER["HTTP_HOST"] ?? null) . '/' . basename(__FILE__)); + } + +?> diff --git a/docker/roundcube/rootfs/etc/roundcubemail/config.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/config.inc.php new file mode 100644 index 00000000..00116be4 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/config.inc.php @@ -0,0 +1,255 @@ += 5.6 + $config['imap_conn_options'] = [ + 'ssl' => [ + 'verify_peer_name' => false, + 'verify_peer' => false, + 'allow_self_signed' => true + ], + 'proxy_protocol' => 2 + ]; + $config['proxy_whitelist'] = ['127.0.0.1', '172.18.0.7']; + + // Caching and storage settings + $config['imap_cache'] = 'db'; + $config['imap_cache_ttl'] = '10d'; + $config['messages_cache'] = 'db'; + $config['message_cache_ttl'] = '10d'; + $config['session_storage'] = 'db'; + + // SMTP Server Settings + $config['smtp_server'] = getenv('MAIL_HOST'); + $config['smtp_port'] = getenv('MAIL_PORT'); + $config['smtp_user'] = '%u'; + $config['smtp_pass'] = '%p'; + $config['smtp_helo_host'] = $_SERVER["HTTP_HOST"] ?? null; + + // SMTP Connection TLS settings, adjust for Production + // Required for PHP >= 5.6 + $config['smtp_conn_options'] = Array( + 'ssl' => Array( + 'verify_peer_name' => false, + 'verify_peer' => false, + 'allow_self_signed' => true + ) + ); + + // LDAP Settings + $config['ldap_cache'] = 'db'; + $config['ldap_cache_ttl'] = '1h'; + + // Kolab specific defaults + $config['product_name'] = 'Kolab Groupware'; + $config['quota_zero_as_unlimited'] = false; + $config['login_lc'] = 2; + $config['auto_create_user'] = true; + $config['enable_installer'] = false; + // The SMTP server does not allow empty identities + $config['mdn_use_from'] = true; + + // Plugins + $config['plugins'] = array( + 'kolab_auth', + 'acl', + 'archive', + 'calendar', + 'jqueryui', + 'kolab_activesync', + 'kolab_addressbook', + 'kolab_config', + 'kolab_delegation', + 'kolab_files', + 'kolab_folders', + 'kolab_notes', + 'kolab_tags', + 'managesieve', + 'newmail_notifier', + 'odfviewer', + 'password', + 'redundant_attachments', + 'tasklist', + // contextmenu must be after kolab_addressbook (#444) + 'contextmenu', +'enigma', + ); + + + // Do not show deleted messages, mark deleted messages as read, + // and flag them as deleted instead of moving them to the Trash + // folder. + $config['skip_deleted'] = true; + $config['read_when_deleted'] = true; + $config['flag_for_deletion'] = true; + $config['delete_always'] = true; + + $config['session_lifetime'] = 180; + $config['password_charset'] = 'UTF-8'; + $config['useragent'] = 'Kolab 16/Roundcube ' . RCUBE_VERSION; + + $config['message_sort_col'] = 'date'; + + $config['spellcheck_engine'] = 'pspell'; + $config['spellcheck_dictionary'] = true; + $config['spellcheck_ignore_caps'] = true; + $config['spellcheck_ignore_nums'] = true; + $config['spellcheck_ignore_syms'] = true; + $config['spellcheck_languages'] = array( + 'da' => 'Dansk', + 'de' => 'Deutsch', + 'en' => 'English', + 'es' => 'Español', + 'fr' => 'Français', + 'it' => 'Italiano', + 'nl' => 'Nederlands', + 'pt' => 'Português', + 'ru' => 'Русский', + 'sv' => 'Svenska' + ); + + $config['undo_timeout'] = 10; + $config['upload_progress'] = 2; + $config['address_template'] = '{street}
{locality} {zipcode}
{country} {region}'; + $config['preview_pane'] = true; + $config['preview_pane_mark_read'] = 0; + + $config['autoexpand_threads'] = 2; + $config['top_posting'] = 0; + $config['sig_above'] = false; + $config['mdn_requests'] = 0; + $config['mdn_default'] = false; + $config['dsn_default'] = false; + $config['reply_same_folder'] = false; + + if (file_exists(RCUBE_CONFIG_DIR . '/' . ($_SERVER["HTTP_HOST"] ?? null) . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . ($_SERVER["HTTP_HOST"] ?? null) . '/' . basename(__FILE__)); + } + + // Re-apply mandatory settings here. + + $config['debug_level'] = 1; + $config['devel_mode'] = false; + $config['log_driver'] = 'file'; + $config['log_date_format'] = 'd-M-Y H:i:s,u O'; + $config['syslog_id'] = 'roundcube'; + $config['syslog_facility'] = LOG_USER; + $config['smtp_log'] = false; + $config['log_logins'] = true; + $config['log_session'] = false; + $config['sql_debug'] = false; + $config['memcache_debug'] = false; + $config['imap_debug'] = false; + $config['ldap_debug'] = false; + $config['smtp_debug'] = false; + + $config['skin'] = 'kolab'; + $config['skin_include_php'] = false; + $config['mime_magic'] = null; + $config['im_identify_path'] = '/usr/bin/identify'; + $config['im_convert_path'] = '/usr/bin/convert'; + $config['log_dir'] = 'logs/'; + #$config['temp_dir'] = '/var/lib/roundcubemail/'; + + // Some additional default folders (archive plugin) + $config['archive_mbox'] = 'Archive'; + // The Kolab daemon by default creates 'Spam' + $config['junk_mbox'] = 'Spam'; + $config['default_folders'] = array('INBOX', 'Drafts', 'Sent', 'Spam', 'Trash', 'Archive'); + + $config['address_book_type'] = 'ldap'; + $config['autocomplete_min_length'] = 3; + $config['autocomplete_threads'] = 0; + $config['autocomplete_max'] = 15; + $config['ldap_public'] = array( + 'kolab_addressbook' => array( + 'name' => 'Global Address Book', + 'hosts' => Array(getenv('LDAP_HOST')), + 'port' => 389, + 'use_tls' => false, + 'base_dn' => 'dc=hosted,dc=com', + 'user_specific' => true, + 'bind_dn' => '%dn', + 'bind_pass' => '', + 'search_base_dn' => 'dc=hosted,dc=com', + 'search_bind_dn' => 'uid=kolab-service,ou=Special Users,dc=mgmt,dc=com', + 'search_bind_pw' => getenv('LDAP_SERVICE_BIND_PW'), + 'search_filter' => '(&(objectClass=inetorgperson)(mail=%fu))', + 'writable' => false, + 'LDAP_Object_Classes' => array("top", "inetorgperson"), + 'required_fields' => array("cn", "sn", "mail"), + 'LDAP_rdn' => 'uid', + 'ldap_version' => 3, // using LDAPv3 + 'search_fields' => array('displayname', 'mail'), + 'sort' => array('displayname', 'sn', 'givenname', 'cn'), + 'scope' => 'sub', + 'filter' => '(objectClass=inetorgperson)', + 'vlv' => true, + 'vlv_search' => true, + 'fuzzy_search' => true, + 'sizelimit' => '0', + 'timelimit' => '0', + 'fieldmap' => Array( + // Roundcube => LDAP + 'name' => 'displayName', + 'surname' => 'sn', + 'firstname' => 'givenName', + 'middlename' => 'initials', + 'email:primary' => 'mail', + 'email:alias' => 'alias', + 'email:personal' => 'mailalternateaddress', + 'phone:main' => 'telephoneNumber', + 'phone:work' => 'alternateTelephoneNumber', + 'phone:mobile' => 'mobile', + 'phone:work2' => 'blackberry', + 'jobtitle' => 'title', + 'manager' => 'manager', + 'assistant' => 'secretary', + 'photo' => 'jpegphoto' + ), + 'groups' => Array( + 'base_dn' => 'dc=hosted,dc=com', + 'filter' => '(&' . '(|(objectclass=groupofuniquenames)(objectclass=groupofurls))' . '(mail=*))', + 'object_classes' => Array("top", "groupOfUniqueNames"), + 'member_attr' => 'uniqueMember', + ), + ), + ); + + $config['autocomplete_addressbooks'] = Array( + 'kolab_addressbook' + ); + + $config['autocomplete_single'] = true; + + $config['htmleditor'] = 0; + + $config['kolab_http_request'] = Array( + 'ssl_verify_host' => false, + 'ssl_verify_peer' => false, + ); + + @include('kolab_syncroton.inc.php'); + + +?> diff --git a/docker/roundcube/rootfs/etc/roundcubemail/dav.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/dav.inc.php new file mode 100644 index 00000000..257c1ec7 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/dav.inc.php @@ -0,0 +1,160 @@ +. | + | | + +-------------------------------------------------------------------------+ +*/ + +$config = array(); + +// The HTTP path to the iRony root directory. +// Set to / if the service is registered as document root for a virtual host +$config['base_uri'] = '/iRony/'; + +// User agent string written to kolab storage MIME messages +$config['useragent'] = 'Kolab DAV Server libkolab/' . RCUBE_VERSION; + +// Type of Auth cache. Supported values: 'db', 'apc' and 'memcache'. +// Note: This is only for username canonification map. +$config['kolabdav_auth_cache'] = 'db'; + +// lifetime of the Auth cache, possible units: s, m, h, d, w +$config['kolabdav_auth_cache_ttl'] = '1h'; + +// enable debug console showing the internal function calls triggered +// by http requests. This will write log to /var/log/iRony/console +$config['kolabdav_console'] = false; + +// enable logging of full HTTP payload +// (bitmask of these values: 2 = HTTP Requests, 4 = HTTP Responses) +$config['kolabdav_http_log'] = 0; + +// expose iTip invitations from email inbox in CalDAV scheduling inbox. +// this will make capable CalDAV clients process event invitations and +// as a result, the invitation messages are removed from the email inbox. +// WARNING: this feature is still experimental and not fully implemented. +// See https://git.kolab.org/T93 for details and implementation status. +$config['kolabdav_caldav_inbox'] = false; + +// Enables the CardDAV Directory Gateway Extension by exposing an +// LDAP-based address book in the pricipals address book collection. +// Properties of this option are the same as for $config['ldap_public'] entries. +// NOTE: Mapping of (additional) 'uid' and 'changed' fields is required! +/* +$config['kolabdav_ldap_directory'] = array( + 'name' => 'Global Address Book', + 'hosts' => 'localhost', + 'port' => 389, + 'use_tls' => false, + // If true the base_dn, bind_dn and bind_pass default to the user's credentials. + 'user_specific' => false, + // It's possible to bind with the current user's credentials for individual address books. + // The login name is used to search for the DN to bind with + 'search_base_dn' => 'ou=People,dc=example,dc=org', + 'search_bind_dn' => 'uid=kolab-service,ou=Special Users,dc=example,dc=org', + 'search_bind_pw' => 'Welcome2KolabSystems', + 'search_filter' => '(&(objectClass=inetOrgPerson)(mail=%fu))', + // When 'user_specific' is enabled following variables can be used in base_dn/bind_dn config: + // %fu - The full username provided, assumes the username is an email + // address, uses the username_domain value if not an email address. + // %u - The username prior to the '@'. + // %d - The domain name after the '@'. + // %dc - The domain name hierarchal string e.g. "dc=test,dc=domain,dc=com" + // %dn - DN found by ldap search when search_filter/search_base_dn are used + 'base_dn' => 'ou=People,dc=example,dc=org', + 'bind_dn' => 'uid=kolab-service,ou=Special Users,dc=example,dc=org', + 'bind_pass' => 'Welcome2KolabSystems', + 'ldap_version' => 3, + 'filter' => '(objectClass=inetOrgPerson)', + 'search_fields' => array('displayname', 'mail'), + 'sort' => array('displayname', 'sn', 'givenname', 'cn'), + 'scope' => 'sub', + 'searchonly' => true, // Set to false to enable listing + 'sizelimit' => '1000', + 'timelimit' => '0', + 'fieldmap' => array( + // Roundcube => LDAP + 'name' => 'displayName', + 'surname' => 'sn', + 'firstname' => 'givenName', + 'middlename' => 'initials', + 'prefix' => 'title', + 'email:work' => 'mail', + 'email:other' => 'alias', + 'phone:main' => 'telephoneNumber', + 'phone:work' => 'alternateTelephoneNumber', + 'phone:mobile' => 'mobile', + 'phone:work2' => 'blackberry', + 'street' => 'street', + 'zipcode' => 'postalCode', + 'locality' => 'l', + 'organization' => 'o', + 'jobtitle' => 'title', + 'photo' => 'jpegphoto', + // required for internal handling and caching + 'uid' => 'nsuniqueid', + 'changed' => 'modifytimestamp', + ), +); + +// Expose all resources as an LDAP-based address book in the pricipals address book collection. +// This enables Non-Kolab-Clients to add resources to an event. +// Properties of this option are the same as for $config['kolabdav_ldap_directory'] entries. +$config['kolabdav_ldap_resources'] = array( + 'name' => 'Global Resources', + 'hosts' => 'localhost', + 'port' => 389, + 'use_tls' => false, + 'user_specific' => false, + 'search_base_dn' => 'ou=People,dc=example,dc=org', + 'search_bind_dn' => 'uid=kolab-service,ou=Special Users,dc=example,dc=org', + 'search_bind_pw' => 'Welcome2KolabSystems', + 'search_filter' => '(&(objectClass=inetOrgPerson)(mail=%fu))', + 'base_dn' => 'ou=Resources,dc=example,dc=org', + 'bind_dn' => 'uid=kolab-service,ou=Special Users,dc=example,dc=org', + 'bind_pass' => 'Welcome2KolabSystems', + 'ldap_version' => 3, + 'filter' => '(|(objectclass=groupofuniquenames)(objectclass=groupofurls)(objectclass=kolabsharedfolder))', + 'search_fields' => array('displayname', 'mail'), + 'sort' => array('displayname', 'sn', 'givenname', 'cn'), + 'scope' => 'sub', + 'searchonly' => false, // Set to false to enable listing + 'sizelimit' => '1000', + 'timelimit' => '0', + 'fieldmap' => array( + // Internal => LDAP + 'name' => 'cn', + 'email' => 'mail', + 'owner' => 'owner', + 'description' => 'description', + 'attributes' => 'kolabdescattribute', + 'members' => 'uniquemember', + // these mappings are required for owner display + 'phone' => 'telephoneNumber', + 'mobile' => 'mobile', + ), +); + +*/ + +// Enable caching for LDAP directory data. +// This is recommended with 'searchonly' => false to speed-up sychronization of multiple clients +// $config['kolabdav_ldap_cache'] = 'memcache'; +// $config['kolabdav_ldap_cache_ttl'] = 600; // in seconds diff --git a/docker/roundcube/rootfs/etc/roundcubemail/kolab_activesync.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/kolab_activesync.inc.php new file mode 100644 index 00000000..20011256 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/kolab_activesync.inc.php @@ -0,0 +1,7 @@ + not subscribed, 1 => subscribed, 2 => subscribed with alarm +$config['activesync_force_subscriptions'] = array('windowsoutlook15' => array('INBOX' => 1, 'Sent' => 1, 'Trash' => 1, 'Calendar' => 1, 'Contacts' => 1, 'Tasks' => 1)); diff --git a/docker/roundcube/rootfs/etc/roundcubemail/kolab_addressbook.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/kolab_addressbook.inc.php new file mode 100644 index 00000000..0f6b8ab6 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/kolab_addressbook.inc.php @@ -0,0 +1,20 @@ + diff --git a/docker/roundcube/rootfs/etc/roundcubemail/kolab_auth.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/kolab_auth.inc.php new file mode 100644 index 00000000..013267c7 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/kolab_auth.inc.php @@ -0,0 +1,70 @@ + 'Kolab Auth', + 'hosts' => Array(getenv('LDAP_HOST')), + 'port' => 389, + 'use_tls' => false, + 'user_specific' => true, + 'base_dn' => 'dc=hosted,dc=com', + 'bind_dn' => 'uid=kolab-service,ou=Special Users,dc=mgmt,dc=com', + 'bind_pass' => getenv('LDAP_SERVICE_BIND_PW'), + 'writable' => false, + 'ldap_version' => 3, // using LDAPv3 + 'fieldmap' => Array( + 'name' => 'displayname', + 'email' => 'mail', + 'email:alias' => 'alias', + 'role' => 'nsroledn', + ), + 'sort' => 'displayname', + 'scope' => 'sub', + 'filter' => '(objectClass=*)', + 'fuzzy_search' => true, + 'sizelimit' => '0', + 'timelimit' => '0', + 'groups' => Array( + 'base_dn' => 'dc=hosted,dc=com', + 'filter' => '(|(objectclass=groupofuniquenames)(objectclass=groupofurls))', + 'object_classes' => Array('top', 'groupOfUniqueNames'), + 'member_attr' => 'uniqueMember', + ), + ); + + + // This will overwrite defined filter + $config['kolab_auth_filter'] = '(&' . '(objectclass=inetorgperson)' . '(|(uid=%u)(mail=%fu)(alias=%fu)))'; + + // Use this fields (from fieldmap configuration) to get authentication ID + $config['kolab_auth_login'] = 'email'; + + // Use this fields (from fieldmap configuration) for default identity + $config['kolab_auth_name'] = 'name'; + $config['kolab_auth_alias'] = 'alias'; + $config['kolab_auth_email'] = 'email'; + + if (preg_match('/\/helpdesk-login\//', $_SERVER["REQUEST_URI"] ?? null) ) { + + // Login and password of the admin user. Enables "Login As" feature. + $config['kolab_auth_admin_login'] = getenv('IMAP_ADMIN_LOGIN'); + $config['kolab_auth_admin_password'] = getenv('IMAP_ADMIN_PASSWORD'); + + $config['kolab_auth_auditlog'] = true; + } + + // Administrative role field (from fieldmap configuration) which must be filled with + // specified value which adds privilege to login as another user. + $config['kolab_auth_role'] = 'role'; + $config['kolab_auth_role_value'] = 'cn=kolab-admin,dc=mgmt,dc=com'; + + // Administrative group name to which user must be assigned to + // which adds privilege to login as another user. + $config['kolab_auth_group'] = 'Kolab Helpdesk'; + + if (file_exists(RCUBE_CONFIG_DIR . '/' . ($_SERVER["HTTP_HOST"] ?? null) . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . ($_SERVER["HTTP_HOST"] ?? null) . '/' . basename(__FILE__)); + } + +?> diff --git a/docker/roundcube/rootfs/etc/roundcubemail/kolab_delegation.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/kolab_delegation.inc.php new file mode 100644 index 00000000..f8358198 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/kolab_delegation.inc.php @@ -0,0 +1,14 @@ + diff --git a/docker/roundcube/rootfs/etc/roundcubemail/kolab_files.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/kolab_files.inc.php new file mode 100644 index 00000000..3ba79bed --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/kolab_files.inc.php @@ -0,0 +1,29 @@ + diff --git a/docker/roundcube/rootfs/etc/roundcubemail/kolab_folders.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/kolab_folders.inc.php new file mode 100644 index 00000000..d64717b0 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/kolab_folders.inc.php @@ -0,0 +1,21 @@ + diff --git a/docker/roundcube/rootfs/etc/roundcubemail/kolab_syncroton.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/kolab_syncroton.inc.php new file mode 100644 index 00000000..a72b3555 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/kolab_syncroton.inc.php @@ -0,0 +1,125 @@ + Roundcube contact fields map for GAL search +/* Default: array( + 'alias' => 'nickname', + 'company' => 'organization', + 'displayName' => 'name', + 'emailAddress' => 'email', + 'firstName' => 'firstname', + 'lastName' => 'surname', + 'mobilePhone' => 'phone.mobile', + 'office' => 'office', + 'picture' => 'photo', + 'phone' => 'phone', + 'title' => 'jobtitle', +); +*/ +$config['activesync_gal_fieldmap'] = null; + +// List of device types that will sync the LDAP addressbook(s) as a normal folder. +// For devices that do not support GAL searching, e.g. Outlook. +// Note: To make the LDAP addressbook sources working we need two additional +// fields ('uid' and 'changed') specified in the fieldmap array +// of the LDAP configuration ('ldap_public' option). For example: +// 'uid' => 'nsuniqueid', +// 'changed' => 'modifytimestamp', +// Examples: +// array('windowsoutlook') # enable for Oultook only +// true # enable for all +$config['activesync_gal_sync'] = false; + +// GAL cache. As reading all contacts from LDAP may be slow, caching is recommended. +$config['activesync_gal_cache'] = 'db'; + +// TTL of GAL cache entries. Technically this causes that synchronized +// contacts will not be updated (queried) often than the specified interval. +$config['activesync_gal_cache_ttl'] = '1d'; + +// List of Roundcube plugins +// WARNING: Not all plugins used in Roundcube can be listed here +$config['activesync_plugins'] = array( + 'libcalendaring', + 'libkolab' +); + +// Defines for how many seconds we'll sleep between every +// action for detecting changes in folders. Default: 60 +$config['activesync_ping_timeout'] = 60; + +// Defines maximum Ping interval in seconds. Default: 900 (15 minutes) +$config['activesync_ping_interval'] = 900; + +// We start detecting changes n seconds since the last sync of a folder +// Default: 180 +$config['activesync_quiet_time'] = 0; + +// Defines maximum number of folders in a single Sync/Ping request. Default: 100. +$config['activesync_max_folders'] = 100; + +// When a device is reqistered, by default a set of folders are +// subscribed for syncronization, i.e. INBOX and personal folders with +// defined folder type: +// mail.drafts, mail.wastebasket, mail.sentitems, mail.outbox, +// event, event.default, +// contact, contact.default, +// task, task.default +// This default set can be extended by adding following values: +// 1 - all subscribed folders in personal namespace +// 2 - all folders in personal namespace +// 4 - all subscribed folders in other users namespace +// 8 - all folders in other users namespace +// 16 - all subscribed folders in shared namespace +// 32 - all folders in shared namespace +$config['activesync_init_subscriptions'] = 21; + +// Defines blacklist of devices (device type strings) that do not support folder hierarchies. +// When set to an array folder hierarchies are used on all devices not listed here. +// When set to null an old whitelist approach will be used where we do opposite +// action and enable folder hierarchies only on device types known to support it. +$config['activesync_multifolder_blacklist'] = array(); + +// Blacklist overwrites for specified object type. If set to an array +// it will have a precedence over 'activesync_multifolder_blacklist' list only for that type. +// Note: Outlook does not support multiple folders for contacts, +// in that case use $config['activesync_multifolder_blacklist_contact'] = array('windowsoutlook'); +$config['activesync_multifolder_blacklist_mail'] = null; +$config['activesync_multifolder_blacklist_event'] = null; +$config['activesync_multifolder_blacklist_contact'] = array('windowsoutlook'); +$config['activesync_multifolder_blacklist_note'] = null; +$config['activesync_multifolder_blacklist_task'] = null; + +$config['activesync_protected_folders'] = array('windowsoutlook' => array('INBOX', 'Sent', 'Trash')); + +// Enables adding sender name in the From: header of send email +// when a device uses email address only (e.g. iOS devices) +$config['activesync_fix_from'] = false; diff --git a/docker/roundcube/rootfs/etc/roundcubemail/libkolab.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/libkolab.inc.php new file mode 100644 index 00000000..76161ce8 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/libkolab.inc.php @@ -0,0 +1,16 @@ + diff --git a/docker/roundcube/rootfs/etc/roundcubemail/managesieve.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/managesieve.inc.php new file mode 100644 index 00000000..db2024ee --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/managesieve.inc.php @@ -0,0 +1,31 @@ + Array( + 'verify_peer_name' => false, + 'verify_peer' => false, + 'allow_self_signed' => true + ) + ); + + if (file_exists(RCUBE_CONFIG_DIR . '/' . $_SERVER["HTTP_HOST"] . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . $_SERVER["HTTP_HOST"] . '/' . basename(__FILE__)); + } + +?> diff --git a/docker/roundcube/rootfs/etc/roundcubemail/mimetypes.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/mimetypes.inc.php new file mode 100644 index 00000000..efb4698e --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/mimetypes.inc.php @@ -0,0 +1,56 @@ + 'application/vnd.ms-excel', + 'xlm' => 'application/vnd.ms-excel', + 'xla' => 'application/vnd.ms-excel', + 'xlc' => 'application/vnd.ms-excel', + 'xlt' => 'application/vnd.ms-excel', + 'xlw' => 'application/vnd.ms-excel', + 'pdf' => 'application/pdf', + 'ppt' => 'application/vnd.ms-powerpoint', + 'pps' => 'application/vnd.ms-powerpoint', + 'pot' => 'application/vnd.ms-powerpoint', + 'doc' => 'application/msword', + 'dot' => 'application/msword', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'otf' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'otm' => 'application/vnd.oasis.opendocument.text-master', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web', + 'docm' => 'application/vnd.ms-word.document.macroEnabled.12', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', + 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xps' => 'application/vnd.ms-xpsdocument', + 'rar' => 'application/x-rar-compressed', + '7z' => 'application/x-7z-compressed', + 's7z' => 'application/x-7z-compressed', + 'vcf' => 'text/vcard', + 'ics' => 'text/calendar', +]; diff --git a/docker/roundcube/rootfs/etc/roundcubemail/password.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/password.inc.php new file mode 100644 index 00000000..09808d92 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/password.inc.php @@ -0,0 +1,155 @@ + diff --git a/docker/roundcube/rootfs/etc/roundcubemail/recipient_to_contact.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/recipient_to_contact.inc.php new file mode 100644 index 00000000..9d22aeb8 --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/recipient_to_contact.inc.php @@ -0,0 +1,3 @@ + + + + +

Welcome to Kolab Groupware

+

+ Here could be your Message of the Day. +

+ + diff --git a/docker/roundcube/rootfs/etc/roundcubemail/terms.inc.php b/docker/roundcube/rootfs/etc/roundcubemail/terms.inc.php new file mode 100644 index 00000000..28b450cb --- /dev/null +++ b/docker/roundcube/rootfs/etc/roundcubemail/terms.inc.php @@ -0,0 +1,22 @@ + diff --git a/docker/roundcube/rootfs/opt/app-root/src/build.sh b/docker/roundcube/rootfs/opt/app-root/src/build.sh new file mode 100755 index 00000000..ddd91e04 --- /dev/null +++ b/docker/roundcube/rootfs/opt/app-root/src/build.sh @@ -0,0 +1,62 @@ +#!/bin/bash +set -e +set -x + +pushd /opt/app-root/src/ + +# Clone what we don't find (roundcubemail-skin-elastic is not publicly available, so can't be included this way) +if [ ! -d roundcubemail ]; then + # Push this branch on an apheleia-it repo + git clone --branch dev/kolab-1.5 https://github.com/cmollekopf/roundcubemail.git roundcubemail +fi +if [ ! -d roundcubemail-plugins-kolab ]; then + git clone --branch master https://git.kolab.org/diffusion/RPK/roundcubemail-plugins-kolab.git roundcubemail-plugins-kolab +fi +if [ ! -d syncroton ]; then + git clone --branch master https://git.kolab.org/diffusion/S/syncroton.git syncroton +fi +if [ ! -d iRony ]; then + git clone --branch master https://git.kolab.org/source/iRony.git iRony +fi +if [ ! -d chwala ]; then + git clone --branch master https://git.kolab.org/diffusion/C/chwala.git chwala +fi +if [ ! -d autoconf ]; then + git clone --branch master https://git.kolab.org/diffusion/AC/autoconf.git autoconf +fi +if [ ! -d freebusy ]; then + git clone --branch master https://git.kolab.org/diffusion/F/freebusy.git freebusy +fi + + +pushd roundcubemail +cp /opt/app-root/src/composer.json composer.json +rm -rf vendor/ composer.lock +php -dmemory_limit=-1 $(command -v composer) install + +cd /opt/app-root/src/ +./update.sh +cd /opt/app-root/src/roundcubemail + +# Adjust the configs + +sed -i -r \ + -e "s/'vlv'(\s+)=> false,/'vlv'\1=> true,/g" \ + -e "s/'vlv_search'(\s+)=> false,/'vlv_search'\1=> true,/g" \ + -e "s/inetOrgPerson/inetorgperson/g" \ + -e "s/kolabInetOrgPerson/inetorgperson/g" \ + config/*.inc.php + +sed -i -r -e "s|\$config\['enigma_pgp_homedir'\] = .*$|\$config['enigma_pgp_homedir'] = '/tmp/';|g" config/enigma.inc.php +sed -i -r -e "s|\$config\['enigma_passwordless'\] = .*$|\$config['enigma_passwordless'] = true;|g" config/enigma.inc.php +sed -i -r -e "s|\$config\['enigma_multihost'\] = .*$|\$config['enigma_multihost'] = true;|g" config/enigma.inc.php +echo "\$config['enigma_woat'] = true;" >> config/enigma.inc.php + +sed -i -r -e "s|\$config\['managesieve_host'\] = .*$|\$config['managesieve_host'] = 'kolab';|g" config/managesieve.inc.php + +popd + +# Set the php timezone +sed -i -r -e 's|^(;*)date\.timezone.*$|date.timezone = Europe/Zurich|g' /etc/php.ini +# Allow environment variables from fpm +sed -i -e "s/;clear_env/clear_env/" /etc/php-fpm.d/www.conf diff --git a/docker/roundcube/rootfs/opt/app-root/src/composer.json b/docker/roundcube/rootfs/opt/app-root/src/composer.json new file mode 100755 index 00000000..f0f3f126 --- /dev/null +++ b/docker/roundcube/rootfs/opt/app-root/src/composer.json @@ -0,0 +1,179 @@ +{ + "name": "kolab/roundcubemail", + "description": "The Roundcube Webmail suite", + "license": "GPL-3.0+", + "version": "1.5.3", + "config": { + "platform": { + "php": "7.2.24" + }, + "allow-plugins": { + "roundcube/plugin-installer": true + } + }, + "repositories": [ + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/kolab_activesync", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/kolab_addressbook", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/kolab_auth", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/kolab_config", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/kolab_delegation", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/kolab_files", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/kolab_folders", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/kolab_notes", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/kolab_tags", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/kolab_chat", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/odfviewer", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/pdfviewer", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/tasklist", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/calendar", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/libcalendaring", + "options": { + "symlink": false + } + }, + { + "type": "path", + "url": "/opt/app-root/src/roundcubemail-plugins-kolab/plugins/libkolab", + "options": { + "symlink": false + } + }, + { + "type": "composer", + "url": "https://plugins.roundcube.net" + } + ], + "require": { + "php": ">=7.2.0", + "pear/pear-core-minimal": "~1.10.1", + "pear/auth_sasl": "~1.1.0", + "pear/mail_mime": "~1.10.0", + "pear/http_request2": "~2.5.0", + "pear/net_smtp": "~1.10.0", + "pear/crypt_gpg": "~1.6.3", + "pear/net_sieve": "~1.4.5", + "roundcube/plugin-installer": "~0.2.0", + "roundcube/rtf-html-php": "~2.1", + "masterminds/html5": "~2.7.0", + "endroid/qr-code": "~1.6.5", + "guzzlehttp/guzzle": "^7.4.1", + "kolab/calendar": "~3.5.11", + "kolab/kolab_activesync": "~3.5.6", + "kolab/kolab_addressbook": "~3.5.6", + "kolab/kolab_auth": "~3.5.6", + "kolab/kolab_chat": "~3.5.2", + "kolab/kolab_config": "~3.4.0", + "kolab/kolab_delegation": "~3.5.11", + "kolab/kolab_files": "~3.5.2", + "kolab/kolab_folders": "~3.5.2", + "kolab/kolab_notes": "~3.5.5", + "kolab/kolab_tags": "~3.5.2", + "kolab/net_ldap3": "dev-master", + "kolab/odfviewer": "~3.4.0", + "kolab/pdfviewer": "~3.4.0", + "kolab/tasklist": "~3.5.10", + "johndoh/contextmenu": "~3.2.1", + "zf1/zend-json": "~1.12.11", + "zf1/zend-log": "~1.12.11", + "zf1/zend-controller": "~1.12.11", + "sabre/vobject" : "~4.5.1", + "sabre/dav" : "~4.0", + "sabre/http" : "~5.0", + "smarty/smarty" : "~3.1.7" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^5.7.21", + "phpstan/phpstan": "^1.4", + "squizlabs/php_codesniffer": "^3.6", + "phpcompatibility/php-compatibility": "^9.3" + }, + "suggest": { + "mkopinsky/zxcvbn-php": "^4.4.2 required for Zxcvbn password strength driver" + } +} diff --git a/docker/roundcube/rootfs/opt/app-root/src/enable-xdebug.sh b/docker/roundcube/rootfs/opt/app-root/src/enable-xdebug.sh new file mode 100755 index 00000000..416179cd --- /dev/null +++ b/docker/roundcube/rootfs/opt/app-root/src/enable-xdebug.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +dnf -y install php-xdebug + +cat << EOF > /etc/php.d/xdebug.ini +zend_extension=/usr/lib64/php/modules/xdebug.so + +# Profiler config for xdebug3 +#xdebug.mode=profile +#xdebug.output_dir="/tmp/" +#xdebug.start_with_request=trigger + +# Profiler config for xdebug2 +#xdebug.remote_log="/tmp/xdebug.log" +xdebug.profiler_enable = 0 +# Enable using a XDEBUG_PROFILE GET/POST parameter +xdebug.profiler_enable_trigger = 1 +xdebug.profiler_output_dir = "/tmp/" +#xdebug.remote_enable=on +#xdebug.remote_port=9000 +#xdebug.remote_autostart=0 +#xdebug.remote_connect_back=on +#xdebug.idekey=editor-xdebug +EOF diff --git a/docker/roundcube/rootfs/opt/app-root/src/init.sh b/docker/roundcube/rootfs/opt/app-root/src/init.sh new file mode 100755 index 00000000..1b9f6950 --- /dev/null +++ b/docker/roundcube/rootfs/opt/app-root/src/init.sh @@ -0,0 +1,75 @@ +#!/bin/bash +set -e +set -x + +pushd /opt/app-root/src/ + +sed -i -r -e "s|service_bind_pw = .*$|service_bind_pw = $LDAP_SERVICE_BIND_PW|g" /etc/kolab/kolab.conf + +pushd roundcubemail + +## Copy our configs over the default ones +cp /etc/roundcubemail/* config/ + +DES_KEY=$(openssl rand -base64 24); +sed -i -r -e "s|\$config\['des_key'\] = .*$|\$config['des_key'] = \"$DES_KEY\";|g" config/config.inc.php + +# Initialize the db +cat > /tmp/kolab-setup-my.cnf << EOF +[client] +host=${DB_HOST} +user=root +password=${DB_ROOT_PASSWORD} +EOF + +mysql --defaults-file=/tmp/kolab-setup-my.cnf </dev/null 2>&1 || : + done + fi +done + +# FIXME should we be runnin updates? +# bin/updatedb.sh --dir SQL/ --package roundcube +# bin/updatedb.sh --dir plugins/libkolab/SQL/ --package libkolab +# bin/updatedb.sh --dir plugins/calendar/SQL/ --package calendar + +popd + +roundcubemail/bin/initdb.sh --dir syncroton/docs/SQL/ || : +roundcubemail/bin/initdb.sh --dir chwala/doc/SQL/ || : + +# Fix permissions. Logfiles could have been written as root during dbinit especially. +chmod 777 -R roundcubemail/logs +chmod 777 -R roundcubemail/temp + +echo "" +echo "Done, starting httpd..." + +mkdir -p /run/php-fpm +/usr/sbin/php-fpm +chmod 777 /run/php-fpm +mkdir -p /run/httpd +exec httpd -DFOREGROUND diff --git a/docker/roundcube/rootfs/opt/app-root/src/reload.sh b/docker/roundcube/rootfs/opt/app-root/src/reload.sh new file mode 100755 index 00000000..619e9d68 --- /dev/null +++ b/docker/roundcube/rootfs/opt/app-root/src/reload.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +kill -SIGUSR1 1 diff --git a/docker/roundcube/rootfs/opt/app-root/src/update-from-source.sh b/docker/roundcube/rootfs/opt/app-root/src/update-from-source.sh new file mode 100755 index 00000000..189b24f7 --- /dev/null +++ b/docker/roundcube/rootfs/opt/app-root/src/update-from-source.sh @@ -0,0 +1,35 @@ +#!/bin/bash +#Update from source (rather then via composer which updates to the latest commit) + +for repo in roundcubemail syncroton iRony chwala autoconf freebusy +do + if [ -d /src.orig/$directory ]; then + rsync -av \ + --exclude=vendor \ + --exclude=temp \ + --exclude=config \ + --exclude=logs \ + --exclude=.git \ + --exclude=config.inc.php \ + --exclude=composer.json \ + --exclude=composer.lock \ + /src.orig/$directory/ /opt/app-root/src/$directory + fi +done + +pushd /src.orig/roundcubemail-plugins-kolab/plugins + +for plugin in $(ls -1d) +do + if [ -d /opt/app-root/src/roundcubemail/plugins/${plugin}/ ]; then + rsync -av \ + --exclude=vendor \ + --exclude=composer.json \ + --exclude=config.inc.php \ + $plugin/ /opt/app-root/src/roundcubemail/plugins/$plugin + fi +done +popd + + +./reload.sh diff --git a/docker/roundcube/rootfs/opt/app-root/src/update.sh b/docker/roundcube/rootfs/opt/app-root/src/update.sh new file mode 100755 index 00000000..00bab99d --- /dev/null +++ b/docker/roundcube/rootfs/opt/app-root/src/update.sh @@ -0,0 +1,178 @@ +#!/bin/bash +set -e +set -x + +# Look for local repositories +for repo in roundcubemail roundcubemail-plugins-kolab roundcubemail-skin-elastic syncroton iRony chwala autoconf freebusy +do + if [ -d /src.orig/$repo ]; then + rsync -av \ + --exclude=vendor \ + --exclude=temp \ + --exclude=logs \ + --exclude=composer.lock \ + /src.orig/$repo/ /opt/app-root/src/$repo + fi +done + +pushd /opt/app-root/src/ + +LESSC=/usr/local/bin/lessc +SKINS=(kolab plesk) + +pushd roundcubemail +cp /opt/app-root/src/composer.json composer.json + +php -dmemory_limit=-1 $(command -v composer) update + +bin/install-jsdeps.sh + +# May require an "npm install less" and "npm install less-plugin-clean-css" +pushd skins/elastic +$LESSC -x styles/styles.less > styles/styles.css +$LESSC -x styles/print.less > styles/print.css +$LESSC -x styles/embed.less > styles/embed.css +popd +$LESSC --clean-css="--s1 --advanced" --rewrite-urls=all plugins/libkolab/skins/elastic/libkolab.less > plugins/libkolab/skins/elastic/libkolab.min.css + +bin/updatecss.sh --dir skins/elastic +popd + +# Install skins +for skin in "${SKINS[@]}"; do + if [ -d "roundcubemail-skin-elastic/$skin" ]; then + cp -r "roundcubemail-skin-elastic/$skin" roundcubemail/skins/ + else + echo "Skin $skin is not available" + fi +done + +pushd roundcubemail + +for skin in $(ls -1d skins/* | grep -vE '(classic|elastic|larry)'); do + skin=$(basename $skin) + + # Copy elastic skin over $skin (but don't overwrite what already existis) + find \ + ./skins/elastic/ \ + ./plugins/libkolab/skins/elastic/ \ + -type f | sort | while read file; do + target_dir=$(dirname ${file} | sed -e 's|%{datadir}|.|g' -e 's|./public_html/assets/|./|g' -e 's|./public_html/assets/plugins/libkolab/|./|g' -e "s/elastic/$skin/g") + file_name=$(basename ${file}) + echo "Target: $target_dir, file $file_name" + if [ ! -d ${target_dir} ]; then + mkdir -p ${target_dir} + fi + if [ ! -f "${target_dir}/${file_name}" ]; then + cp -av "${file}" "${target_dir}" + fi + done + + # Replace elastic references, but don't change the depends value in meta.json + sed -i -e "s/\"elastic\"/\"$skin\"/g" \ + $(find skins/$skin/ plugins/libkolab/skins/$skin/ -type f -not -name "meta.json") + + pushd skins/$skin + $LESSC -x styles/styles.less > styles/styles.css + $LESSC -x styles/print.less > styles/print.css + $LESSC -x styles/embed.less > styles/embed.css + popd + $LESSC --clean-css="--s1 --advanced" --rewrite-urls=all plugins/libkolab/skins/$skin/libkolab.less > plugins/libkolab/skins/$skin/libkolab.min.css + + # Compile and compress the CSS + #for file in `find . -type f -name "styles.less" -o -name "print.less" -o -name "embed.less" -o -name "libkolab.less"`; do + # %{_bindir}/lessc --relative-urls ${file} > $(dirname ${file})/$(basename ${file} .less).css + # + # sed -i \ + # -e "s|../../../skins/plesk/images/contactpic.png|../../../../skins/plesk/images/contactpic.png|" \ + # -e "s|../../../skins/plesk/images/watermark.jpg|../../../../skins/plesk/images/watermark.jpg|" \ + # $(dirname ${file})/$(basename ${file} .less).css + # + # cat $(dirname ${file})/$(basename ${file} .less).css + #done + + bin/updatecss.sh --dir "skins/$skin" +done + +## Configs + +# Install plugin configs +for plugin in $(find plugins/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sort); do + if [ -f "plugins/${plugin}/config.inc.php.dist" ]; then + pushd plugins/${plugin} + mv config.inc.php.dist ../../config/${plugin}.inc.php + rm -f config.inc.php + ln -s ../../config/${plugin}.inc.php config.inc.php + popd + fi +done + +# Copy our configs over the default ones +cp /etc/roundcubemail/* config/ + +DES_KEY=$(openssl rand -base64 24); +sed -i -r -e "s|\$config\['des_key'\] = .*$|\$config['des_key'] = \"$DES_KEY\";|g" config/config.inc.php + +##Fix permissions +chmod 777 -R logs +chmod 777 -R temp + +popd + +# Maybe redo this in case of updates +# Install chwala +pushd chwala +rm -f lib/ext/Roundcube lib/drivers/kolab/plugins vendor +mkdir -p lib/ext +ln -s ../../../roundcubemail/program/lib/Roundcube lib/ext/Roundcube +ln -s ../../../../roundcubemail/plugins lib/drivers/kolab/plugins +ln -s ../roundcubemail/vendor vendor +rm -R config +ln -s ../roundcubemail/config config +chmod 777 -R cache +chmod 777 -R logs +popd + + +# Install iRony +pushd iRony +rm -f lib/FileAPI lib/Roundcube lib/plugins vendor +ln -s ../../chwala/lib lib/FileAPI +ln -s ../../roundcubemail/program/lib/Roundcube lib/Roundcube +ln -s ../../roundcubemail/plugins lib/plugins +ln -s ../roundcubemail/vendor vendor +rm -R config +ln -s ../roundcubemail/config config +mkdir -p logs +chmod 777 -R logs +mkdir -p temp +chmod 777 -R temp +popd + + +# Install syncroton +pushd syncroton +rm -f lib/ext/Roundcube lib/plugins vendor +mkdir -p lib/ext +ln -s ../../../roundcubemail/program/lib/Roundcube lib/ext/Roundcube +ln -s ../../roundcubemail/plugins lib/plugins +ln -s ../roundcubemail/vendor vendor +rm -R config +ln -s ../roundcubemail/config config +chmod 777 -R logs +popd + +# Install autoconf +pushd autoconf +rm -f vendor +ln -s ../roundcubemail/vendor vendor +chmod 777 -R logs +popd + +# Install freebusy +pushd freebusy +rm -f vendor +ln -s ../roundcubemail/vendor vendor +mkdir -p logs +chmod 777 -R logs +popd