diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 28e95d4..70b225d 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -70,29 +70,18 @@ gen_ssl_cert() { } install() { - tables=$(mysql \ - -u "${DATASOURCES_DEFAULT_USERNAME:-passbolt}" \ - -h "${DATASOURCES_DEFAULT_HOST:-localhost}" \ - -P "${DATASOURCES_DEFAULT_PORT:-3306}" \ - -BN -e "SHOW TABLES FROM ${DATASOURCES_DEFAULT_DATABASE:-passbolt}" \ - -p"${DATASOURCES_DEFAULT_PASSWORD:-P4ssb0lt}" |wc -l) - app_config="/var/www/passbolt/config/app.php" + local app_config="/var/www/passbolt/config/app.php" if [ ! -f "$app_config" ]; then su -c 'cp /var/www/passbolt/config/app.default.php /var/www/passbolt/config/app.php' -s /bin/bash www-data fi - if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ]; then + if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f '/var/www/passbolt/config/passbolt.php' ]; then gpg_auto_fingerprint="$(su -c "gpg --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 - if [ "$tables" -eq 0 ]; then - su -c '/var/www/passbolt/bin/cake passbolt install --no-admin' -s /bin/bash www-data - else - su -c '/var/www/passbolt/bin/cake passbolt migrate' -s /bin/bash www-data - echo "Enjoy! ☮" - fi + su -c '/var/www/passbolt/bin/cake passbolt install --no-admin' -s /bin/bash www-data || su -c '/var/www/passbolt/bin/cake passbolt migrate' -s /bin/bash www-data && echo "Enjoy! ☮" } email_cron_job() { diff --git a/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb b/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb new file mode 100644 index 0000000..3672732 --- /dev/null +++ b/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb @@ -0,0 +1,126 @@ +require 'spec_helper' + +describe 'passbolt_api service' do + + before(:all) do + @mysql_image = Docker::Image.create('fromImage' => 'mariadb:latest') + @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 + + while @mysql.json['State']['Health']['Status'] != 'healthy' + sleep 1 + end + + @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES) + + @container = Docker::Container.create( + 'Env' => [ + "DATASOURCES_DEFAULT_HOST=#{@mysql.json['NetworkSettings']['IPAddress']}", + ], + 'Binds' => [ "#{FIXTURES_PATH + '/passbolt.php'}:/var/www/passbolt/config/passbolt.php" ], + 'Image' => @image.id) + + @container.start + @container.logs(stdout: true) + + set :docker_container, @container.id + sleep 17 + end + + after(:all) do + @mysql.kill + @container.kill + end + + let(:passbolt_host) { @container.json['NetworkSettings']['IPAddress'] } + let(:uri) { "/healthcheck/status.json" } + let(:curl) { "curl -sk -o /dev/null -w '%{http_code}' -H 'Host: passbolt.local' https://#{passbolt_host}/#{uri}" } + + describe 'php service' do + it 'is running supervised' do + expect(service('php-fpm')).to be_running.under('supervisor') + end + + it 'has its port open' do + expect(@container.json['Config']['ExposedPorts']).to have_key('9000/tcp') + end + end + + describe 'email cron' do + it 'is running supervised' do + expect(service('cron')).to be_running.under('supervisor') + end + end + + describe 'web service' do + it 'is running supervised' do + expect(service('nginx')).to be_running.under('supervisor') + end + + it 'is listening on port 80' do + expect(@container.json['Config']['ExposedPorts']).to have_key('80/tcp') + end + + it 'is listening on port 443' do + expect(@container.json['Config']['ExposedPorts']).to have_key('443/tcp') + end + end + + describe 'passbolt status' do + it 'returns 200' do + expect(command(curl).stdout).to eq '200' + end + end + + describe 'passbolt serverkey unaccessible' do + let(:uri) { '/config/gpg/serverkey.asc' } + it "returns 404" do + expect(command(curl).stdout).to eq '404' + end + end + + describe 'passbolt serverkey private unaccessible' do + let(:uri) { '/config/gpg/serverkey_private.asc' } + it 'returns 404' do + expect(command(curl).stdout).to eq '404' + end + end + + describe 'passbolt conf unaccessible' do + let(:uri) { '/config/app.php' } + it 'returns 404' do + expect(command(curl).stdout).to eq '404' + end + end + describe 'passbolt tmp folder is unaccessible' do + let(:uri) { '/tmp/cache/database/empty' } + it 'returns 404' do + expect(command(curl).stdout).to eq '404' + end + end + + describe 'hide information' do + let(:curl) { "curl -Isk -H 'Host: passbolt.local' https://#{passbolt_host}/" } + it 'hides php version' do + expect(command("#{curl} | grep 'X-Powered-By: PHP'").stdout).to be_empty + end + + it 'hides nginx version' do + expect(command("#{curl} | grep 'Server:'").stdout.strip).to match(/^Server:\s+nginx$/) + end + end + +end diff --git a/spec/fixtures/passbolt.php b/spec/fixtures/passbolt.php new file mode 100644 index 0000000..88d159a --- /dev/null +++ b/spec/fixtures/passbolt.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' => '/home/www-data/.gnupg', + // + // Replace GNUPGHOME with above value even if it is set. + //'putenv' => false, + + // Main server key. + 'serverKey' => [ + // Server private key fingerprint. + 'fingerprint' => '2FC8945833C51946E937F9FED47B0811573EE67E', + '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', +// ], +// ], +// ] + +]; diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9620baa..39299aa 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,6 +2,7 @@ require 'serverspec' require 'docker' ROOT_DOCKERFILES = File.expand_path('../../', __FILE__) +FIXTURES_PATH = File::expand_path("fixtures", File::dirname(__FILE__)) set :backend, :docker Docker.options[:read_timeout] = 3600