diff --git a/images/nginx/Dockerfile b/images/nginx/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..ae1f1037ccd4c96622b48730dc3c588dbb2db9a2 --- /dev/null +++ b/images/nginx/Dockerfile @@ -0,0 +1,34 @@ +ARG NGINX_VERSION + +FROM nginx:${NGINX_VERSION} + +LABEL io.k8s.description="Drupal managed infra nginx" \ + io.k8s.display-name="Drupal 8 Managed Infra nginx" \ + io.openshift.tags="managed,drupal,nginx" \ + maintainer="Drupal Admins <drupal-admins@cern.ch>" + +ENV DRUPAL_APP_DIR /app +ENV DRUPAL_CODE_DIR /code +ENV DRUPAL_SHARED_VOLUME /drupal-data + +# COPY --from=builder ${DRUPAL_CODE_DIR} ${DRUPAL_CODE_DIR} +# COPY --from=builder /fix-permissions /fix-permissions +# COPY --from=builder /init-app.sh /init-app.sh + +# NGINX Configuration +ADD config/nginx.conf /etc/nginx/nginx.conf +ADD config/default.conf /etc/nginx/conf.d/default.conf +### n.b.: https://www.redpill-linpro.com/sysadvent/2017/12/10/jekyll-openshift.html +RUN \ + mkdir -p /etc/nginx/ /var/run /var/cache/nginx /var/lib/nginx /var/log/nginx /var/tmp/nginx/ && \ + chgrp -R 0 /etc/nginx/ /var/run /var/cache/nginx /var/lib/nginx /var/log/nginx /var/tmp/nginx/ && \ + chmod -R g=u /etc/nginx/ /var/run /var/cache/nginx /var/lib/nginx /var/log/nginx /var/tmp/nginx/ + +WORKDIR ${DRUPAL_APP_DIR} +# Fix permissions on target folder to copy there drupal code. +# RUN /fix-permissions ${DRUPAL_APP_DIR} + +ADD run-nginx.sh / +RUN chmod +x /run-nginx.sh + +ENTRYPOINT ["/run-nginx.sh"] diff --git a/images/nginx/config/default.conf b/images/nginx/config/default.conf new file mode 100644 index 0000000000000000000000000000000000000000..7de3bd6d298f22d399aaa06a541c182c1bf141ff --- /dev/null +++ b/images/nginx/config/default.conf @@ -0,0 +1,135 @@ +upstream php { + server php-fpm:9000; +} + +server { + #listen 8080 ssl; + listen 8080; + + #ssl_certificate /etc/ssl/certs/ca-certificates.crt; + #ssl_certificate_key /etc/ssl/certs/ca-cert-COMODO_Certification_Authority.pem; + #ssl_session_cache shared:SSL:20m; + #ssl_session_timeout 4h; + + root /app/web; + + location = /favicon.ico { + log_not_found off; + access_log off; + } + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + # Very rarely should these ever be accessed outside of your lan + location ~* \.(txt|log)$ { + allow 192.168.0.0/16; + deny all; + } + + # https://drupal.stackexchange.com/questions/192151/cannot-install-any-theme + rewrite ^/core/authorize.php/core/authorize.php(.*)$ /core/authorize.php$1; + location ~ \..*/.*\.php$ { + return 403; + } + + location ~ ^/sites/.*/private/ { + return 403; + } + + # Block access to scripts in site files directory + location ~ ^/sites/[^/]+/files/.*\.php$ { + deny all; + } + + # Allow "Well-Known URIs" as per RFC 5785 + location ~* ^/.well-known/ { + allow all; + } + + # Block access to "hidden" files and directories whose names begin with a + # period. This includes directories used by version control systems such + # as Subversion or Git to store control files. + location ~ (^|/)\. { + return 403; + } + + location / { + # try_files $uri @rewrite; # For Drupal <= 6 + try_files $uri /index.php?$query_string; # For Drupal >= 7 + } + + location @rewrite { + rewrite ^/(.*)$ /index.php?q=$1; + } + + # Don't allow direct access to PHP files in the vendor directory. + location ~ /vendor/.*\.php$ { + deny all; + return 404; + } + + # In Drupal 8, we must also match new paths where the '.php' appears in + # the middle, such as update.php/selection. The rule we use is strict, + # and only allows this pattern with the update.php front controller. + # This allows legacy path aliases in the form of + # blog/index.php/legacy-path to continue to route to Drupal nodes. If + # you do not have any paths like that, then you might prefer to use a + # laxer rule, such as: + # location ~ \.php(/|$) { + # The laxer rule will continue to work if Drupal uses this new URL + # pattern with front controllers other than update.php in a future + # release. + location ~ '\.php$|^/update.php' { + fastcgi_split_path_info ^(.+?\.php)(|/.*)$; + # Security note: If you're running a version of PHP older than the + # latest 5.3, you should have "cgi.fix_pathinfo = 0;" in php.ini. + # See http://serverfault.com/q/627903/94922 for details. + include fastcgi_params; + # Block httpoxy attacks. See https://httpoxy.org/ . + fastcgi_param HTTP_PROXY ""; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param QUERY_STRING $query_string; + fastcgi_intercept_errors on; + # PHP 5 socket location. + #fastcgi_pass unix:/var/run/php5-fpm.sock; + # PHP 7 socket location. + fastcgi_pass php; + } + + # Fighting with Styles? This little gem is amazing. + # location ~ ^/sites/.*/files/imagecache/ { # For Drupal <= 6 + location ~ ^/sites/.*/files/styles/ { # For Drupal >= 7 + try_files $uri @rewrite; + } + + # Handle private files through Drupal. Private file's path can come + # with a language prefix. + location ~ ^(/[a-z\-]+)?/system/files/ { # For Drupal >= 7 + try_files $uri /index.php?$query_string; + } + + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { + try_files $uri @rewrite; + expires max; + log_not_found off; + } + + + location ^~ /simplesaml { + alias /app/vendor/simplesamlphp/simplesamlphp/www; + + location ~ ^(?<prefix>/simplesaml)(?<phpfile>.+?\.php)(?<pathinfo>/.*)?$ { + include fastcgi_params; + fastcgi_pass php; + fastcgi_index index.php; + fastcgi_split_path_info ^(.+?\.php)(/.+)$; + fastcgi_param SCRIPT_FILENAME $document_root$phpfile; + fastcgi_param PATH_INFO $pathinfo if_not_empty; + } + } +} \ No newline at end of file diff --git a/images/nginx/config/nginx.conf b/images/nginx/config/nginx.conf new file mode 100644 index 0000000000000000000000000000000000000000..3ae41bf88d0a710a3331a534b0de4d52dab7e918 --- /dev/null +++ b/images/nginx/config/nginx.conf @@ -0,0 +1,23 @@ +worker_processes 1; + +pid /var/run/nginx.pid; +error_log /dev/stderr debug; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /dev/stdout; + sendfile on; + + include /etc/nginx/conf.d/*.conf; + #https://serverfault.com/questions/587386/an-upstream-response-is-buffered-to-a-temporary-file + proxy_max_temp_file_size 0; +} \ No newline at end of file diff --git a/images/nginx/run-nginx.sh b/images/nginx/run-nginx.sh new file mode 100644 index 0000000000000000000000000000000000000000..bcdcbb97f22ba284e4b9fa6002d7339c78395462 --- /dev/null +++ b/images/nginx/run-nginx.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -ex + +# Setup drupal site +/init-app.sh + +# Run Nginx +exec nginx -g "daemon off;" \ No newline at end of file diff --git a/images/php-base/Dockerfile b/images/php-base/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..ede14dd275ef4326b113082911e1b978957d0ebd --- /dev/null +++ b/images/php-base/Dockerfile @@ -0,0 +1,70 @@ +# from https://www.drupal.org/docs/8/system-requirements/drupal-8-php-requirements +# from https://github.com/docker-library/docs/blob/master/php/README.md#supported-tags-and-respective-dockerfile-links +ARG PHP_VERSION + +FROM php:${PHP_VERSION} + +LABEL io.k8s.description="Drupal managed infra base" \ + io.k8s.display-name="Drupal 8 Managed Infra base" \ + io.openshift.tags="managed,drupal,php,nginx" \ + maintainer="Drupal Admins <drupal-admins@cern.ch>" + +# install some utils +RUN apk --update add \ + # Some composer packages need git + git \ + patch \ + curl \ + gettext \ + zip \ + unzip \ + mysql-client \ + jq \ + tzdata + +# Configured timezone. +ENV TZ=Europe/Zurich +RUN touch /usr/share/zoneinfo/$TZ \ + && cp /usr/share/zoneinfo/$TZ /etc/localtime \ + && echo $TZ > /etc/timezone && \ + apk del tzdata \ + && rm -rf /var/cache/apk/* + +# PHP FPM +RUN set -eux; \ + \ + apk add --no-cache --virtual .build-deps autoconf g++ make \ + coreutils \ + freetype-dev \ + libjpeg-turbo-dev \ + libpng-dev \ + libzip-dev \ + ; \ + \ + pecl install -o -f redis \ + ; \ + \ + rm -rf /tmp/pear \ + ; \ + \ + docker-php-ext-configure gd \ + --with-freetype-dir=/usr/include \ + --with-jpeg-dir=/usr/include \ + --with-png-dir=/usr/include \ + ; \ + \ + docker-php-ext-install -j "$(nproc)" \ + gd \ + opcache \ + pdo_mysql \ + zip \ + ; \ + \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --virtual .drupal-phpexts-rundeps $runDeps; \ + apk del .build-deps \ No newline at end of file diff --git a/images/php-fpm/Dockerfile b/images/php-fpm/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..2d740eddecd70a1d50a373a0906f6ad6f4e059c4 --- /dev/null +++ b/images/php-fpm/Dockerfile @@ -0,0 +1,38 @@ +ARG PHP_BASE_VERSION + +FROM gitlab-registry.cern.ch/drupal/paas/dmi/php-base:${PHP_BASE_VERSION} + +LABEL io.k8s.description="Drupal managed infra php-fpm" \ + io.k8s.display-name="Drupal 8 Managed Infra php-fpm" \ + io.openshift.tags="managed,drupal,php-fpm" \ + maintainer="Drupal Admins <drupal-admins@cern.ch>" + +# DRUPAL specific. Include drupal tools in the PATH +# DRUPAL_APP_DIR path must be in consoncance with Nginx configuration +ENV DRUPAL_APP_DIR /app +ENV DRUPAL_CODE_DIR /code +ENV DRUPAL_SHARED_VOLUME /drupal-data + +# COPY --from=builder ${DRUPAL_CODE_DIR} ${DRUPAL_CODE_DIR} +# COPY --from=builder /fix-permissions /fix-permissions +# COPY --from=builder /init-app.sh /init-app.sh + +WORKDIR ${DRUPAL_APP_DIR} +# Fix permissions on target folder to copy there drupal code. +# RUN /fix-permissions ${DRUPAL_APP_DIR} + +# Add extra configurations +# At this point, composer has created the required settings.php through post-update-cmd: DrupalProject\composer\ScriptHandler::createRequiredFiles +# Overwrite settings.php with ours. +# - php-fpm +ADD config/php-fpm/ /usr/local/etc/php-fpm.d/ +# - Simplesamlphp +ADD config/simplesamlphp/ ${DRUPAL_CODE_DIR}/vendor/simplesamlphp/simplesamlphp/ +# - opcache +ADD config/opcache/ /usr/local/etc/php/conf.d/ + + +ADD run-php-fpm.sh hooks/post-hook.sh / +RUN chmod +x /run-php-fpm.sh /post-hook.sh + +ENTRYPOINT ["/run-php-fpm.sh"] \ No newline at end of file diff --git a/images/php-fpm/config/opcache/opcache-recommended.ini b/images/php-fpm/config/opcache/opcache-recommended.ini new file mode 100644 index 0000000000000000000000000000000000000000..632a1e5a8ae71631ae6753563b9ef28f20a31bf3 --- /dev/null +++ b/images/php-fpm/config/opcache/opcache-recommended.ini @@ -0,0 +1,8 @@ +# set recommended PHP.ini settings +# see https://secure.php.net/manual/en/opcache.installation.php +opcache.memory_consumption=128 +opcache.interned_strings_buffer=8 +opcache.max_accelerated_files=4000 +opcache.revalidate_freq=60 +opcache.fast_shutdown=1 +opcache.enable_cli=1 \ No newline at end of file diff --git a/images/php-fpm/config/php-fpm/www.conf b/images/php-fpm/config/php-fpm/www.conf new file mode 100644 index 0000000000000000000000000000000000000000..6a36b265a45a23d4f011d469ae313c201ebecddc --- /dev/null +++ b/images/php-fpm/config/php-fpm/www.conf @@ -0,0 +1,11 @@ +[www] +listen = 9000 +pm = dynamic +pm.max_children = 5 +pm.start_servers = 2 +pm.min_spare_servers = 1 +pm.max_spare_servers = 3 +catch_workers_output = yes +php_admin_value[error_log] = /var/log/fpm-php.www.log +php_admin_flag[log_errors] = on +access.log = /proc/self/fd/2 \ No newline at end of file diff --git a/images/php-fpm/config/simplesamlphp/attributemap/cern2name.php b/images/php-fpm/config/simplesamlphp/attributemap/cern2name.php new file mode 100644 index 0000000000000000000000000000000000000000..1e3c2a433fe3a534d02b384dbc5fb566c9986f90 --- /dev/null +++ b/images/php-fpm/config/simplesamlphp/attributemap/cern2name.php @@ -0,0 +1,16 @@ +<?php +$attributemap = array( + 'http://schemas.xmlsoap.org/claims/EmailAddress' => 'email', + 'http://schemas.xmlsoap.org/claims/CommonName' => 'login', + 'http://schemas.xmlsoap.org/claims/Group' => 'egroups', + 'http://schemas.xmlsoap.org/claims/DisplayName' => 'fullname', + 'http://schemas.xmlsoap.org/claims/PhoneNumber' => 'phonenumber', + 'http://schemas.xmlsoap.org/claims/Building' => 'building', + 'http://schemas.xmlsoap.org/claims/Firstname' => 'firstname', + 'http://schemas.xmlsoap.org/claims/Lastname' => 'lastname', + 'http://schemas.xmlsoap.org/claims/Department' => 'department', + 'http://schemas.xmlsoap.org/claims/HomeInstitute' => 'homeinstitute', + 'http://schemas.xmlsoap.org/claims/PersonID' => 'personid', + 'http://schemas.xmlsoap.org/claims/PreferredLanguage' => 'preferredlanguage', + 'http://schemas.xmlsoap.org/claims/IdentityClass' => 'identityclass', +); \ No newline at end of file diff --git a/images/php-fpm/config/simplesamlphp/config/acl.php b/images/php-fpm/config/simplesamlphp/config/acl.php new file mode 100644 index 0000000000000000000000000000000000000000..558466f837f8c2f38e4e2c049d9873697d36fb46 --- /dev/null +++ b/images/php-fpm/config/simplesamlphp/config/acl.php @@ -0,0 +1,58 @@ +<?php +/* +* This file defines "named" access control lists, which can +* be reused in several places. +*/ +$config = array( + 'adminlist' => array( + //array('allow', 'equals', 'mail', 'admin1@example.org'), + //array('allow', 'has', 'groups', 'admin'), + // The default action is to deny access. + ), + + 'example-simple' => array( + array('allow', 'equals', 'mail', 'admin1@example.org'), + array('allow', 'equals', 'mail', 'admin2@example.org'), + // The default action is to deny access. + ), + + 'example-deny-some' => array( + array('deny', 'equals', 'mail', 'eviluser@example.org'), + array('allow'), // Allow everybody else. + ), + + 'example-maildomain' => array( + array('allow', 'equals-preg', 'mail', '/@example\.org$/'), + // The default action is to deny access. + ), + + 'example-allow-employees' => array( + array('allow', 'has', 'eduPersonAffiliation', 'employee'), + // The default action is to deny access. + ), + + 'example-allow-employees-not-students' => array( + array('deny', 'has', 'eduPersonAffiliation', 'student'), + array('allow', 'has', 'eduPersonAffiliation', 'employee'), + // The default action is to deny access. + ), + + 'example-deny-student-except-one' => array( + array('deny', 'and', + array('has', 'eduPersonAffiliation', 'student'), + array('not', 'equals', 'mail', 'user@example.org'), + ), + array('allow'), + ), + + 'example-allow-or' => array( + array('allow', 'or', + array('equals', 'eduPersonAffiliation', 'student', 'member'), + array('equals', 'mail', 'someuser@example2.org'), + ), + ), + + 'example-allow-all' => array( + array('allow'), + ), +); diff --git a/images/php-fpm/config/simplesamlphp/config/authsources.php b/images/php-fpm/config/simplesamlphp/config/authsources.php new file mode 100644 index 0000000000000000000000000000000000000000..3850929537c24c278924d8d6318e6267c0d24f32 --- /dev/null +++ b/images/php-fpm/config/simplesamlphp/config/authsources.php @@ -0,0 +1,23 @@ +<?php +$config = array( + // This is a authentication source which handles admin authentication. + 'admin' => array( + // The default is to use core:AdminPassword, but it can be replaced with + // any authentication source. + + 'core:AdminPassword', + ), + + 'cern-sp' => array ( + 'saml:SP', + 'base64attributes' => true, + 'attributeencodings' => 'base64', + 'entityID' => getenv('HOSTNAME'), + 'idp' => 'https://cern.ch/login' , + 'discoURL' => NULL, + 'privatekey' => '/tmp/simplesamlcert/saml.pem', + 'certificate' => '/tmp/simplesamlcert/saml.crt', + 'sign.logout' => true, + 'signature.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' , + ), +); diff --git a/images/php-fpm/config/simplesamlphp/config/autmemcookie.php b/images/php-fpm/config/simplesamlphp/config/autmemcookie.php new file mode 100644 index 0000000000000000000000000000000000000000..04f6d088a28b1e10717316bc386a23cab59ef885 --- /dev/null +++ b/images/php-fpm/config/simplesamlphp/config/autmemcookie.php @@ -0,0 +1,74 @@ +<?php +/** +* This is the configuration file for the Auth MemCookie example. +*/ + +$config = array( + +/* +* The authentication source that should be used. +* +* This must be one of the authentication sources configured in config/authsources.php. +*/ +//'authsource' => 'cern-sp', +'authsource' => 'default-sp', + +/* +* This is the name of the cookie we should save the session id in. The value of this option must match the +* Auth_memCookie_CookieName option in the Auth MemCookie configuration. The default value is 'AuthMemCookie'. +* +* Default: +* 'cookiename' => 'AuthMemCookie', +*/ +'cookiename' => 'AuthMemCookie', + +/* +* This option specifies the name of the attribute which contains the username of the user. It must be set to +* a valid attribute name. +* +* Examples: +* 'username' => 'uid', // LDAP attribute for user id. +* 'username' => 'mail', // LDAP attribute for email address. +* +* Default: +* No default value. +*/ +'username' => null, + +/* +* This option specifies the name of the attribute which contains the groups of the user. Set this option to +* NULL if you don't want to include any groups. +* +* Example: +* 'groups' => 'edupersonaffiliation', +* +* Default: +* 'groups' => null, +*/ +'groups' => null, + +/* +* This option contains the hostnames or IP addresses of the memcache servers where we should store the +* authentication information. Separator is a comma. This option should match the address part of the +* Auth_memCookie_Memcached_AddrPort option in the Auth MemCookie configuration. +* +* Examples: +* 'memcache.host' => '192.168.93.52', +* 'memcache.host' => 'memcache.example.org', +* 'memcache.host' => 'memcache1.example.org,memcache2.example.org' +* +* Default: +* 'memcache.host' => '127.0.0.1', +*/ +'memcache.host' => '127.0.0.1', + +/* +* This option contains the port number of the memcache server where we should store the +* authentication information. This option should match the port part of the +* Auth_memCookie_Memcached_AddrPort option in the Auth MemCookie configuration. +* +* Default: +* 'memcache.port' => 11211, +*/ +'memcache.port' => 11211, +); \ No newline at end of file diff --git a/images/php-fpm/config/simplesamlphp/config/config.php b/images/php-fpm/config/simplesamlphp/config/config.php new file mode 100644 index 0000000000000000000000000000000000000000..ba3c9f088ce49a19f014fbf60a1ec15dd2af4773 --- /dev/null +++ b/images/php-fpm/config/simplesamlphp/config/config.php @@ -0,0 +1,1078 @@ +<?php +/* +* The configuration of SimpleSAMLphp +* +*/ + +$config = array( + + /******************************* + | BASIC CONFIGURATION OPTIONS | + *******************************/ + + /* + * Setup the following parameters to match your installation. + * See the user manual for more details. + */ + + /* + * baseurlpath is a *URL path* (not a filesystem path). + * A valid format for 'baseurlpath' is: + * [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/] + * + * The full url format is useful if your SimpleSAMLphp setup is hosted behind + * a reverse proxy. In that case you can specify the external url here. + * + * Please note that SimpleSAMLphp will then redirect all queries to the + * external url, no matter where you come from (direct access or via the + * reverse proxy). + */ + //'baseurlpath' => 'simplesaml/', + 'baseurlpath' => 'https://' . $_SERVER['HOSTNAME'] . '/simplesaml/', + + /* + * The following settings are *filesystem paths* which define where + * SimpleSAMLphp can find or write the following things: + * - 'certdir': The base directory for certificate and key material. + * - 'loggingdir': Where to write logs. + * - 'datadir': Storage of general data. + * - 'temdir': Saving temporary files. SimpleSAMLphp will attempt to create + * this directory if it doesn't exist. + * When specified as a relative path, this is relative to the SimpleSAMLphp + * root directory. + */ + 'certdir' => 'cert/', + 'loggingdir' => 'log/', + 'datadir' => 'data/', + 'tempdir' => '/tmp/simplesaml', + + /* + * Some information about the technical persons running this installation. + * The email address will be used as the recipient address for error reports, and + * also as the technical contact in generated metadata. + */ + 'technicalcontact_name' => 'Drupal Administrators', + 'technicalcontact_email' => 'drupal-admins@cern.ch', + + /* + * The envelope from address for outgoing emails. + * This should be in a domain that has your application's IP addresses in its SPF record + * to prevent it from being rejected by mail filters. + */ + //'sendmail_from' => 'no-reply@example.org', + + /* + * The timezone of the server. This option should be set to the timezone you want + * SimpleSAMLphp to report the time in. The default is to guess the timezone based + * on your system timezone. + * + * See this page for a list of valid timezones: http://php.net/manual/en/timezones.php + */ + 'timezone' => 'Europe/Zurich', + + + + /********************************** + | SECURITY CONFIGURATION OPTIONS | + **********************************/ + + /* + * This is a secret salt used by SimpleSAMLphp when it needs to generate a secure hash + * of a value. It must be changed from its default value to a secret value. The value of + * 'secretsalt' can be any valid string of any length. + * + * A possible way to generate a random salt is by running the following command from a unix shell: + * LC_CTYPE=C tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo + */ + //'secretsalt' => 'defaultsecretsalt', + 'secretsalt' => getenv('SECRETSALT'), + + /* + * This password must be kept secret, and modified from the default value 123. + * This password will give access to the installation page of SimpleSAMLphp with + * metadata listing and diagnostics pages. + * You can also put a hash here; run "bin/pwgen.php" to generate one. + */ + //'auth.adminpassword' => '123', + 'auth.adminpassword' => getenv('AUTH_ADMINPASSWORD'), + + /* + * Set this options to true if you want to require administrator password to access the web interface + * or the metadata pages, respectively. + */ + 'admin.protectindexpage' => false, + 'admin.protectmetadata' => false, + + /* + * Set this option to false if you don't want SimpleSAMLphp to check for new stable releases when + * visiting the configuration tab in the web interface. + */ + 'admin.checkforupdates' => true, + + /* + * Array of domains that are allowed when generating links or redirects + * to URLs. SimpleSAMLphp will use this option to determine whether to + * to consider a given URL valid or not, but you should always validate + * URLs obtained from the input on your own (i.e. ReturnTo or RelayState + * parameters obtained from the $_REQUEST array). + * + * SimpleSAMLphp will automatically add your own domain (either by checking + * it dynamically, or by using the domain defined in the 'baseurlpath' + * directive, the latter having precedence) to the list of trusted domains, + * in case this option is NOT set to NULL. In that case, you are explicitly + * telling SimpleSAMLphp to verify URLs. + * + * Set to an empty array to disallow ALL redirects or links pointing to + * an external URL other than your own domain. This is the default behaviour. + * + * Set to NULL to disable checking of URLs. DO NOT DO THIS UNLESS YOU KNOW + * WHAT YOU ARE DOING! + * + * Example: + * 'trusted.url.domains' => array('sp.example.com', 'app.example.com'), + */ + 'trusted.url.domains' => array(), + + /* + * Enable regular expression matching of trusted.url.domains. + * + * Set to true to treat the values in trusted.url.domains as regular + * expressions. Set to false to do exact string matching. + * + * If enabled, the start and end delimiters ('^' and '$') will be added to + * all regular expressions in trusted.url.domains. + */ + 'trusted.url.regex' => false, + + /* + * Enable secure POST from HTTPS to HTTP. + * + * If you have some SP's on HTTP and IdP is normally on HTTPS, this option + * enables secure POSTing to HTTP endpoint without warning from browser. + * + * For this to work, module.php/core/postredirect.php must be accessible + * also via HTTP on IdP, e.g. if your IdP is on + * https://idp.example.org/ssp/ , then + * http://idp.example.org/ssp/module.php/core/postredirect.php must be accessible. + */ + 'enable.http_post' => false, + + + + /************************ + | ERRORS AND DEBUGGING | + ************************/ + + /* + * The 'debug' option allows you to control how SimpleSAMLphp behaves in certain + * situations where further action may be taken + * + * It can be left unset, in which case, debugging is switched off for all actions. + * If set, it MUST be an array containing the actions that you want to enable, or + * alternatively a hashed array where the keys are the actions and their + * corresponding values are booleans enabling or disabling each particular action. + * + * SimpleSAMLphp provides some pre-defined actiones, though modules could add new + * actions here. Refer to the documentation of every module to learn if they + * allow you to set any more debugging actions. + * + * The pre-defined actions are: + * + * - 'saml': this action controls the logging of SAML messages exchanged with other + * entities. When enabled ('saml' is present in this option, or set to true), all + * SAML messages will be logged, including plaintext versions of encrypted + * messages. + * + * - 'backtraces': this action controls the logging of error backtraces. If you + * want to log backtraces so that you can debug any possible errors happening in + * SimpleSAMLphp, enable this action (add it to the array or set it to true). + * + * - 'validatexml': this action allows you to validate SAML documents against all + * the relevant XML schemas. SAML 1.1 messages or SAML metadata parsed with + * the XML to SimpleSAMLphp metadata converter or the metaedit module will + * validate the SAML documents if this option is enabled. + * + * If you want to disable debugging completely, unset this option or set it to an + * empty array. + */ + 'debug' => array( + 'saml' => true, + 'backtraces' => true, + 'validatexml' => true, + ), + + /* + * When 'showerrors' is enabled, all error messages and stack traces will be output + * to the browser. + * + * When 'errorreporting' is enabled, a form will be presented for the user to report + * the error to 'technicalcontact_email'. + */ + 'showerrors' => true, + 'errorreporting' => true, + + /* + * Custom error show function called from SimpleSAML_Error_Error::show. + * See docs/simplesamlphp-errorhandling.txt for function code example. + * + * Example: + * 'errors.show_function' => array('sspmod_example_Error_Show', 'show'), + */ + + + + /************************** + | LOGGING AND STATISTICS | + **************************/ + + /* + * Define the minimum log level to log. Available levels: + * - SimpleSAML\Logger::ERR No statistics, only errors + * - SimpleSAML\Logger::WARNING No statistics, only warnings/errors + * - SimpleSAML\Logger::NOTICE Statistics and errors + * - SimpleSAML\Logger::INFO Verbose logs + * - SimpleSAML\Logger::DEBUG Full debug logs - not recommended for production + * + * Choose logging handler. + * + * Options: [syslog,file,errorlog] + * + */ + 'logging.level' => SimpleSAML\Logger::DEBUG, + 'logging.handler' => 'errorlog', + + /* + * Specify the format of the logs. Its use varies depending on the log handler used (for instance, you cannot + * control here how dates are displayed when using the syslog or errorlog handlers), but in general the options + * are: + * + * - %date{<format>}: the date and time, with its format specified inside the brackets. See the PHP documentation + * of the strftime() function for more information on the format. If the brackets are omitted, the standard + * format is applied. This can be useful if you just want to control the placement of the date, but don't care + * about the format. + * + * - %process: the name of the SimpleSAMLphp process. Remember you can configure this in the 'logging.processname' + * option below. + * + * - %level: the log level (name or number depending on the handler used). + * + * - %stat: if the log entry is intended for statistical purposes, it will print the string 'STAT ' (bear in mind + * the trailing space). + * + * - %trackid: the track ID, an identifier that allows you to track a single session. + * + * - %srcip: the IP address of the client. If you are behind a proxy, make sure to modify the + * $_SERVER['REMOTE_ADDR'] variable on your code accordingly to the X-Forwarded-For header. + * + * - %msg: the message to be logged. + * + */ + //'logging.format' => '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg', + + /* + * Choose which facility should be used when logging with syslog. + * + * These can be used for filtering the syslog output from SimpleSAMLphp into its + * own file by configuring the syslog daemon. + * + * See the documentation for openlog (http://php.net/manual/en/function.openlog.php ) for available + * facilities. Note that only LOG_USER is valid on windows. + * + * The default is to use LOG_LOCAL5 if available, and fall back to LOG_USER if not. + */ + 'logging.facility' => defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER, + + /* + * The process name that should be used when logging to syslog. + * The value is also written out by the other logging handlers. + */ + 'logging.processname' => 'simplesamlphp', + + /* + * Logging: file - Logfilename in the loggingdir from above. + */ + 'logging.logfile' => 'simplesamlphp.log', + + /* + * This is an array of outputs. Each output has at least a 'class' option, which + * selects the output. + */ + 'statistics.out' => array(// Log statistics to the normal log. + /* + array( + 'class' => 'core:Log', + 'level' => 'notice', + ), + */ + // Log statistics to files in a directory. One file per day. + /* + array( + 'class' => 'core:File', + 'directory' => '/var/log/stats', + ), + */ + ), + + + + /*********************** + | PROXY CONFIGURATION | + ***********************/ + + /* + * Proxy to use for retrieving URLs. + * + * Example: + * 'proxy' => 'tcp://proxy.example.com:5100' + */ + 'proxy' => null, + + /* + * Username/password authentication to proxy (Proxy-Authorization: Basic) + * Example: + * 'proxy.auth' = 'myuser:password' + */ + //'proxy.auth' => 'myuser:password', + + + + /************************** + | DATABASE CONFIGURATION | + **************************/ + + /* + * This database configuration is optional. If you are not using + * core functionality or modules that require a database, you can + * skip this configuration. + */ + + /* + * Database connection string. + * Ensure that you have the required PDO database driver installed + * for your connection string. + */ + 'database.dsn' => 'mysql:host=localhost;dbname=saml', + + /* + * SQL database credentials + */ + 'database.username' => 'simplesamlphp', + 'database.password' => 'secret', + 'database.options' => array(), + + /* + * (Optional) Table prefix + */ + 'database.prefix' => '', + + /* + * True or false if you would like a persistent database connection + */ + 'database.persistent' => false, + + /* + * Database slave configuration is optional as well. If you are only + * running a single database server, leave this blank. If you have + * a master/slave configuration, you can define as many slave servers + * as you want here. Slaves will be picked at random to be queried from. + * + * Configuration options in the slave array are exactly the same as the + * options for the master (shown above) with the exception of the table + * prefix. + */ + 'database.slaves' => array( + /* + array( + 'dsn' => 'mysql:host=myslave;dbname=saml', + 'username' => 'simplesamlphp', + 'password' => 'secret', + 'persistent' => false, + ), + */ + ), + + + + /************* + | PROTOCOLS | + *************/ + + /* + * Which functionality in SimpleSAMLphp do you want to enable. Normally you would enable only + * one of the functionalities below, but in some cases you could run multiple functionalities. + * In example when you are setting up a federation bridge. + */ + 'enable.saml20-idp' => false, + 'enable.shib13-idp' => false, + 'enable.adfs-idp' => false, + 'enable.wsfed-sp' => false, + 'enable.authmemcookie' => false, + + /* + * Default IdP for WS-Fed. + */ + 'default-wsfed-idp' => 'urn:federation:pingfederate:localhost', + + /* + * Whether SimpleSAMLphp should sign the response or the assertion in SAML 1.1 authentication + * responses. + * + * The default is to sign the assertion element, but that can be overridden by setting this + * option to TRUE. It can also be overridden on a pr. SP basis by adding an option with the + * same name to the metadata of the SP. + */ + 'shib13.signresponse' => true, + + + + /*********** + | MODULES | + ***********/ + + /* + * Configuration to override module enabling/disabling. + * + * Example: + * + * 'module.enable' => array( + * 'exampleauth' => TRUE, // Setting to TRUE enables. + * 'saml' => FALSE, // Setting to FALSE disables. + * 'core' => NULL, // Unset or NULL uses default. + * ), + * + */ + + + + /************************* + | SESSION CONFIGURATION | + *************************/ + + /* + * This value is the duration of the session in seconds. Make sure that the time duration of + * cookies both at the SP and the IdP exceeds this duration. + */ + 'session.duration' => 8 * (60 * 60), // 8 hours. + + /* + * Sets the duration, in seconds, data should be stored in the datastore. As the data store is used for + * login and logout requests, this option will control the maximum time these operations can take. + * The default is 4 hours (4*60*60) seconds, which should be more than enough for these operations. + */ + 'session.datastore.timeout' => (4 * 60 * 60), // 4 hours + + /* + * Sets the duration, in seconds, auth state should be stored. + */ + 'session.state.timeout' => (60 * 60), // 1 hour + + /* + * Option to override the default settings for the session cookie name + */ + 'session.cookie.name' => 'SimpleSAMLSessionID', + + /* + * Expiration time for the session cookie, in seconds. + * + * Defaults to 0, which means that the cookie expires when the browser is closed. + * + * Example: + * 'session.cookie.lifetime' => 30*60, + */ + 'session.cookie.lifetime' => 0, + + /* + * Limit the path of the cookies. + * + * Can be used to limit the path of the cookies to a specific subdirectory. + * + * Example: + * 'session.cookie.path' => '/simplesaml/', + */ + 'session.cookie.path' => '/', + + /* + * Cookie domain. + * + * Can be used to make the session cookie available to several domains. + * + * Example: + * 'session.cookie.domain' => '.example.org', + */ + 'session.cookie.domain' => null, + + /* + * Set the secure flag in the cookie. + * + * Set this to TRUE if the user only accesses your service + * through https. If the user can access the service through + * both http and https, this must be set to FALSE. + */ + 'session.cookie.secure' => false, + + /* + * Options to override the default settings for php sessions. + */ + 'session.phpsession.cookiename' => 'SimpleSAML', + 'session.phpsession.savepath' => null, + 'session.phpsession.httponly' => true, + + /* + * Option to override the default settings for the auth token cookie + */ + 'session.authtoken.cookiename' => 'SimpleSAMLAuthToken', + + /* + * Options for remember me feature for IdP sessions. Remember me feature + * has to be also implemented in authentication source used. + * + * Option 'session.cookie.lifetime' should be set to zero (0), i.e. cookie + * expires on browser session if remember me is not checked. + * + * Session duration ('session.duration' option) should be set according to + * 'session.rememberme.lifetime' option. + * + * It's advised to use remember me feature with session checking function + * defined with 'session.check_function' option. + */ + 'session.rememberme.enable' => false, + 'session.rememberme.checked' => false, + 'session.rememberme.lifetime' => (14 * 86400), + + /* + * Custom function for session checking called on session init and loading. + * See docs/simplesamlphp-advancedfeatures.txt for function code example. + * + * Example: + * 'session.check_function' => array('sspmod_example_Util', 'checkSession'), + */ + + + + /************************** + | MEMCACHE CONFIGURATION | + **************************/ + + /* + * Configuration for the 'memcache' session store. This allows you to store + * multiple redundant copies of sessions on different memcache servers. + * + * 'memcache_store.servers' is an array of server groups. Every data + * item will be mirrored in every server group. + * + * Each server group is an array of servers. The data items will be + * load-balanced between all servers in each server group. + * + * Each server is an array of parameters for the server. The following + * options are available: + * - 'hostname': This is the hostname or ip address where the + * memcache server runs. This is the only required option. + * - 'port': This is the port number of the memcache server. If this + * option isn't set, then we will use the 'memcache.default_port' + * ini setting. This is 11211 by default. + * - 'weight': This sets the weight of this server in this server + * group. http://php.net/manual/en/function.Memcache-addServer.php + * contains more information about the weight option. + * - 'timeout': The timeout for this server. By default, the timeout + * is 3 seconds. + * + * Example of redundant configuration with load balancing: + * This configuration makes it possible to lose both servers in the + * a-group or both servers in the b-group without losing any sessions. + * Note that sessions will be lost if one server is lost from both the + * a-group and the b-group. + * + * 'memcache_store.servers' => array( + * array( + * array('hostname' => 'mc_a1'), + * array('hostname' => 'mc_a2'), + * ), + * array( + * array('hostname' => 'mc_b1'), + * array('hostname' => 'mc_b2'), + * ), + * ), + * + * Example of simple configuration with only one memcache server, + * running on the same computer as the web server: + * Note that all sessions will be lost if the memcache server crashes. + * + * 'memcache_store.servers' => array( + * array( + * array('hostname' => 'localhost'), + * ), + * ), + * + */ + 'memcache_store.servers' => array( + array( + array('hostname' => 'localhost'), + ), + ), + + /* + * This value allows you to set a prefix for memcache-keys. The default + * for this value is 'simpleSAMLphp', which is fine in most cases. + * + * When running multiple instances of SSP on the same host, and more + * than one instance is using memcache, you probably want to assign + * a unique value per instance to this setting to avoid data collision. + */ + 'memcache_store.prefix' => '', + + /* + * This value is the duration data should be stored in memcache. Data + * will be dropped from the memcache servers when this time expires. + * The time will be reset every time the data is written to the + * memcache servers. + * + * This value should always be larger than the 'session.duration' + * option. Not doing this may result in the session being deleted from + * the memcache servers while it is still in use. + * + * Set this value to 0 if you don't want data to expire. + * + * Note: The oldest data will always be deleted if the memcache server + * runs out of storage space. + */ + 'memcache_store.expires' => 36 * (60 * 60), // 36 hours. + + + + /************************************* + | LANGUAGE AND INTERNATIONALIZATION | + *************************************/ + + /* + * Language-related options. + */ + 'language' => array( + /* + * An array in the form 'language' => <list of alternative languages>. + * + * Each key in the array is the ISO 639 two-letter code for a language, + * and its value is an array with a list of alternative languages that + * can be used if the given language is not available at some point. + * Each alternative language is also specified by its ISO 639 code. + * + * For example, for the "no" language code (Norwegian), we would have: + * + * 'priorities' => array( + * 'no' => array('nb', 'nn', 'en', 'se'), + * ... + * ), + * + * establishing that if a translation for the "no" language code is + * not available, we look for translations in "nb" (Norwegian Bokmal), + * and so on, in that order. + */ + 'priorities' => array( + 'no' => array('nb', 'nn', 'en', 'se'), + 'nb' => array('no', 'nn', 'en', 'se'), + 'nn' => array('no', 'nb', 'en', 'se'), + 'se' => array('nb', 'no', 'nn', 'en'), + ), + ), + + /* + * Languages available, RTL languages, and what language is the default. + */ + 'language.available' => array( + 'en', 'no', 'nn', 'se', 'da', 'de', 'sv', 'fi', 'es', 'ca', 'fr', 'it', 'nl', 'lb', + 'cs', 'sl', 'lt', 'hr', 'hu', 'pl', 'pt', 'pt-br', 'tr', 'ja', 'zh', 'zh-tw', 'ru', + 'et', 'he', 'id', 'sr', 'lv', 'ro', 'eu', 'el', 'af' + ), + 'language.rtl' => array('ar', 'dv', 'fa', 'ur', 'he'), + 'language.default' => 'en', + + /* + * Options to override the default settings for the language parameter + */ + 'language.parameter.name' => 'language', + 'language.parameter.setcookie' => true, + + /* + * Options to override the default settings for the language cookie + */ + 'language.cookie.name' => 'language', + 'language.cookie.domain' => null, + 'language.cookie.path' => '/', + 'language.cookie.secure' => false, + 'language.cookie.httponly' => false, + 'language.cookie.lifetime' => (60 * 60 * 24 * 900), + + /* + * Which i18n backend to use. + * + * "SimpleSAMLphp" is the home made system, valid for 1.x. + * For 2.x, only "gettext/gettext" will be possible. + * + * Home-made templates will always use "SimpleSAMLphp". + * To use twig (where avaliable), select "gettext/gettext". + */ + 'language.i18n.backend' => 'SimpleSAMLphp', + + /** + * Custom getLanguage function called from SimpleSAML\Locale\Language::getLanguage(). + * Function should return language code of one of the available languages or NULL. + * See SimpleSAML\Locale\Language::getLanguage() source code for more info. + * + * This option can be used to implement a custom function for determining + * the default language for the user. + * + * Example: + * 'language.get_language_function' => array('sspmod_example_Template', 'getLanguage'), + */ + + /* + * Extra dictionary for attribute names. + * This can be used to define local attributes. + * + * The format of the parameter is a string with <module>:<dictionary>. + * + * Specifying this option will cause us to look for modules/<module>/dictionaries/<dictionary>.definition.json + * The dictionary should look something like: + * + * { + * "firstattribute": { + * "en": "English name", + * "no": "Norwegian name" + * }, + * "secondattribute": { + * "en": "English name", + * "no": "Norwegian name" + * } + * } + * + * Note that all attribute names in the dictionary must in lowercase. + * + * Example: 'attributes.extradictionary' => 'ourmodule:ourattributes', + */ + 'attributes.extradictionary' => null, + + + + /************** + | APPEARANCE | + **************/ + + /* + * Which theme directory should be used? + */ + 'theme.use' => 'default', + + /* + * Templating options + * + * By default, twig templates are not cached. To turn on template caching: + * Set 'template.cache' to an absolute path pointing to a directory that + * SimpleSAMLphp has read and write permissions to. + */ + //'template.cache' => '', + + /* + * Set the 'template.auto_reload' to true if you would like SimpleSAMLphp to + * recompile the templates (when using the template cache) if the templates + * change. If you don't want to check the source templates for every request, + * set it to false. + */ + 'template.auto_reload' => false, + + /* + * Set this option to true to indicate that your installation of SimpleSAMLphp + * is running in a production environment. This will affect the way resources + * are used, offering an optimized version when running in production, and an + * easy-to-debug one when not. Set it to false when you are testing or + * developing the software. + * + * Defaults to true. + */ + 'production' => true, + + + + /********************* + | DISCOVERY SERVICE | + *********************/ + + /* + * Whether the discovery service should allow the user to save his choice of IdP. + */ + 'idpdisco.enableremember' => true, + 'idpdisco.rememberchecked' => true, + + /* + * The disco service only accepts entities it knows. + */ + 'idpdisco.validate' => true, + + 'idpdisco.extDiscoveryStorage' => null, + + /* + * IdP Discovery service look configuration. + * Wether to display a list of idp or to display a dropdown box. For many IdP' a dropdown box + * gives the best use experience. + * + * When using dropdown box a cookie is used to highlight the previously chosen IdP in the dropdown. + * This makes it easier for the user to choose the IdP + * + * Options: [links,dropdown] + */ + 'idpdisco.layout' => 'dropdown', + + + + /************************************* + | AUTHENTICATION PROCESSING FILTERS | + *************************************/ + + /* + * Authentication processing filters that will be executed for all IdPs + * Both Shibboleth and SAML 2.0 + */ + 'authproc.idp' => array( + /* Enable the authproc filter below to add URN prefixes to all attributes + /*10 => array( + 'class' => 'core:AttributeMap', 'addurnprefix' + ), */ + /* Enable the authproc filter below to automatically generated eduPersonTargetedID. + 20 => 'core:TargetedID', + */ + + // Adopts language from attribute to use in UI + 30 => 'core:LanguageAdaptor', + + 45 => array( + 'class' => 'core:StatisticsWithAttribute', + 'attributename' => 'realm', + 'type' => 'saml20-idp-SSO', + ), + + /* When called without parameters, it will fallback to filter attributes <the old way> + * by checking the 'attributes' parameter in metadata on IdP hosted and SP remote. + */ + 50 => 'core:AttributeLimit', + + /* + * Search attribute "distinguishedName" for pattern and replaces if found + + 60 => array( + 'class' => 'core:AttributeAlter', + 'pattern' => '/OU=studerende/', + 'replacement' => 'Student', + 'subject' => 'distinguishedName', + '%replace', + ), + */ + + /* + * Consent module is enabled (with no permanent storage, using cookies). + + 90 => array( + 'class' => 'consent:Consent', + 'store' => 'consent:Cookie', + 'focus' => 'yes', + 'checked' => TRUE + ), + */ + // If language is set in Consent module it will be added as an attribute. + 99 => 'core:LanguageAdaptor', + ), + + /* + * Authentication processing filters that will be executed for all SPs + * Both Shibboleth and SAML 2.0 + */ + 'authproc.sp' => array( + /* + 10 => array( + 'class' => 'core:AttributeMap', 'removeurnprefix' + ), + */ + + 10 => array( + 'class' => 'core:AttributeMap', + 'cern2name', + ), + + /* + * Generate the 'group' attribute populated from other variables, including eduPersonAffiliation. + 60 => array( + 'class' => 'core:GenerateGroups', 'eduPersonAffiliation' + ), + */ + /* + * All users will be members of 'users' and 'members' + 61 => array( + 'class' => 'core:AttributeAdd', 'groups' => array('users', 'members') + ), + */ + + // Adopts language from attribute to use in UI + 90 => 'core:LanguageAdaptor', + + ), + + + + /************************** + | METADATA CONFIGURATION | + **************************/ + + /* + * This option configures the metadata sources. The metadata sources is given as an array with + * different metadata sources. When searching for metadata, SimpleSAMLphp will search through + * the array from start to end. + * + * Each element in the array is an associative array which configures the metadata source. + * The type of the metadata source is given by the 'type' element. For each type we have + * different configuration options. + * + * Flat file metadata handler: + * - 'type': This is always 'flatfile'. + * - 'directory': The directory we will load the metadata files from. The default value for + * this option is the value of the 'metadatadir' configuration option, or + * 'metadata/' if that option is unset. + * + * XML metadata handler: + * This metadata handler parses an XML file with either an EntityDescriptor element or an + * EntitiesDescriptor element. The XML file may be stored locally, or (for debugging) on a remote + * web server. + * The XML metadata handler defines the following options: + * - 'type': This is always 'xml'. + * - 'file': Path to the XML file with the metadata. + * - 'url': The URL to fetch metadata from. THIS IS ONLY FOR DEBUGGING - THERE IS NO CACHING OF THE RESPONSE. + * + * MDQ metadata handler: + * This metadata handler looks up for the metadata of an entity at the given MDQ server. + * The MDQ metadata handler defines the following options: + * - 'type': This is always 'mdq'. + * - 'server': Base URL of the MDQ server. Mandatory. + * - 'validateFingerprint': The fingerprint of the certificate used to sign the metadata. You don't need this + * option if you don't want to validate the signature on the metadata. Optional. + * - 'cachedir': Directory where metadata can be cached. Optional. + * - 'cachelength': Maximum time metadata can be cached, in seconds. Defaults to 24 + * hours (86400 seconds). Optional. + * + * PDO metadata handler: + * This metadata handler looks up metadata of an entity stored in a database. + * + * Note: If you are using the PDO metadata handler, you must configure the database + * options in this configuration file. + * + * The PDO metadata handler defines the following options: + * - 'type': This is always 'pdo'. + * + * Examples: + * + * This example defines two flatfile sources. One is the default metadata directory, the other + * is a metadata directory with auto-generated metadata files. + * + * 'metadata.sources' => array( + * array('type' => 'flatfile'), + * array('type' => 'flatfile', 'directory' => 'metadata-generated'), + * ), + * + * This example defines a flatfile source and an XML source. + * 'metadata.sources' => array( + * array('type' => 'flatfile'), + * array('type' => 'xml', 'file' => 'idp.example.org-idpMeta.xml'), + * ), + * + * This example defines an mdq source. + * 'metadata.sources' => array( + * array( + * 'type' => 'mdq', + * 'server' => 'http://mdq.server.com:8080' , + * 'cachedir' => '/var/simplesamlphp/mdq-cache', + * 'cachelength' => 86400 + * ) + * ), + * + * This example defines an pdo source. + * 'metadata.sources' => array( + * array('type' => 'pdo') + * ), + * + * Default: + * 'metadata.sources' => array( + * array('type' => 'flatfile') + * ), + */ + 'metadata.sources' => array( + array('type' => 'flatfile'), + ), + + /* + * Should signing of generated metadata be enabled by default. + * + * Metadata signing can also be enabled for a individual SP or IdP by setting the + * same option in the metadata for the SP or IdP. + */ + 'metadata.sign.enable' => false, + + /* + * The default key & certificate which should be used to sign generated metadata. These + * are files stored in the cert dir. + * These values can be overridden by the options with the same names in the SP or + * IdP metadata. + * + * If these aren't specified here or in the metadata for the SP or IdP, then + * the 'certificate' and 'privatekey' option in the metadata will be used. + * if those aren't set, signing of metadata will fail. + */ + 'metadata.sign.privatekey' => null, + 'metadata.sign.privatekey_pass' => null, + 'metadata.sign.certificate' => null, + 'metadata.sign.algorithm' => null, + + + /**************************** + | DATA STORE CONFIGURATION | + ****************************/ + + /* + * Configure the data store for SimpleSAMLphp. + * + * - 'phpsession': Limited datastore, which uses the PHP session. + * - 'memcache': Key-value datastore, based on memcache. + * - 'sql': SQL datastore, using PDO. + * - 'redis': Key-value datastore, based on redis. + * + * The default datastore is 'phpsession'. + * + * (This option replaces the old 'session.handler'-option.) + */ + 'store.type' => 'redis', + + /* + * The DSN the sql datastore should connect to. + * + * See http://www.php.net/manual/en/pdo.drivers.php for the various + * syntaxes. + */ + 'store.sql.dsn' => 'sqlite:/path/to/sqlitedatabase.sq3', + + /* + * The username and password to use when connecting to the database. + */ + 'store.sql.username' => null, + 'store.sql.password' => null, + + /* + * The prefix we should use on our tables. + */ + 'store.sql.prefix' => 'SimpleSAMLphp', + + /* + * The hostname and port of the Redis datastore instance. + */ + 'store.redis.host' => 'redis.' . getenv('NAMESPACE') . '.svc.cluster.local', + //The option 'store.redis.port' must be a valid integer value. + 'store.redis.port' => (int)getenv('REDIS_SERVICE_PORT'), + + /* + * The prefix we should use on our Redis datastore. + */ + 'store.redis.prefix' => 'SimpleSAMLphp', +); diff --git a/images/php-fpm/config/simplesamlphp/metadata/saml20-idp-remote.php b/images/php-fpm/config/simplesamlphp/metadata/saml20-idp-remote.php new file mode 100644 index 0000000000000000000000000000000000000000..e5efd72348e27392fa8722ba9570faea06aacda3 --- /dev/null +++ b/images/php-fpm/config/simplesamlphp/metadata/saml20-idp-remote.php @@ -0,0 +1,113 @@ +<?php +/** + * SAML 2.0 remote IdP metadata for SimpleSAMLphp. + * + * Remember to remove the IdPs you don't use from this file. + * + * See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-idp-remote + */ + +$metadata['https://cern.ch/login'] = array ( + 'entityid' => 'https://cern.ch/login', + 'description' => + array ( + 'en-US' => 'CERN', + ), + 'OrganizationName' => + array ( + 'en-US' => 'CERN', + ), + 'name' => + array ( + 'en-US' => 'CERN', + ), + 'OrganizationDisplayName' => + array ( + 'en-US' => 'CERN', + ), + 'url' => + array ( + 'en-US' => 'http://cern.ch/', + ), + 'OrganizationURL' => + array ( + 'en-US' => 'http://cern.ch/', + ), + 'contacts' => + array ( + 0 => + array ( + 'contactType' => 'support', + 'company' => 'CERN', + 'givenName' => 'Service', + 'surName' => 'Desk', + 'emailAddress' => + array ( + 0 => 'service-desk@cern.ch', + ), + 'telephoneNumber' => + array ( + 0 => '+41227678888', + ), + ), + ), + 'metadata-set' => 'saml20-idp-remote', + 'SingleSignOnService' => + array ( + 0 => + array ( + 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', + 'Location' => 'https://login.cern.ch/adfs/ls/', + ), + 1 => + array ( + 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', + 'Location' => 'https://login.cern.ch/adfs/ls/', + ), + ), + 'SingleLogoutService' => + array ( + 0 => + array ( + 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', + 'Location' => 'https://login.cern.ch/adfs/ls/', + ), + 1 => + array ( + 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', + 'Location' => 'https://login.cern.ch/adfs/ls/', + ), + ), + 'ArtifactResolutionService' => + array ( + 0 => + array ( + 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP', + 'Location' => 'https://login.cern.ch/adfs/services/trust/artifactresolution', + 'index' => 0, + ), + ), + 'NameIDFormats' => + array ( + 0 => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', + 1 => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', + 2 => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', + ), + 'keys' => + array ( + 0 => + array ( + 'encryption' => true, + 'signing' => false, + 'type' => 'X509Certificate', + 'X509Certificate' => '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', + ), + 1 => + array ( + 'encryption' => false, + 'signing' => true, + 'type' => 'X509Certificate', + 'X509Certificate' => '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', + ), + ), +); \ No newline at end of file diff --git a/images/php-fpm/hooks/post-hook.sh b/images/php-fpm/hooks/post-hook.sh new file mode 100644 index 0000000000000000000000000000000000000000..7d57e2c4c30454548bdc7859d124ea14bd625b4c --- /dev/null +++ b/images/php-fpm/hooks/post-hook.sh @@ -0,0 +1,22 @@ +#!/bin/sh +set -x + +# Check if database connection exists +mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASSWORD $DB_NAME -e "select 1" 2>&1 1>/dev/null +if [ $? -ne 0 ]; then + exit 1; +fi + +if drush status --fields=bootstrap | grep -q 'Successful'; then + + echo "--> Cleaning caches..." + drush -y cr + + echo "--> Updating database..." + drush -y updb + + echo "--> Importing configuration..." + drush -y cim +fi + +echo "--> Running..." \ No newline at end of file diff --git a/images/php-fpm/run-php-fpm.sh b/images/php-fpm/run-php-fpm.sh new file mode 100644 index 0000000000000000000000000000000000000000..c0eca340a7390a4c4d6a164089df3d13807b1984 --- /dev/null +++ b/images/php-fpm/run-php-fpm.sh @@ -0,0 +1,37 @@ +#!/bin/sh +set -x + +# Setup drupal site +/init-app.sh + +## OPERATOR ACTIONS +# If site does not exist, install it. +if [[ ${ENVIRONMENT} == 'production' ] && [ ! drush status --fields=bootstrap | grep -q 'Successful' ]]; then + + sitename=$NAMESPACE.web.cern.ch + drush -y si cern \ + --db-url=mysql://$DB_USER:$DB_PASSWORD@$DB_HOST:$DB_PORT/$DB_NAME \ + --account-name=admin \ + --site-name=$sitename \ + $VERBOSITY + + # Check if provisioning was successful, otherwise exit. + if [ $? -ne 0 ]; then + exit 1; + fi + + # Clean caches + drush -y cr +fi + +## TESTING +# If there are files in /tmp/configmap that are not empty +# (overriden by a ConfigMap) copy them +if [ -n "$(ls -A /tmp/settings)" ]; then + cat /tmp/settings/settings.${ENVIRONMENT}.php > ${DRUPAL_APP_DIR}/web/sites/default/settings.${ENVIRONMENT}.php + #chmod 444 ${DRUPAL_APP_DIR}/web/sites/default/settings.${ENVIRONMENT}.php +fi +## TESTING + +echo "---> Running PHP-FPM..." +exec php-fpm diff --git a/images/site-builder/Dockerfile b/images/site-builder/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..9af107640b18b9fa59fabbf66c17d8c4160b4afa --- /dev/null +++ b/images/site-builder/Dockerfile @@ -0,0 +1,56 @@ +ARG PHP_BASE_VERSION +ARG COMPOSER_VERSION + +FROM gitlab-registry.cern.ch/drupal/paas/dmi/php-base:${PHP_BASE_VERSION} + +LABEL io.k8s.description="Drupal managed infra site-builder" \ + io.k8s.display-name="Drupal 8 Managed Infra site-builder" \ + io.openshift.tags="managed,drupal,site-builder" \ + maintainer="Drupal Admins <drupal-admins@cern.ch>" + +ADD fix-permissions /fix-permissions +RUN chmod +x /fix-permissions + +# Install composer +# Get releases from https://github.com/composer/composer/releases +ENV COMPOSER_VERSION ${COMPOSER_VERSION:-1.9.0} +ENV COMPOSER_HOME ${DRUPAL_APP_DIR} +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer --version=${COMPOSER_VERSION} + +# DRUPAL specific. Include drupal tools in the PATH +# DRUPAL_APP_DIR is the drupal final destination. Must be in consonance with nginx. +# DRUPAL_CODE_DIR is used to pre-set drupal code. +ENV DRUPAL_APP_DIR /app +ENV DRUPAL_CODE_DIR /code +ENV HOME ${DRUPAL_CODE_DIR} +RUN mkdir -p ${DRUPAL_CODE_DIR} ${DRUPAL_APP_DIR} + +# From here we will manage all central/non central modules + drupal version +RUN git clone https://gitlab.cern.ch/drupal/paas/composer-drupal-project ${DRUPAL_CODE_DIR} + +WORKDIR ${DRUPAL_CODE_DIR} +# Composer as root/super user! See https://getcomposer.org/root for details +# Set up drupal minimum stack +ENV COMPOSER_MEMORY_LIMIT -1 +RUN composer install --optimize-autoloader --no-cache -vv + +# TO BE REMOVED +# Web Team modules and themes. This needs to be removed in favour of composer +ADD toremove.sh / +RUN chmod +x /toremove.sh && /toremove.sh +# TO BE REMOVED + +# Add extra configurations +# At this point, composer has created the required settings.php through: +# post-update-cmd: DrupalProject\composer\ScriptHandler::createRequiredFiles +# Overwrite settings.php with ours. +# - settings.php +ADD config/sites/default/settings.php ${DRUPAL_CODE_DIR}/web/sites/default/settings.php +# Remove ${DRUPAL_CODE_DIR}/web/sites/default/files, preparing it to be symbolic link after init-app.sh; +RUN rm -rf ${DRUPAL_CODE_DIR}/web/sites/default/files +# Fix-permissions +RUN /fix-permissions ${DRUPAL_CODE_DIR} + +# Add init-container for every container that contains drupal code +ADD init-app.sh / +RUN chmod +x /init-app.sh \ No newline at end of file diff --git a/images/site-builder/config/sites/default/settings.dev.php b/images/site-builder/config/sites/default/settings.dev.php new file mode 100644 index 0000000000000000000000000000000000000000..8f73833bf98caf09b066ff746d153a129d42bd12 --- /dev/null +++ b/images/site-builder/config/sites/default/settings.dev.php @@ -0,0 +1,25 @@ +<?php +// CONSIDER USING THIS AS CONFIG MAP +// +//https://api.drupal.org/api/drupal/sites%21example.settings.local.php/8.7.x +/** + * Show all error messages, with backtrace information. + * + * In case the error level could not be fetched from the database, as for + * example the database connection failed, we rely only on this value. + */ +# Check https://jimconte.com/blog/web/drupal-8-environment-specific-configurations +# ================================================================ +# disable page cache and other cache bins +# ================================================================ +#$cache_bins = array('bootstrap','config','data','default','discovery','dynamic_page_cache','entity','menu','migrate','render','rest','static','toolbar'); +#foreach ($cache_bins as $bin) { +# $settings['cache']['bins'][$bin] = 'cache.backend.null'; +#} + +$config['system.logging']['error_level'] = 'verbose'; + +$trusted_host_pattern="^" . getenv('NAMESPACE') . "\.apptest\.cern\.ch$"; +$settings['trusted_host_patterns'] = array( + $trusted_host_pattern, +); diff --git a/images/site-builder/config/sites/default/settings.php b/images/site-builder/config/sites/default/settings.php new file mode 100644 index 0000000000000000000000000000000000000000..bdaa03e7a386e081f62135f2965e3ca76f9a6a9c --- /dev/null +++ b/images/site-builder/config/sites/default/settings.php @@ -0,0 +1,143 @@ +<?php +// @codingStandardsIgnoreFile +// Database settings. +$databases['default']['default'] = [ + 'host' => getenv('DB_HOST'), + 'port' => getenv('DB_PORT'), + 'database' => getenv('DB_NAME'), + 'username' => getenv('DB_USER'), + 'password' => getenv('DB_PASSWORD'), + 'namespace' => 'Drupal\Core\Database\Driver\mysql', + 'driver' => 'mysql', + 'prefix' => '', + 'collation' => 'utf8mb4_general_ci', +]; + +// Location of the site configuration files. +$config_directories[CONFIG_SYNC_DIRECTORY] = '../config/sync'; + +// Configure file paths +// Private file paths. +$settings['file_private_path'] = getenv('DRUPAL_SHARED_VOLUME') . '/private'; +// Configure tmp folder +$settings['file_temporary_path'] = '/tmp'; + +// Configure feeds tmp folder +// Fix: https://www.drupal.org/project/feeds/issues/2912130 +if (isset($config['system.file']) && !is_null($config['system.file']['path']['temporary'])) +{ + $config['system.file']['path']['temporary'] = getenv('DRUPAL_SHARED_VOLUME') . "/private/feeds/tmp"; +} + +// Config trusted host pattern +$trusted_host_pattern="^". str_replace(".","\.",getenv('HOSTNAME')) . "$"; +$settings['trusted_host_patterns'] = array( + $trusted_host_pattern, +); + +// Salt for one-time login links, cancel links, form tokens, etc. +$settings['hash_salt'] = hash("sha256",getenv('DB_NAME') . getenv('DB_USER') . getenv('DB_PASS')); +/** + * Load services definition file. + */ +$settings['container_yamls'][] = $app_root . '/' . $site_path . '/services.yml'; +/** + * The default list of directories that will be ignored by Drupal's file API. + * + * By default ignore node_modules folders to avoid issues + * with common frontend tools and recursive scanning of directories looking for + * extensions. + * + * @see file_scan_directory() + * @see \Drupal\Core\Extension\ExtensionDiscovery::scanDirectory() + */ +$settings['file_scan_ignore_directories'] = [ + 'node_modules', +]; + +/** + * Redis Configuration. + * @See https://pantheon.io/docs/redis/ > No Keys Found + * @See also https://gist.github.com/keopx/7d5fe4d7a890c792c43bb79cf56718e0 + * @ See also https://docs.platform.sh/frameworks/drupal8/redis.html + */ + +if (extension_loaded('redis')) { + // Set Redis as the default backend for any cache bin not otherwise specified. + $settings['cache']['default'] = 'cache.backend.redis'; + $settings['redis.connection']['interface'] = 'PhpRedis'; + $settings['redis.connection']['host'] = 'redis.' . getenv('NAMESPACE') . '.svc.cluster.local'; + $settings['redis.connection']['port'] = getenv('REDIS_SERVICE_PORT'); + + // Allow the services to work before the Redis module itself is enabled. + $settings['container_yamls'][] = 'modules/contrib/redis/redis.services.yml'; + // Manually add the classloader path, this is required for the container cache bin definition below + // and allows to use it without the redis module being enabled. + $class_loader->addPsr4('Drupal\\redis\\', 'modules/contrib/redis/src'); + // Use redis for container cache. + // The container cache is used to load the container definition itself, and + // thus any configuration stored in the container itself is not available + // yet. These lines force the container cache to use Redis rather than the + // default SQL cache. + $settings['bootstrap_container_definition'] = [ + 'parameters' => [], + 'services' => [ + 'redis.factory' => [ + 'class' => 'Drupal\redis\ClientFactory', + ], + 'cache.backend.redis' => [ + 'class' => 'Drupal\redis\Cache\CacheBackendFactory', + 'arguments' => ['@redis.factory', '@cache_tags_provider.container', '@serialization.phpserialize'], + ], + 'cache.container' => [ + 'class' => '\Drupal\redis\Cache\PhpRedis', + 'factory' => ['@cache.backend.redis', 'get'], + 'arguments' => ['container'], + ], + 'cache_tags_provider.container' => [ + 'class' => 'Drupal\redis\Cache\RedisCacheTagsChecksum', + 'arguments' => ['@redis.factory'], + ], + 'serialization.phpserialize' => [ + 'class' => 'Drupal\Component\Serialization\PhpSerialize', + ], + ], + ]; + + /** Optional prefix for cache entries */ + $settings['cache_prefix'] = getenv('NAMESPACE'); + + /** @see: https://pantheon.io/docs/redis/ */ + // Always set the fast backend for bootstrap, discover and config, otherwise + // this gets lost when redis is enabled. + $settings['cache']['bins']['bootstrap'] = 'cache.backend.chainedfast'; + $settings['cache']['bins']['discovery'] = 'cache.backend.chainedfast'; + $settings['cache']['bins']['config'] = 'cache.backend.chainedfast'; + /** @see: https://github.com/md-systems/redis */ + // Use for all bins otherwise specified. + $settings['cache']['default'] = 'cache.backend.redis'; + // Use this to only use it for specific cache bins. + $settings['cache']['bins']['render'] = 'cache.backend.redis'; + // Use for all queues unless otherwise specified for a specific queue. + $settings['queue_default'] = 'queue.redis'; + // Or if you want to use reliable queue implementation. + $settings['queue_default'] = 'queue.redis_reliable'; + // Use this to only use Redis for a specific queue (aggregator_feeds in this case). + $settings['queue_service_aggregator_feeds'] = 'queue.redis'; + // Or if you want to use reliable queue implementation. + $settings['queue_service_aggregator_feeds'] = 'queue.redis_reliable'; +} + +/** + * Load local development override configuration, if available. + * + * Use settings.local.php to override variables on secondary (staging, + * development, etc) installations of this site. Typically used to disable + * caching, JavaScript/CSS compression, re-routing of outgoing emails, and + * other things that should not happen on development and testing sites. + * + * Keep this code block at the end of this file to take full effect. + */ +if (getenv('ENVIRONMENT') != 'production' && file_exists($app_root . '/' . $site_path . '/settings.' . getenv('ENVIRONMENT') . '.php')) { + include $app_root . '/' . $site_path . '/settings.' . getenv('ENVIRONMENT') . '.php'; +} diff --git a/images/site-builder/fix-permissions b/images/site-builder/fix-permissions new file mode 100644 index 0000000000000000000000000000000000000000..32c4625eed6667b20953d163033a695441a8247c --- /dev/null +++ b/images/site-builder/fix-permissions @@ -0,0 +1,6 @@ +#!/bin/sh +# Fix permissions on the given directory to allow group read/write of +# regular files and execute of directories. +find -L "$1" -exec chgrp 0 {} \; +find -L "$1" -exec chmod g+rw {} \; +find -L "$1" -type d -exec chmod g+x {} + \ No newline at end of file diff --git a/images/site-builder/init-app.sh b/images/site-builder/init-app.sh new file mode 100644 index 0000000000000000000000000000000000000000..ea09cd8c074d3da07ec925fcdd294470930da078 --- /dev/null +++ b/images/site-builder/init-app.sh @@ -0,0 +1,34 @@ +#!/bin/sh +set -ex + +# Set drupal under target directory +cp -Rf ${DRUPAL_CODE_DIR}/. ${DRUPAL_APP_DIR}/ + +### Pre create folders under ${DRUPAL_SHARED_VOLUME} +# Check if files folder exists, otherwise create it. +if [ ! -d "${DRUPAL_SHARED_VOLUME}/files" ]; then + mkdir -p ${DRUPAL_SHARED_VOLUME}/files +fi + +# Check if private folder exists, otherwise create it. +if [ ! -d "${DRUPAL_SHARED_VOLUME}/private" ]; then + mkdir -p ${DRUPAL_SHARED_VOLUME}/private +fi + +if [ ! -d "${DRUPAL_SHARED_VOLUME}/modules" ]; then + mkdir -p ${DRUPAL_SHARED_VOLUME}/modules +fi + +if [ ! -d "${DRUPAL_SHARED_VOLUME}/themes" ]; then + mkdir -p ${DRUPAL_SHARED_VOLUME}/themes +fi + +# Set symlinks +ln -s ${DRUPAL_SHARED_VOLUME}/files ${DRUPAL_APP_DIR}/web/sites/default/files +ln -s ${DRUPAL_SHARED_VOLUME}/modules ${DRUPAL_APP_DIR}/web/sites/default/modules +ln -s ${DRUPAL_SHARED_VOLUME}/themes ${DRUPAL_APP_DIR}/web/sites/default/themes + +# The directory sites/default is not protected from modifications and poses a security risk. +# Change the directory's permissions to be non-writable is needed. +chmod -R 555 ${DRUPAL_APP_DIR}/web/sites/default +chmod 444 ${DRUPAL_APP_DIR}/web/sites/default/settings.php \ No newline at end of file diff --git a/images/site-builder/toremove.sh b/images/site-builder/toremove.sh new file mode 100644 index 0000000000000000000000000000000000000000..790eb29d8766f78bd6e9da9de2d0464a46704623 --- /dev/null +++ b/images/site-builder/toremove.sh @@ -0,0 +1,28 @@ +#!/bin/sh +set -x + +# Modules +git clone --depth=1 --single-branch --branch "v1.1.0" https://gitlab.cern.ch/web-team/drupal/public/d8/modules/twig-functions-library.git ${DRUPAL_CODE_DIR}/web/modules/contrib/twig_functions_library + +git clone --depth=1 --single-branch --branch "v2.1.1" https://gitlab.cern.ch/web-team/drupal/public/d8/modules/paragraph-types.git ${DRUPAL_CODE_DIR}/web/modules/contrib/cern_paragraph_types + +git clone --depth=1 --single-branch --branch "v2.0" https://gitlab.cern.ch/web-team/drupal/public/d8/modules/cern-loading.git ${DRUPAL_CODE_DIR}/web/modules/contrib/cern_loading + +git clone --depth=1 --single-branch --branch "v2.2.0" https://gitlab.cern.ch/web-team/drupal/public/d8/modules/cern-landing-page.git ${DRUPAL_CODE_DIR}/web/modules/contrib/cern_landing_page + +git clone --depth=1 --single-branch --branch "v2.0" https://gitlab.cern.ch/web-team/drupal/public/d8/modules/cern-full-html-format.git ${DRUPAL_CODE_DIR}/web/modules/contrib/cern_full_html_format + +git clone --depth=1 --single-branch --branch "v2.6.1" https://gitlab.cern.ch/web-team/drupal/public/d8/modules/cern-components.git ${DRUPAL_CODE_DIR}/web/modules/contrib/cern_components + +git clone --depth=1 --single-branch --branch "v1.4.0" https://gitlab.cern.ch/web-team/drupal/public/d8/modules/cern-display-formats.git ${DRUPAL_CODE_DIR}/web/modules/contrib/cern_display_formats + +git clone --depth=1 --single-branch --branch "v2.2.0" https://gitlab.cern.ch/web-team/drupal/public/d8/modules/cern-toolbar.git ${DRUPAL_CODE_DIR}/web/modules/contrib/cern_toolbar + +git clone --depth=1 --single-branch --branch "v2.1.1" https://gitlab.cern.ch/web-team/drupal/public/d8/modules/cern-cds-media.git ${DRUPAL_CODE_DIR}/web/modules/contrib/cern_cds_media + +git clone --depth=1 --single-branch --branch "v2.1.0" https://gitlab.cern.ch/web-team/drupal/public/d8/modules/cern-dev-status.git ${DRUPAL_CODE_DIR}/web/modules/contrib/cern_dev_status + +# Themes +git clone --depth=1 --single-branch --branch "v2.5.1" https://gitlab.cern.ch/web-team/drupal/public/d8/themes/cernbase.git ${DRUPAL_CODE_DIR}/web/themes/custom/cernbase + +git clone --depth=1 --single-branch --branch "v2.4.3" https://gitlab.cern.ch/web-team/drupal/public/d8/themes/cern.git ${DRUPAL_CODE_DIR}/web/themes/custom/cernclean