diff --git a/.gitlab-ci/Jobs/test_images.yaml b/.gitlab-ci/Jobs/test_images.yaml index bfa1800..7b261eb 100644 --- a/.gitlab-ci/Jobs/test_images.yaml +++ b/.gitlab-ci/Jobs/test_images.yaml @@ -40,6 +40,11 @@ ce-docker-runtime-no-envs: variables: TEST_NAME: docker_runtime_no_envs +ce-docker-runtime-no-envs: + extends: .test-images + variables: + TEST_NAME: docker_runtime_with_passbolt_php + pro-docker-image: extends: .test-pro-images variables: @@ -55,6 +60,11 @@ pro-docker-runtime-no-envs: variables: TEST_NAME: docker_runtime_no_envs +pro-docker-runtime-with-passbolt-php: + extends: .test-images + variables: + TEST_NAME: docker_runtime_with_passbolt_php + ce-non-root-docker-image: extends: .test-images variables: @@ -73,6 +83,12 @@ ce-non-root-docker-runtime-no-envs: TEST_NAME: docker_runtime_no_envs ROOTLESS: "true" +ce-non-root-docker-runtime-with-passbolt-php: + extends: .test-images + variables: + TEST_NAME: docker_runtime_with_passbolt_php + ROOTLESS: "true" + pro-non-root-docker-image: extends: .test-pro-images variables: @@ -90,3 +106,9 @@ pro-non-root-docker-runtime-no-envs: variables: TEST_NAME: docker_runtime_no_envs ROOTLESS: "true" + +pro-non-root-docker-runtime-with-passbolt-php: + extends: .test-images + variables: + TEST_NAME: docker_runtime_with_passbolt_php + ROOTLESS: "true" diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c50f62..7357e47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,14 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## [Unreleased](https://github.com/passbolt/passbolt_docker/compare/v3.9.3...HEAD) +## [Unreleased](https://github.com/passbolt/passbolt_docker/compare/v3.9.4...HEAD) + +## [3.9.4](https://github.com/passbolt/passbolt_docker/compare/v3.9.3...v3.9.4) - 2023-04-18 + +### Added +- Update mariadb to version 10.10 [#190](https://github.com/passbolt/passbolt_docker/pull/190) +- Added PASSBOLT_GPG_SERVER_KEY_FINGERPRINT_FORCE env variable. Fixes [#192](https://github.com/passbolt/passbolt_docker/issues/192) +- Arm arch support for arm64/v8, arm/v7 and arm/v5 linux architectures. ## [3.9.3](https://github.com/passbolt/passbolt_docker/compare/v3.9.2...v3.9.3) - 2023-03-17 diff --git a/README.md b/README.md index d52173b..5b54cb6 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,7 @@ Passbolt docker image provides several environment variables to configure differ | PASSBOLT_KEY_EMAIL | Key owner email address | passbolt@yourdomain.com | PASSBOLT_KEY_EXPIRATION | Key expiration date | 0, never expires | PASSBOLT_GPG_SERVER_KEY_FINGERPRINT | GnuPG fingerprint | null +| PASSBOLT_GPG_SERVER_KEY_FINGERPRINT_FORCE | Force calculation of GnuPG fingerprint for server key | null | PASSBOLT_GPG_SERVER_KEY_PUBLIC | Path to GnuPG public server key | /etc/passbolt/gpg/serverkey.asc | PASSBOLT_GPG_SERVER_KEY_PRIVATE | Path to GnuPG private server key | /etc/passbolt/gpg/serverkey_private.asc | PASSBOLT_PLUGINS_EXPORT_ENABLED | Enable export plugin | true @@ -208,3 +209,10 @@ This feature is only supported for: This repository also provides a way to quickly setup Passbolt for development purposes. This way should never be used in production, as this would be unsafe. You can use the docker-compose files under [docker-compose/](./docker-compose/) to spin up Passbolt for production using docker compose. If you would like to setup Passbolt for development purposes, please follow the steps described [here](./dev/README.md). + +## Run passbolt docker tests + +```bash +PASSBOLT_FLAVOUR=ce PASSBOLT_COMPONENT=stable ROOTLESS=false bundle exec rake spec +``` + diff --git a/Rakefile b/Rakefile index 11ba867..3eed247 100644 --- a/Rakefile +++ b/Rakefile @@ -1,26 +1,30 @@ require 'rake' require 'rspec/core/rake_task' -task :spec => 'spec:all' -task :default => :spec +task spec: 'spec:all' +task default: :spec namespace :spec do targets = [] Dir.glob('./spec/*').each do |dir| next unless File.directory?(dir) + target = File.basename(dir) - target = "_#{target}" if target == "default" + target = "_#{target}" if target == 'default' targets << target end - task :all => targets - task :default => :all + task all: targets + task default: :all targets.each do |target| - original_target = target == "_default" ? target[1..-1] : target + original_target = target == '_default' ? target[1..-1] : target desc "Run serverspec tests to #{original_target}" RSpec::Core::RakeTask.new(target.to_sym) do |t| ENV['TARGET_HOST'] = original_target + ENV['PASSBOLT_FLAVOUR'] || ENV['PASSBOLT_FLAVOUR'] = 'ce' + ENV['PASSBOLT_COMPONENT'] || ENV['PASSBOLT_COMPONENT'] = 'stable' + ENV['ROOTLESS'] || ENV['ROOTLESS'] = 'false' t.pattern = "spec/#{original_target}/*_spec.rb" end end diff --git a/docker-compose/docker-compose-ce.yaml b/docker-compose/docker-compose-ce.yaml index 5c9f0c8..60b54af 100644 --- a/docker-compose/docker-compose-ce.yaml +++ b/docker-compose/docker-compose-ce.yaml @@ -1,7 +1,7 @@ version: '3.9' services: db: - image: mariadb:10.3 + image: mariadb:10.10 restart: unless-stopped environment: MYSQL_RANDOM_ROOT_PASSWORD: "true" diff --git a/docker-compose/docker-compose-pro.yaml b/docker-compose/docker-compose-pro.yaml index 131a60d..fa6f74e 100644 --- a/docker-compose/docker-compose-pro.yaml +++ b/docker-compose/docker-compose-pro.yaml @@ -1,7 +1,7 @@ version: '3.9' services: db: - image: mariadb:10.3 + image: mariadb:10.10 restart: unless-stopped environment: MYSQL_RANDOM_ROOT_PASSWORD: "true" diff --git a/scripts/entrypoint/passbolt/entrypoint.sh b/scripts/entrypoint/passbolt/entrypoint.sh index 317e333..d1b8276 100644 --- a/scripts/entrypoint/passbolt/entrypoint.sh +++ b/scripts/entrypoint/passbolt/entrypoint.sh @@ -93,7 +93,9 @@ function install() { su -c "cp $passbolt_config/app.default.php $passbolt_config/app.php" -s /bin/bash www-data fi - if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f "$passbolt_config/passbolt.php" ]; then + if [[ ( "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT_FORCE}" == "true" ) || \ + ( -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" && \ + ! -f "$passbolt_config/passbolt.php" ) ]]; then gpg_auto_fingerprint="$(su -c "gpg --homedir $GNUPGHOME --list-keys --with-colons ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} |grep fpr |head -1| cut -f10 -d:" -ls /bin/bash www-data)" export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint fi diff --git a/spec/docker_runtime_with_passbolt_php/docker_runtime_with_passbolt_php_spec.rb b/spec/docker_runtime_with_passbolt_php/docker_runtime_with_passbolt_php_spec.rb new file mode 100644 index 0000000..5b08f9a --- /dev/null +++ b/spec/docker_runtime_with_passbolt_php/docker_runtime_with_passbolt_php_spec.rb @@ -0,0 +1,96 @@ + +require 'spec_helper' + +describe 'passbolt_api service' do + before(:all) do + @mysql_image = + if ENV['GITLAB_CI'] + Docker::Image.create( + 'fromImage' => 'registry.gitlab.com/passbolt/passbolt-ci-docker-images/mariadb-10.3:latest' + ) + else + Docker::Image.create('fromImage' => 'mariadb:latest') + end + + @mysql = Docker::Container.create( + 'Env' => [ + 'MYSQL_ROOT_PASSWORD=test', + 'MYSQL_DATABASE=passbolt', + 'MYSQL_USER=passbolt', + 'MYSQL_PASSWORD=±!@#$%^&*()_+=-}{|:;<>?' + ], + 'Healthcheck' => { + "Test": [ + 'CMD-SHELL', + 'mysqladmin ping --silent' + ] + }, + 'Image' => @mysql_image.id + ) + + @mysql.start + + sleep 1 while @mysql.json['State']['Health']['Status'] != 'healthy' + + if ENV['GITLAB_CI'] + Docker.authenticate!( + 'username' => ENV['CI_REGISTRY_USER'].to_s, + 'password' => ENV['CI_REGISTRY_PASSWORD'].to_s, + 'serveraddress' => 'https://registry.gitlab.com/' + ) + @image = + if ENV['ROOTLESS'] == 'true' + Docker::Image.create( + 'fromImage' => "#{ENV['CI_REGISTRY_IMAGE']}:#{ENV['PASSBOLT_FLAVOUR']}-rootless-latest" + ) + else + Docker::Image.create( + 'fromImage' => "#{ENV['CI_REGISTRY_IMAGE']}:#{ENV['PASSBOLT_FLAVOUR']}-root-latest" + ) + end + else + @image = Docker::Image.build_from_dir( + ROOT_DOCKERFILES, + { + 'dockerfile' => $dockerfile, + 'buildargs' => JSON.generate($buildargs) + } + ) + end + + @container = Docker::Container.create( + 'Env' => [ + "DATASOURCES_DEFAULT_HOST=#{@mysql.json['NetworkSettings']['IPAddress']}", + 'DATASOURCES_DEFAULT_PASSWORD=±!@#$%^&*()_+=-}{|:;<>?', + 'DATASOURCES_DEFAULT_USERNAME=passbolt', + 'DATASOURCES_DEFAULT_DATABASE=passbolt', + 'PASSBOLT_SSL_FORCE=true', + 'PASSBOLT_GPG_SERVER_KEY_FINGERPRINT_FORCE=true' + ], + 'Image' => @image.id, + 'Binds' => $binds.append( + "#{FIXTURES_PATH + '/passbolt-no-fingerprint.php'}:#{PASSBOLT_CONFIG_PATH + '/passbolt.php'}", + "#{FIXTURES_PATH + '/public-test.key'}:#{PASSBOLT_CONFIG_PATH + 'gpg/unsecure.key'}", + "#{FIXTURES_PATH + '/private-test.key'}:#{PASSBOLT_CONFIG_PATH + 'gpg/unsecure_private.key'}", + ), + ) + + @container.start + @container.logs(stdout: true) + + set :docker_container, @container.id + sleep 17 + end + + after(:all) do + @mysql.kill + @container.kill + end + + describe 'force fingerprint calculation' do + it 'is contains fingerprint environment variable' do + expect(file('/etc/environment').content).to match(/PASSBOLT_GPG_SERVER_KEY_FINGERPRINT/) + end + end + +end diff --git a/spec/fixtures/passbolt-no-fingerprint.php b/spec/fixtures/passbolt-no-fingerprint.php new file mode 100644 index 0000000..ed21ec3 --- /dev/null +++ b/spec/fixtures/passbolt-no-fingerprint.php @@ -0,0 +1,142 @@ + [ + // A base URL to use for absolute links. + // The url where the passbolt instance will be reachable to your end users. + // This information is need to render images in emails for example + 'fullBaseUrl' => 'https://passbolt.local', + ], + + // Database configuration. + 'Datasources' => [ + 'default' => [ + //'host' => 'db', + //'port' => 'non_standard_port_number', + 'username' => 'passbolt', + 'password' => '±!@#$%^&*()_+=-}{|:;<>?', + 'database' => 'passbolt', + ], + ], + + // Email configuration. + 'EmailTransport' => [ + 'default' => [ + 'host' => 'localhost', + 'port' => 25, + 'username' => 'user', + 'password' => 'secret', + // Is this a secure connection? true if yes, null if no. + 'tls' => null, + //'timeout' => 30, + //'client' => null, + //'url' => null, + ], + ], + 'Email' => [ + 'default' => [ + // Defines the default name and email of the sender of the emails. + 'from' => ['passbolt@your_organization.com' => 'Passbolt'], + //'charset' => 'utf-8', + //'headerCharset' => 'utf-8', + ], + ], + + /** + * DEFAULT PASSBOLT CONFIGURATION + * + * This is the default configuration. + * It enforces the use of ssl, and does not provide a default OpenPGP key. + * If your objective is to try passbolt quickly for evaluation purpose, and security is not important + * you can use the demo config example provided in the next section below. + */ + 'passbolt' => [ + // GPG Configuration. + // The keyring must to be owned and accessible by the webserver user. + // Example: www-data user on Debian + 'gpg' => [ + // Tell GPG where to find the keyring. + // If putenv is set to false, gnupg will use the default path ~/.gnupg. + // For example : + // - Apache on Centos it would be in '/usr/share/httpd/.gnupg' + // - Apache on Debian it would be in '/var/www/.gnupg' + // - Nginx on Centos it would be in '/var/lib/nginx/.gnupg' + // - etc. + 'keyring' => '/var/lib/passbolt/.gnupg', + // + // Replace GNUPGHOME with above value even if it is set. + //'putenv' => false, + + // Main server key. + 'serverKey' => [ + // Server private key fingerprint. + 'fingerprint' => '', + 'public' => CONFIG . DS . 'gpg' . DS . 'unsecure.key', + 'private' => CONFIG . DS . 'gpg' . DS . 'unsecure_private.key', + ], + ], + ], + +/** + * DEMO CONFIGURATION EXAMPLE + * + * Uncomment the lines below if you want to try passbolt quickly. + * and if you are not concerned about the security of your installation. + * (Don't forget to comment the default config above). + */ +// 'debug' => true, +// 'passbolt' => [ +// 'registration' => [ +// 'public' => true +// ], +// 'ssl' => [ +// 'force' => false, +// ], +// 'gpg' => [ +// 'serverKey' => [ +// 'fingerprint' => '2FC8945833C51946E937F9FED47B0811573EE67E', +// 'public' => CONFIG . DS . 'gpg' . DS . 'unsecure.key', +// 'private' => CONFIG . DS . 'gpg' . DS . 'unsecure_private.key', +// ], +// ], +// ] + +];