Commit db6989dd authored by Vladimir Shushlin's avatar Vladimir Shushlin Committed by Stan Hu

Add Let's Encrypt application settings

Store Let's Encrypt account email in application settings
Also add explicit terms of service consent
parent 22ed1ba3
...@@ -127,6 +127,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -127,6 +127,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
[ [
*::ApplicationSettingsHelper.visible_attributes, *::ApplicationSettingsHelper.visible_attributes,
*::ApplicationSettingsHelper.external_authorization_service_attributes, *::ApplicationSettingsHelper.external_authorization_service_attributes,
*lets_encrypt_visible_attributes,
:domain_blacklist_file, :domain_blacklist_file,
disabled_oauth_sign_in_sources: [], disabled_oauth_sign_in_sources: [],
import_sources: [], import_sources: [],
...@@ -134,4 +135,13 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -134,4 +135,13 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
restricted_visibility_levels: [] restricted_visibility_levels: []
] ]
end end
def lets_encrypt_visible_attributes
return [] unless Feature.enabled?(:pages_auto_ssl)
[
:lets_encrypt_notification_email,
:lets_encrypt_terms_of_service_accepted
]
end
end end
...@@ -229,6 +229,16 @@ class ApplicationSetting < ApplicationRecord ...@@ -229,6 +229,16 @@ class ApplicationSetting < ApplicationRecord
presence: true, presence: true,
if: -> (setting) { setting.external_auth_client_cert.present? } if: -> (setting) { setting.external_auth_client_cert.present? }
validates :lets_encrypt_notification_email,
devise_email: true,
format: { without: /@example\.(com|org|net)\z/,
message: N_("Let's Encrypt does not accept emails on example.com") },
allow_blank: true
validates :lets_encrypt_notification_email,
presence: true,
if: :lets_encrypt_terms_of_service_accepted?
validates_with X509CertificateCredentialsValidator, validates_with X509CertificateCredentialsValidator,
certificate: :external_auth_client_cert, certificate: :external_auth_client_cert,
pkey: :external_auth_client_key, pkey: :external_auth_client_key,
......
...@@ -5,16 +5,33 @@ ...@@ -5,16 +5,33 @@
.form-group .form-group
= f.label :max_pages_size, 'Maximum size of pages (MB)', class: 'label-bold' = f.label :max_pages_size, 'Maximum size of pages (MB)', class: 'label-bold'
= f.number_field :max_pages_size, class: 'form-control' = f.number_field :max_pages_size, class: 'form-control'
.form-text.text-muted 0 for unlimited .form-text.text-muted
= _("0 for unlimited")
.form-group .form-group
.form-check .form-check
= f.check_box :pages_domain_verification_enabled, class: 'form-check-input' = f.check_box :pages_domain_verification_enabled, class: 'form-check-input'
= f.label :pages_domain_verification_enabled, class: 'form-check-label' do = f.label :pages_domain_verification_enabled, class: 'form-check-label' do
Require users to prove ownership of custom domains = _("Require users to prove ownership of custom domains")
.form-text.text-muted .form-text.text-muted
Domain verification is an essential security measure for public GitLab = _("Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled")
sites. Users are required to demonstrate they control a domain before
it is enabled
= link_to icon('question-circle'), help_page_path('user/project/pages/getting_started_part_three.md', anchor: 'dns-txt-record') = link_to icon('question-circle'), help_page_path('user/project/pages/getting_started_part_three.md', anchor: 'dns-txt-record')
- if Feature.enabled?(:pages_auto_ssl)
%h5
= _("Configure Let's Encrypt")
%p
- lets_encrypt_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: "https://letsencrypt.org/" }
= _("%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA), that give digital certificates in order to enable HTTPS (SSL/TLS) for websites.").html_safe % { lets_encrypt_link_start: lets_encrypt_link_start, lets_encrypt_link_end: '</a>'.html_safe }
.form-group
= f.label :lets_encrypt_notification_email, _("Email"), class: 'label-bold'
= f.text_field :lets_encrypt_notification_email, class: 'form-control'
.form-text.text-muted
= _("A Let's Encrypt account will be configured for this GitLab installation using your email address. You will receive emails to warn of expiring certificates.")
.form-group
.form-check
= f.check_box :lets_encrypt_terms_of_service_accepted, class: 'form-check-input'
= f.label :lets_encrypt_terms_of_service_accepted, class: 'form-check-label' do
// Terms of Service should actually be a link, but the best way to get the url is using API
// So it will be done in later MR
= _("I have read and agree to the Let's Encrypt Terms of Service")
= f.submit 'Save changes', class: "btn btn-success" = f.submit _('Save changes'), class: "btn btn-success"
# frozen_string_literal: true
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddLetsEncryptNotificationEmailToApplicationSettings < ActiveRecord::Migration[5.0]
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
def change
add_column :application_settings, :lets_encrypt_notification_email, :string
end
end
# frozen_string_literal: true
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddLetsEncryptTermsOfServiceAcceptedToApplicationSettings < ActiveRecord::Migration[5.0]
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
disable_ddl_transaction!
def up
add_column_with_default(:application_settings, :lets_encrypt_terms_of_service_accepted, :boolean, default: false)
end
def down
remove_column :application_settings, :lets_encrypt_terms_of_service_accepted
end
end
...@@ -187,6 +187,8 @@ ActiveRecord::Schema.define(version: 20190426180107) do ...@@ -187,6 +187,8 @@ ActiveRecord::Schema.define(version: 20190426180107) do
t.string "encrypted_external_auth_client_key_iv" t.string "encrypted_external_auth_client_key_iv"
t.string "encrypted_external_auth_client_key_pass" t.string "encrypted_external_auth_client_key_pass"
t.string "encrypted_external_auth_client_key_pass_iv" t.string "encrypted_external_auth_client_key_pass_iv"
t.string "lets_encrypt_notification_email"
t.boolean "lets_encrypt_terms_of_service_accepted", default: false, null: false
t.index ["usage_stats_set_by_user_id"], name: "index_application_settings_on_usage_stats_set_by_user_id", using: :btree t.index ["usage_stats_set_by_user_id"], name: "index_application_settings_on_usage_stats_set_by_user_id", using: :btree
end end
......
...@@ -138,6 +138,9 @@ msgstr "" ...@@ -138,6 +138,9 @@ msgstr ""
msgid "%{label_for_message} unavailable" msgid "%{label_for_message} unavailable"
msgstr "" msgstr ""
msgid "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA), that give digital certificates in order to enable HTTPS (SSL/TLS) for websites."
msgstr ""
msgid "%{level_name} is not allowed in a %{group_level_name} group." msgid "%{level_name} is not allowed in a %{group_level_name} group."
msgstr "" msgstr ""
...@@ -245,6 +248,9 @@ msgstr "" ...@@ -245,6 +248,9 @@ msgstr ""
msgid "- show less" msgid "- show less"
msgstr "" msgstr ""
msgid "0 for unlimited"
msgstr ""
msgid "1 %{type} addition" msgid "1 %{type} addition"
msgid_plural "%{count} %{type} additions" msgid_plural "%{count} %{type} additions"
msgstr[0] "" msgstr[0] ""
...@@ -366,6 +372,9 @@ msgstr "" ...@@ -366,6 +372,9 @@ msgstr ""
msgid "A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features." msgid "A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr "" msgstr ""
msgid "A Let's Encrypt account will be configured for this GitLab installation using your email address. You will receive emails to warn of expiring certificates."
msgstr ""
msgid "A default branch cannot be chosen for an empty project." msgid "A default branch cannot be chosen for an empty project."
msgstr "" msgstr ""
...@@ -2525,6 +2534,9 @@ msgstr "" ...@@ -2525,6 +2534,9 @@ msgstr ""
msgid "Configure Gitaly timeouts." msgid "Configure Gitaly timeouts."
msgstr "" msgstr ""
msgid "Configure Let's Encrypt"
msgstr ""
msgid "Configure automatic git checks and housekeeping on repositories." msgid "Configure automatic git checks and housekeeping on repositories."
msgstr "" msgstr ""
...@@ -3280,6 +3292,9 @@ msgstr "" ...@@ -3280,6 +3292,9 @@ msgstr ""
msgid "Domain" msgid "Domain"
msgstr "" msgstr ""
msgid "Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled"
msgstr ""
msgid "Don't show again" msgid "Don't show again"
msgstr "" msgstr ""
...@@ -4622,6 +4637,9 @@ msgstr "" ...@@ -4622,6 +4637,9 @@ msgstr ""
msgid "I accept the|Terms of Service and Privacy Policy" msgid "I accept the|Terms of Service and Privacy Policy"
msgstr "" msgstr ""
msgid "I have read and agree to the Let's Encrypt Terms of Service"
msgstr ""
msgid "ID" msgid "ID"
msgstr "" msgstr ""
...@@ -5311,6 +5329,9 @@ msgstr "" ...@@ -5311,6 +5329,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values." msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr "" msgstr ""
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
msgid "Limited to showing %d event at most" msgid "Limited to showing %d event at most"
msgid_plural "Limited to showing %d events at most" msgid_plural "Limited to showing %d events at most"
msgstr[0] "" msgstr[0] ""
...@@ -7626,6 +7647,9 @@ msgstr "" ...@@ -7626,6 +7647,9 @@ msgstr ""
msgid "Require all users to accept Terms of Service and Privacy Policy when they access GitLab." msgid "Require all users to accept Terms of Service and Privacy Policy when they access GitLab."
msgstr "" msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
msgid "Resend invite" msgid "Resend invite"
msgstr "" msgstr ""
......
...@@ -375,6 +375,37 @@ describe 'Admin updates settings' do ...@@ -375,6 +375,37 @@ describe 'Admin updates settings' do
expect(Gitlab::CurrentSettings.pages_domain_verification_enabled?).to be_truthy expect(Gitlab::CurrentSettings.pages_domain_verification_enabled?).to be_truthy
expect(page).to have_content "Application settings saved successfully" expect(page).to have_content "Application settings saved successfully"
end end
context 'When pages_auto_ssl is enabled' do
before do
stub_feature_flags(pages_auto_ssl: true)
visit preferences_admin_application_settings_path
end
it "Change Pages Let's Encrypt settings" do
page.within('.as-pages') do
fill_in 'Email', with: 'my@test.example.com'
check "I have read and agree to the Let's Encrypt Terms of Service"
click_button 'Save changes'
end
expect(Gitlab::CurrentSettings.lets_encrypt_notification_email).to eq 'my@test.example.com'
expect(Gitlab::CurrentSettings.lets_encrypt_terms_of_service_accepted).to eq true
end
end
context 'When pages_auto_ssl is disabled' do
before do
stub_feature_flags(pages_auto_ssl: false)
visit preferences_admin_application_settings_path
end
it "Doesn't show Let's Encrypt options" do
page.within('.as-pages') do
expect(page).not_to have_content('Email')
end
end
end
end end
def check_all_events def check_all_events
......
...@@ -31,6 +31,20 @@ describe ApplicationSetting do ...@@ -31,6 +31,20 @@ describe ApplicationSetting do
it { is_expected.to allow_value("dev.gitlab.com").for(:commit_email_hostname) } it { is_expected.to allow_value("dev.gitlab.com").for(:commit_email_hostname) }
it { is_expected.not_to allow_value("@dev.gitlab").for(:commit_email_hostname) } it { is_expected.not_to allow_value("@dev.gitlab").for(:commit_email_hostname) }
it { is_expected.to allow_value("myemail@gitlab.com").for(:lets_encrypt_notification_email) }
it { is_expected.to allow_value(nil).for(:lets_encrypt_notification_email) }
it { is_expected.not_to allow_value("notanemail").for(:lets_encrypt_notification_email) }
it { is_expected.not_to allow_value("myemail@example.com").for(:lets_encrypt_notification_email) }
it { is_expected.to allow_value("myemail@test.example.com").for(:lets_encrypt_notification_email) }
context "when user accepted let's encrypt terms of service" do
before do
setting.update(lets_encrypt_terms_of_service_accepted: true)
end
it { is_expected.not_to allow_value(nil).for(:lets_encrypt_notification_email) }
end
describe 'default_artifacts_expire_in' do describe 'default_artifacts_expire_in' do
it 'sets an error if it cannot parse' do it 'sets an error if it cannot parse' do
setting.update(default_artifacts_expire_in: 'a') setting.update(default_artifacts_expire_in: 'a')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment