From 018ee774577197d895b274d248176d62aa364ecf Mon Sep 17 00:00:00 2001 From: Lauren Barker Date: Mon, 20 Dec 2021 22:14:44 +0000 Subject: [PATCH 1/6] Add Bizible script This adds the Bizible scripts on the sign in/up and trial sign up page. To align with our privacy policy the script only gets activated when the `Bizible` is set in the config on GitLab.com and when there is no signed in user. Resolves https://gitlab.com/gitlab-com/marketing/digital-experience/buyer-experience/-/issues/211 --- app/controllers/concerns/bizible_csp.rb | 19 ++++++++++++ app/controllers/registrations_controller.rb | 1 + app/controllers/sessions_controller.rb | 1 + app/helpers/bizible_helper.rb | 10 ++++++ .../devise/confirmations/almost_there.haml | 1 + app/views/devise/registrations/new.html.haml | 1 + app/views/devise/sessions/new.html.haml | 1 + app/views/layouts/_bizible.html.haml | 4 +++ config/gitlab.yml.example | 3 ++ .../trial_registrations_controller.rb | 1 + .../views/trial_registrations/new.html.haml | 2 ++ spec/features/users/login_spec.rb | 12 +++++++ spec/helpers/bizible_helper_spec.rb | 31 +++++++++++++++++++ 13 files changed, 87 insertions(+) create mode 100644 app/controllers/concerns/bizible_csp.rb create mode 100644 app/helpers/bizible_helper.rb create mode 100644 app/views/layouts/_bizible.html.haml create mode 100644 spec/helpers/bizible_helper_spec.rb diff --git a/app/controllers/concerns/bizible_csp.rb b/app/controllers/concerns/bizible_csp.rb new file mode 100644 index 00000000000000..96adf526365b7b --- /dev/null +++ b/app/controllers/concerns/bizible_csp.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module BizibleCSP + extend ActiveSupport::Concern + + included do + content_security_policy do |policy| + next unless helpers.bizible_enabled? || policy.directives.present? + + default_script_src = policy.directives['script-src'] || policy.directives['default-src'] + script_src_values = Array.wrap(default_script_src) | ["'unsafe-eval'", 'https://cdn.cookielaw.org', 'https://cdn.bizible.com/scripts/bizible.js'] + policy.script_src(*script_src_values) + + default_connect_src = policy.directives['connect-src'] || policy.directives['default-src'] + connect_src_values = Array.wrap(default_connect_src) | ['https://cdn.cookielaw.org', 'https://cdn.bizible.com/scripts/bizible.js'] + policy.connect_src(*connect_src_values) + end + end +end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 7b688c0ccc28e8..057c451ace21b1 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -6,6 +6,7 @@ class RegistrationsController < Devise::RegistrationsController include RecaptchaHelper include InvisibleCaptchaOnSignup include OneTrustCSP + include BizibleCSP layout 'devise' diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 7e8e3ea878928b..e907e291eeb2cb 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -10,6 +10,7 @@ class SessionsController < Devise::SessionsController include KnownSignIn include Gitlab::Utils::StrongMemoize include OneTrustCSP + include BizibleCSP skip_before_action :check_two_factor_requirement, only: [:destroy] skip_before_action :check_password_expiration, only: [:destroy] diff --git a/app/helpers/bizible_helper.rb b/app/helpers/bizible_helper.rb new file mode 100644 index 00000000000000..970cc6558da9f6 --- /dev/null +++ b/app/helpers/bizible_helper.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module BizibleHelper + def bizible_enabled? + Feature.enabled?(:ecomm_instrumentation, type: :ops) && + Gitlab.config.extra.has_key?('bizible') && + Gitlab.config.extra.bizible.present? && + Gitlab.config.extra.bizible == true + end +end diff --git a/app/views/devise/confirmations/almost_there.haml b/app/views/devise/confirmations/almost_there.haml index 1d46a43e5bdd60..ef19ac33a155c7 100644 --- a/app/views/devise/confirmations/almost_there.haml +++ b/app/views/devise/confirmations/almost_there.haml @@ -4,6 +4,7 @@ - content_for :page_specific_javascripts do = render "layouts/google_tag_manager_head" = render "layouts/one_trust" + = render "layouts/bizible" = render "layouts/google_tag_manager_body" .well-confirmation.gl-text-center.gl-mb-6 diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 87108c8ea78cfb..60c3df718a15b1 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -3,6 +3,7 @@ - content_for :page_specific_javascripts do = render "layouts/google_tag_manager_head" = render "layouts/one_trust" + = render "layouts/bizible" = render "layouts/google_tag_manager_body" .signup-page diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml index 175b45dbbfaef0..c669f3efec6314 100644 --- a/app/views/devise/sessions/new.html.haml +++ b/app/views/devise/sessions/new.html.haml @@ -1,6 +1,7 @@ - page_title _("Sign in") - content_for :page_specific_javascripts do = render "layouts/one_trust" + = render "layouts/bizible" #signin-container - if any_form_based_providers_enabled? diff --git a/app/views/layouts/_bizible.html.haml b/app/views/layouts/_bizible.html.haml new file mode 100644 index 00000000000000..6014f7187f0349 --- /dev/null +++ b/app/views/layouts/_bizible.html.haml @@ -0,0 +1,4 @@ +- if bizible_enabled? + + = javascript_include_tag "//cdn.bizible.com/scripts/bizible.js" + diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index bcb34548f8175a..6758afc91c4660 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -1332,6 +1332,9 @@ production: &base ## OneTrust # one_trust_id: '_your_one_trust_id' + ## Bizible. + # bizible: true + ## Matomo analytics. # matomo_url: '_your_matomo_url' # matomo_site_id: '_your_matomo_site_id' diff --git a/ee/app/controllers/trial_registrations_controller.rb b/ee/app/controllers/trial_registrations_controller.rb index 56a49ab6e70693..e83291a111247c 100644 --- a/ee/app/controllers/trial_registrations_controller.rb +++ b/ee/app/controllers/trial_registrations_controller.rb @@ -4,6 +4,7 @@ # TODO: namespace https://gitlab.com/gitlab-org/gitlab/-/issues/338394 class TrialRegistrationsController < RegistrationsController include OneTrustCSP + include BizibleCSP layout 'minimal' diff --git a/ee/app/views/trial_registrations/new.html.haml b/ee/app/views/trial_registrations/new.html.haml index 7aa1abfad5dd8c..39800da3800547 100644 --- a/ee/app/views/trial_registrations/new.html.haml +++ b/ee/app/views/trial_registrations/new.html.haml @@ -3,6 +3,8 @@ - content_for :page_specific_javascripts do = render "layouts/google_tag_manager_head" = render "layouts/one_trust" + = render "layouts/bizible" + = render "layouts/google_tag_manager_body" .row diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb index 2780549eea1a0f..87f6d920e70be7 100644 --- a/spec/features/users/login_spec.rb +++ b/spec/features/users/login_spec.rb @@ -183,6 +183,18 @@ end end + describe 'with Bizible' do + before do + stub_config(extra: { bizible: SecureRandom.uuid }) + end + + it 'has proper Content-Security-Policy headers' do + visit root_path + + expect(response_headers['Content-Security-Policy']).to include('https://cdn.bizible.com/scripts/bizible.js') + end + end + describe 'with two-factor authentication', :js do def enter_code(code) fill_in 'user_otp_attempt', with: code diff --git a/spec/helpers/bizible_helper_spec.rb b/spec/helpers/bizible_helper_spec.rb new file mode 100644 index 00000000000000..19510d4218a392 --- /dev/null +++ b/spec/helpers/bizible_helper_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe BizibleHelper do + describe '#bizible_enabled?' do + before do + stub_config(extra: { bizible: SecureRandom.uuid }) + end + + subject(:bizible_enabled?) { helper.bizible_enabled? } + + context 'with ecomm_instrumentation feature flag disabled' do + before do + stub_feature_flags(ecomm_instrumentation: false) + end + + it { is_expected.to be_falsey } + end + + context 'with ecomm_instrumentation feature flag enabled' do + context 'when no id is set' do + before do + stub_config(extra: {}) + end + + it { is_expected.to be_falsey } + end + end + end +end -- GitLab From f6fda05ba0c79fe394927b82df3574c28237fa94 Mon Sep 17 00:00:00 2001 From: Lauren Barker Date: Wed, 5 Jan 2022 17:02:50 -0700 Subject: [PATCH 2/6] Apply suggestions from reviewers specify https protocol for bizible script, and extract bizible_csp.rb into a private method. Add bizzible script to 2 additional layouts missed --- app/controllers/concerns/bizible_csp.rb | 4 ++-- app/views/layouts/_bizible.html.haml | 12 +++++++++++- app/views/registrations/welcome/show.html.haml | 1 + app/views/users/terms/index.html.haml | 1 + spec/helpers/bizible_helper_spec.rb | 1 + 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/app/controllers/concerns/bizible_csp.rb b/app/controllers/concerns/bizible_csp.rb index 96adf526365b7b..43062a70599a31 100644 --- a/app/controllers/concerns/bizible_csp.rb +++ b/app/controllers/concerns/bizible_csp.rb @@ -8,11 +8,11 @@ module BizibleCSP next unless helpers.bizible_enabled? || policy.directives.present? default_script_src = policy.directives['script-src'] || policy.directives['default-src'] - script_src_values = Array.wrap(default_script_src) | ["'unsafe-eval'", 'https://cdn.cookielaw.org', 'https://cdn.bizible.com/scripts/bizible.js'] + script_src_values = Array.wrap(default_script_src) | ["'unsafe-eval'", 'https://cdn.bizible.com/scripts/bizible.js'] policy.script_src(*script_src_values) default_connect_src = policy.directives['connect-src'] || policy.directives['default-src'] - connect_src_values = Array.wrap(default_connect_src) | ['https://cdn.cookielaw.org', 'https://cdn.bizible.com/scripts/bizible.js'] + connect_src_values = Array.wrap(default_connect_src) | ['https://cdn.bizible.com/scripts/bizible.js'] policy.connect_src(*connect_src_values) end end diff --git a/app/views/layouts/_bizible.html.haml b/app/views/layouts/_bizible.html.haml index 6014f7187f0349..a2b28c138e5804 100644 --- a/app/views/layouts/_bizible.html.haml +++ b/app/views/layouts/_bizible.html.haml @@ -1,4 +1,14 @@ - if bizible_enabled? - = javascript_include_tag "//cdn.bizible.com/scripts/bizible.js" + = javascript_include_tag "https://cdn.bizible.com/scripts/bizible.js" + = javascript_tag nonce: content_security_policy_nonce do + :plain + const bizibleScript = document.createElement('script'); + bizibleScript.src = 'https://cdn.bizible.com/scripts/bizible.js'; + bizibleScript.nonce = '#{content_security_policy_nonce}' + bizibleScript.charset = 'UTF-8'; + bizibleScript.defer = true; + document.head.appendChild(bizibleScript); + + function OptanonWrapper() { } diff --git a/app/views/registrations/welcome/show.html.haml b/app/views/registrations/welcome/show.html.haml index ca2f225a2d8d98..44dffdbf70aef2 100644 --- a/app/views/registrations/welcome/show.html.haml +++ b/app/views/registrations/welcome/show.html.haml @@ -5,6 +5,7 @@ - content_for :page_specific_javascripts do = render "layouts/google_tag_manager_head" = render "layouts/one_trust" + = render "layouts/bizible" = render "layouts/google_tag_manager_body" .row.gl-flex-grow-1 diff --git a/app/views/users/terms/index.html.haml b/app/views/users/terms/index.html.haml index c461250fc9b9a3..afe257c2fc2c64 100644 --- a/app/views/users/terms/index.html.haml +++ b/app/views/users/terms/index.html.haml @@ -1,6 +1,7 @@ - content_for :page_specific_javascripts do = render "layouts/google_tag_manager_head" = render "layouts/one_trust" + = render "layouts/bizible" = render "layouts/google_tag_manager_body" #js-terms-of-service{ data: { terms_data: terms_data(@term, @redirect) } } diff --git a/spec/helpers/bizible_helper_spec.rb b/spec/helpers/bizible_helper_spec.rb index 19510d4218a392..1568417aadaf48 100644 --- a/spec/helpers/bizible_helper_spec.rb +++ b/spec/helpers/bizible_helper_spec.rb @@ -5,6 +5,7 @@ RSpec.describe BizibleHelper do describe '#bizible_enabled?' do before do + stub_feature_flags(ecomm_instrumentation: true) stub_config(extra: { bizible: SecureRandom.uuid }) end -- GitLab From d3a16c6f05c734edcbdd65a59203693c290b87bb Mon Sep 17 00:00:00 2001 From: Lauren Barker Date: Mon, 24 Jan 2022 11:03:32 -0700 Subject: [PATCH 3/6] Add Bizible spec to check if true --- spec/helpers/bizible_helper_spec.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spec/helpers/bizible_helper_spec.rb b/spec/helpers/bizible_helper_spec.rb index 1568417aadaf48..e992d19198ec02 100644 --- a/spec/helpers/bizible_helper_spec.rb +++ b/spec/helpers/bizible_helper_spec.rb @@ -9,6 +9,22 @@ stub_config(extra: { bizible: SecureRandom.uuid }) end + context 'when bizible is disabled' do + before do + allow(helper).to receive(:bizible_enabled?).and_return(false) + end + + it { is_expected.to be_falsey } + end + + context 'when bizible is disabled' do + before do + allow(helper).to receive(:bizible_enabled?).and_return(true) + end + + it { is_expected.to be_truthy } + end + subject(:bizible_enabled?) { helper.bizible_enabled? } context 'with ecomm_instrumentation feature flag disabled' do -- GitLab From 2fcc66fffdde5086df33ef4e1180e0cae90d73e1 Mon Sep 17 00:00:00 2001 From: Maxime Orefice Date: Thu, 27 Jan 2022 16:14:05 +0000 Subject: [PATCH 4/6] Fix spelling typo --- spec/helpers/bizible_helper_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/helpers/bizible_helper_spec.rb b/spec/helpers/bizible_helper_spec.rb index e992d19198ec02..3617a05f1eb0d5 100644 --- a/spec/helpers/bizible_helper_spec.rb +++ b/spec/helpers/bizible_helper_spec.rb @@ -17,7 +17,7 @@ it { is_expected.to be_falsey } end - context 'when bizible is disabled' do + context 'when bizible is enabled' do before do allow(helper).to receive(:bizible_enabled?).and_return(true) end -- GitLab From 32592f85eca14a7e3ac4eae83aecb30ccf2a52e7 Mon Sep 17 00:00:00 2001 From: Lauren Barker Date: Mon, 7 Feb 2022 10:30:07 -0700 Subject: [PATCH 5/6] Applie 3 suggestions to: 1. remove connect-src, add test spec - rebase this 2. Bizible content security policy extracted to own spec 3. remove feature flag from bizible spec --- app/controllers/concerns/bizible_csp.rb | 4 ---- spec/features/users/bizible_csp_spec.rb | 17 +++++++++++++++++ spec/helpers/bizible_helper_spec.rb | 1 - 3 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 spec/features/users/bizible_csp_spec.rb diff --git a/app/controllers/concerns/bizible_csp.rb b/app/controllers/concerns/bizible_csp.rb index 43062a70599a31..521f3127759493 100644 --- a/app/controllers/concerns/bizible_csp.rb +++ b/app/controllers/concerns/bizible_csp.rb @@ -10,10 +10,6 @@ module BizibleCSP default_script_src = policy.directives['script-src'] || policy.directives['default-src'] script_src_values = Array.wrap(default_script_src) | ["'unsafe-eval'", 'https://cdn.bizible.com/scripts/bizible.js'] policy.script_src(*script_src_values) - - default_connect_src = policy.directives['connect-src'] || policy.directives['default-src'] - connect_src_values = Array.wrap(default_connect_src) | ['https://cdn.bizible.com/scripts/bizible.js'] - policy.connect_src(*connect_src_values) end end end diff --git a/spec/features/users/bizible_csp_spec.rb b/spec/features/users/bizible_csp_spec.rb new file mode 100644 index 00000000000000..4214fcf73c86dd --- /dev/null +++ b/spec/features/users/bizible_csp_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Bizible content security policy' do + let(:user) { create(:user) } + + before do + stub_config(extra: { one_trust_id: SecureRandom.uuid }) + end + + it 'has proper Content Security Policy headers' do + visit root_path + + expect(response_headers['Content-Security-Policy']).to include('https://cdn.bizible.com/scripts/bizible.js') + end +end diff --git a/spec/helpers/bizible_helper_spec.rb b/spec/helpers/bizible_helper_spec.rb index 3617a05f1eb0d5..b82211d51ec305 100644 --- a/spec/helpers/bizible_helper_spec.rb +++ b/spec/helpers/bizible_helper_spec.rb @@ -5,7 +5,6 @@ RSpec.describe BizibleHelper do describe '#bizible_enabled?' do before do - stub_feature_flags(ecomm_instrumentation: true) stub_config(extra: { bizible: SecureRandom.uuid }) end -- GitLab From fd8e0bfd59dea709737e65d7e031fbe5ae76e1a7 Mon Sep 17 00:00:00 2001 From: Lauren Barker Date: Wed, 9 Feb 2022 10:02:14 -0700 Subject: [PATCH 6/6] Apply two suggestions Remove bizible from login spec since it has it's own Update create user for Bizible feature spec --- spec/features/users/bizible_csp_spec.rb | 2 -- spec/features/users/login_spec.rb | 12 ------------ 2 files changed, 14 deletions(-) diff --git a/spec/features/users/bizible_csp_spec.rb b/spec/features/users/bizible_csp_spec.rb index 4214fcf73c86dd..af0b42050b3fd2 100644 --- a/spec/features/users/bizible_csp_spec.rb +++ b/spec/features/users/bizible_csp_spec.rb @@ -3,8 +3,6 @@ require 'spec_helper' RSpec.describe 'Bizible content security policy' do - let(:user) { create(:user) } - before do stub_config(extra: { one_trust_id: SecureRandom.uuid }) end diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb index 87f6d920e70be7..2780549eea1a0f 100644 --- a/spec/features/users/login_spec.rb +++ b/spec/features/users/login_spec.rb @@ -183,18 +183,6 @@ end end - describe 'with Bizible' do - before do - stub_config(extra: { bizible: SecureRandom.uuid }) - end - - it 'has proper Content-Security-Policy headers' do - visit root_path - - expect(response_headers['Content-Security-Policy']).to include('https://cdn.bizible.com/scripts/bizible.js') - end - end - describe 'with two-factor authentication', :js do def enter_code(code) fill_in 'user_otp_attempt', with: code -- GitLab