diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-06-07 14:47:00 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-06-07 14:47:00 +0000 |
commit | 08086ff522742c28a6b10e9b2ed71f0af6633e5b (patch) | |
tree | 5a4fde8b23140cb4edf04b24854b53f87085dd42 | |
parent | 8f3fbbf0d56091ad87158f61bf2a4e96a7f937e3 (diff) | |
download | gitlab-ce-08086ff522742c28a6b10e9b2ed71f0af6633e5b.tar.gz |
Add latest changes from gitlab-org/gitlab@13-12-stable-ee
24 files changed, 129 insertions, 86 deletions
diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml index 5cd64baf4d3..68804b0f4c1 100644 --- a/.gitlab/ci/rails.gitlab-ci.yml +++ b/.gitlab/ci/rails.gitlab-ci.yml @@ -344,7 +344,7 @@ db:migrate-from-previous-major-version: - sed -i -e "s/gem 'grpc', '~> 1.24.0'/gem 'grpc', '~> 1.30.2'/" Gemfile # Update gRPC for Ruby 2.7 - sed -i -e "s/gem 'google-protobuf', '~> 3.8.0'/gem 'google-protobuf', '~> 3.12'/" Gemfile - sed -i -e "s/gem 'nokogiri', '~> 1.10.5'/gem 'nokogiri', '~> 1.11.0'/" Gemfile - - sed -i -e "s/gem 'mimemagic', '~> 0.3.2'/gem 'ruby-magic', '~> 0.3.2'/" Gemfile + - sed -i -e "s/gem 'mimemagic', '~> 0.3.2'/gem 'ruby-magic', '~> 0.4.0'/" Gemfile - run_timed_command "gem install bundler:1.17.3" - run_timed_command "bundle update google-protobuf nokogiri grpc mimemagic bootsnap" - run_timed_command "bundle install ${BUNDLE_INSTALL_FLAGS}" diff --git a/app/services/spam/akismet_service.rb b/app/services/spam/akismet_service.rb index 4e56972ccd5..e9843497dd7 100644 --- a/app/services/spam/akismet_service.rb +++ b/app/services/spam/akismet_service.rb @@ -20,14 +20,18 @@ module Spam created_at: DateTime.current, author: owner_name, author_email: owner_email, - referer: options[:referer] + referrer: options[:referer] } begin is_spam, is_blatant = akismet_client.check(options[:ip_address], options[:user_agent], params) is_spam || is_blatant + rescue ArgumentError => e + Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e) + false rescue StandardError => e - Gitlab::AppLogger.error("Unable to connect to Akismet: #{e}, skipping check") + Gitlab::ErrorTracking.track_exception(e) + Gitlab::AppLogger.error("Error during Akismet spam check, flagging as not spam: #{e}") false end end diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml index 98af69d43b7..82c0df354d4 100644 --- a/app/views/devise/sessions/_new_base.html.haml +++ b/app/views/devise/sessions/_new_base.html.haml @@ -17,7 +17,7 @@ = link_to _('Forgot your password?'), new_password_path(:user) %div - if captcha_enabled? || captcha_on_login_required? - = recaptcha_tags + = recaptcha_tags nonce: content_security_policy_nonce .submit-container.move-submit-down = f.submit _('Sign in'), class: 'gl-button btn btn-confirm', data: { qa_selector: 'sign_in_button' } diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml index 56f74916d8f..1b410f0b671 100644 --- a/app/views/devise/shared/_signup_box.html.haml +++ b/app/views/devise/shared/_signup_box.html.haml @@ -11,7 +11,7 @@ .devise-errors = render 'devise/shared/error_messages', resource: resource - if Gitlab::CurrentSettings.invisible_captcha_enabled - = invisible_captcha + = invisible_captcha nonce: true .name.form-row .col.form-group = f.label :first_name, _('First name'), for: 'new_user_first_name', class: 'label-bold' @@ -34,7 +34,7 @@ %p.gl-field-hint.text-secondary= s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length } %div - if show_recaptcha_sign_up? - = recaptcha_tags + = recaptcha_tags nonce: content_security_policy_nonce .submit-container = f.submit button_text, class: 'btn gl-button btn-confirm', data: { qa_selector: 'new_user_register_button' } = render 'devise/shared/terms_of_service_notice', button_text: button_text diff --git a/app/views/groups/_new_group_fields.html.haml b/app/views/groups/_new_group_fields.html.haml index fd0a7af30ed..fbf9438718e 100644 --- a/app/views/groups/_new_group_fields.html.haml +++ b/app/views/groups/_new_group_fields.html.haml @@ -20,7 +20,7 @@ - if captcha_required? .row.recaptcha .col-sm-4 - = recaptcha_tags + = recaptcha_tags nonce: content_security_policy_nonce .row .form-actions.col-sm-12 = f.submit _('Create group'), class: "btn gl-button btn-confirm" diff --git a/app/views/notify/ssh_key_expired_email.html.haml b/app/views/notify/ssh_key_expired_email.html.haml index 21138bb0113..651bdac7acb 100644 --- a/app/views/notify/ssh_key_expired_email.html.haml +++ b/app/views/notify/ssh_key_expired_email.html.haml @@ -1,7 +1,7 @@ %p = _('Hi %{username}!') % { username: sanitize_name(@user.name) } %p - = _('Your SSH keys with the following fingerprints has expired:') + = _('Your SSH keys with the following fingerprints have expired. Expired SSH keys will not be usable in future versions of GitLab:') %table %tbody - @fingerprints.each do |fingerprint| diff --git a/app/views/notify/ssh_key_expired_email.text.erb b/app/views/notify/ssh_key_expired_email.text.erb index 77b76084606..aa6e79d59b8 100644 --- a/app/views/notify/ssh_key_expired_email.text.erb +++ b/app/views/notify/ssh_key_expired_email.text.erb @@ -1,6 +1,6 @@ <%= _('Hi %{username}!') % { username: sanitize_name(@user.name) } %> -<%= _('Your SSH keys with the following fingerprints has expired:') %> +<%= _('Your SSH keys with the following fingerprints have expired. Expired SSH keys will not be usable in future versions of GitLab:') %> <% @fingerprints.each do |fingerprint| %> - <%= fingerprint %> diff --git a/app/views/notify/ssh_key_expiring_soon.text.erb b/app/views/notify/ssh_key_expiring_soon.text.erb index 2a7c0cafe83..ff6feb87662 100644 --- a/app/views/notify/ssh_key_expiring_soon.text.erb +++ b/app/views/notify/ssh_key_expiring_soon.text.erb @@ -1,6 +1,6 @@ <%= _('Hi %{username}!') % { username: sanitize_name(@user.name) } %> -<%= _('Your SSH keys with the following fingerprints are scheduled to expire soon:') %> +<%= _('Your SSH keys with the following fingerprints are scheduled to expire soon. Expired SSH keys will not be usable in future versions of GitLab:') %> <% @fingerprints.each do |fingerprint| %> - <%= fingerprint %> diff --git a/app/views/notify/ssh_key_expiring_soon_email.html.haml b/app/views/notify/ssh_key_expiring_soon_email.html.haml index f4aee9c5fde..924165ecf3d 100644 --- a/app/views/notify/ssh_key_expiring_soon_email.html.haml +++ b/app/views/notify/ssh_key_expiring_soon_email.html.haml @@ -1,7 +1,7 @@ %p = _('Hi %{username}!') % { username: sanitize_name(@user.name) } %p - = _('Your SSH keys with the following fingerprints are scheduled to expire soon:') + = _('Your SSH keys with the following fingerprints are scheduled to expire soon. Expired SSH keys will not be usable in future versions of GitLab:') %table %tbody - @fingerprints.each do |fingerprint| diff --git a/app/views/shared/_recaptcha_form.html.haml b/app/views/shared/_recaptcha_form.html.haml index 5c5fc714aea..ae0a22fd255 100644 --- a/app/views/shared/_recaptcha_form.html.haml +++ b/app/views/shared/_recaptcha_form.html.haml @@ -10,7 +10,7 @@ = hidden_field(resource_name, field, value: value) = hidden_field_tag(:spam_log_id, spammable.spam_log.id) -# The reCAPTCHA response value will be returned in the 'g-recaptcha-response' field - = recaptcha_tags script: script, callback: 'recaptchaDialogCallback' unless Rails.env.test? + = recaptcha_tags script: script, callback: 'recaptchaDialogCallback', nonce: content_security_policy_nonce unless Rails.env.test? -# Fake the 'g-recaptcha-response' field in the test environment, so that the feature spec -# can get to the (mocked) SpamVerdictService check. = hidden_field_tag('g-recaptcha-response', 'abc123') if Rails.env.test? diff --git a/config/feature_flags/development/remove_description_html_in_release_api.yml b/config/feature_flags/development/remove_description_html_in_release_api.yml deleted file mode 100644 index 0c457dfe2e0..00000000000 --- a/config/feature_flags/development/remove_description_html_in_release_api.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: remove_description_html_in_release_api -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60380 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/329188 -milestone: '13.12' -type: development -group: group::release -default_enabled: true diff --git a/config/feature_flags/development/remove_description_html_in_release_api_override.yml b/config/feature_flags/development/remove_description_html_in_release_api_override.yml deleted file mode 100644 index f924f2ccbd5..00000000000 --- a/config/feature_flags/development/remove_description_html_in_release_api_override.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: remove_description_html_in_release_api_override -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60380 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/329188 -milestone: '13.12' -type: development -group: group::release -default_enabled: false diff --git a/doc/api/releases/index.md b/doc/api/releases/index.md index b2dc562ad27..bc37f1aa0a9 100644 --- a/doc/api/releases/index.md +++ b/doc/api/releases/index.md @@ -10,7 +10,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w > - Using this API you can manipulate GitLab [Release](../../user/project/releases/index.md) entries. > - For manipulating links as a release asset, see [Release Links API](links.md). > - Release Evidences were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26019) in GitLab 12.5. -> - `description_html` field was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/299447) in GitLab 13.12. +> - `description_html` became an opt-in field [with GitLab 13.12 for performance reasons](https://gitlab.com/gitlab-org/gitlab/-/issues/299447). + Please pass the `include_html_description` query string parameter if you need it. ## List Releases @@ -25,6 +26,7 @@ GET /projects/:id/releases | `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). | | `order_by` | string | no | The field to use as order. Either `released_at` (default) or `created_at`. | | `sort` | string | no | The direction of the order. Either `desc` (default) for descending order or `asc` for ascending order. | +| `include_html_description` | boolean | no | If `true`, a response includes HTML rendered Markdown of the release description. | Example request: @@ -228,6 +230,7 @@ GET /projects/:id/releases/:tag_name | ------------- | -------------- | -------- | ----------------------------------------------------------------------------------- | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). | | `tag_name` | string | yes | The Git tag the release is associated with. | +| `include_html_description` | boolean | no | If `true`, a response includes HTML rendered Markdown of the release description. | Example request: diff --git a/doc/user/project/merge_requests/test_coverage_visualization.md b/doc/user/project/merge_requests/test_coverage_visualization.md index c25ee1a8a94..4960e9d9889 100644 --- a/doc/user/project/merge_requests/test_coverage_visualization.md +++ b/doc/user/project/merge_requests/test_coverage_visualization.md @@ -149,7 +149,7 @@ test-jdk11: stage: test image: maven:3.6.3-jdk-11 script: - - 'mvn $MAVEN_CLI_OPTS clean org.jacoco:jacoco-maven-plugin:prepare-agent test jacoco:report' + - mvn $MAVEN_CLI_OPTS clean org.jacoco:jacoco-maven-plugin:prepare-agent test jacoco:report artifacts: paths: - target/site/jacoco/jacoco.xml @@ -161,10 +161,8 @@ coverage-jdk11: stage: visualize image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7 script: - # convert report from jacoco to cobertura, use relative project path - - 'python /opt/cover2cover.py target/site/jacoco/jacoco.xml src/main/java > target/site/cobertura.xml' - # read the <source></source> tag and prepend the path to every filename attribute - - 'python /opt/source2filename.py target/site/cobertura.xml' + # convert report from jacoco to cobertura, using relative project path + - python /opt/cover2cover.py target/site/jacoco/jacoco.xml $CI_PROJECT_DIR/src/main/java/ > target/site/cobertura.xml needs: ["test-jdk11"] dependencies: - test-jdk11 @@ -201,10 +199,8 @@ coverage-jdk11: stage: visualize image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7 script: - # convert report from jacoco to cobertura, use relative project path - - 'python /opt/cover2cover.py build/jacoco/jacoco.xml src/main/java > build/cobertura.xml' - # read the <source></source> tag and prepend the path to every filename attribute - - 'python /opt/source2filename.py build/cobertura.xml' + # convert report from jacoco to cobertura, using relative project path + - python /opt/cover2cover.py build/jacoco/jacoco.xml $CI_PROJECT_DIR/src/main/java/ > build/cobertura.xml needs: ["test-jdk11"] dependencies: - test-jdk11 diff --git a/lib/api/entities/release.rb b/lib/api/entities/release.rb index 94124352298..056b54674f1 100644 --- a/lib/api/entities/release.rb +++ b/lib/api/entities/release.rb @@ -8,7 +8,7 @@ module API expose :name expose :tag, as: :tag_name, if: ->(_, _) { can_download_code? } expose :description - expose :description_html, unless: ->(_, _) { remove_description_html? } do |entity| + expose :description_html, if: -> (_, options) { options[:include_html_description] } do |entity| MarkupHelper.markdown_field(entity, :description, current_user: options[:current_user]) end expose :created_at @@ -45,11 +45,6 @@ module API def can_read_milestone? Ability.allowed?(options[:current_user], :read_milestone, object.project) end - - def remove_description_html? - ::Feature.enabled?(:remove_description_html_in_release_api, object.project, default_enabled: :yaml) && - ::Feature.disabled?(:remove_description_html_in_release_api_override, object.project) - end end end end diff --git a/lib/api/releases.rb b/lib/api/releases.rb index c65a23e334f..7cd8b442706 100644 --- a/lib/api/releases.rb +++ b/lib/api/releases.rb @@ -29,6 +29,8 @@ module API desc: 'Return releases ordered by `released_at` or `created_at`.' optional :sort, type: String, values: %w[asc desc], default: 'desc', desc: 'Return releases sorted in `asc` or `desc` order.' + optional :include_html_description, type: Boolean, + desc: 'If `true`, a response includes HTML rendered markdown of the release description.' end get ':id/releases' do releases = ::ReleasesFinder.new(user_project, current_user, declared_params.slice(:order_by, :sort)).execute @@ -43,7 +45,8 @@ module API # context is unnecessary here. cache_context: -> (_) { "user:{#{current_user&.id}}" }, expires_in: 5.minutes, - current_user: current_user + current_user: current_user, + include_html_description: params[:include_html_description] end desc 'Get a single project release' do @@ -53,11 +56,13 @@ module API end params do requires :tag_name, type: String, desc: 'The name of the tag', as: :tag + optional :include_html_description, type: Boolean, + desc: 'If `true`, a response includes HTML rendered markdown of the release description.' end get ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do authorize_download_code! - present release, with: Entities::Release, current_user: current_user + present release, with: Entities::Release, current_user: current_user, include_html_description: params[:include_html_description] end desc 'Create a new release' do diff --git a/lib/gitlab/content_security_policy/config_loader.rb b/lib/gitlab/content_security_policy/config_loader.rb index 6f6147f0f32..e42b174e085 100644 --- a/lib/gitlab/content_security_policy/config_loader.rb +++ b/lib/gitlab/content_security_policy/config_loader.rb @@ -9,21 +9,20 @@ module Gitlab def self.default_settings_hash settings_hash = { - 'enabled' => true, + 'enabled' => Rails.env.development? || Rails.env.test?, 'report_only' => false, 'directives' => { 'default_src' => "'self'", 'base_uri' => "'self'", - 'child_src' => "'none'", 'connect_src' => "'self'", 'font_src' => "'self'", 'form_action' => "'self' https: http:", 'frame_ancestors' => "'self'", - 'frame_src' => "'self' https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com", + 'frame_src' => "'self' https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com", 'img_src' => "'self' data: blob: http: https:", 'manifest_src' => "'self'", 'media_src' => "'self'", - 'script_src' => "'strict-dynamic' 'self' 'unsafe-inline' 'unsafe-eval' https://www.recaptcha.net https://apis.google.com", + 'script_src' => "'strict-dynamic' 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com/recaptcha/ https://www.recaptcha.net https://apis.google.com", 'style_src' => "'self' 'unsafe-inline'", 'worker_src' => "'self'", 'object_src' => "'none'", @@ -31,6 +30,11 @@ module Gitlab } } + # frame-src was deprecated in CSP level 2 in favor of child-src + # CSP level 3 "undeprecated" frame-src and browsers fall back on child-src if it's missing + # However Safari seems to read child-src first so we'll just keep both equal + settings_hash['directives']['child_src'] = settings_hash['directives']['frame_src'] + allow_webpack_dev_server(settings_hash) if Rails.env.development? allow_cdn(settings_hash) if ENV['GITLAB_CDN_HOST'].present? diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 49a36e7d5e7..a64a2cdb714 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -37597,10 +37597,10 @@ msgstr "" msgid "Your SSH keys (%{count})" msgstr "" -msgid "Your SSH keys with the following fingerprints are scheduled to expire soon:" +msgid "Your SSH keys with the following fingerprints are scheduled to expire soon. Expired SSH keys will not be usable in future versions of GitLab:" msgstr "" -msgid "Your SSH keys with the following fingerprints has expired:" +msgid "Your SSH keys with the following fingerprints have expired. Expired SSH keys will not be usable in future versions of GitLab:" msgstr "" msgid "Your To-Do List" diff --git a/spec/lib/api/entities/release_spec.rb b/spec/lib/api/entities/release_spec.rb index 4f40830a15c..aa2c5126bb9 100644 --- a/spec/lib/api/entities/release_spec.rb +++ b/spec/lib/api/entities/release_spec.rb @@ -8,7 +8,8 @@ RSpec.describe API::Entities::Release do let(:release) { create(:release, project: project) } let(:evidence) { release.evidences.first } let(:user) { create(:user) } - let(:entity) { described_class.new(release, current_user: user).as_json } + let(:entity) { described_class.new(release, current_user: user, include_html_description: include_html_description).as_json } + let(:include_html_description) { false } before do ::Releases::CreateEvidenceService.new(release).execute @@ -58,10 +59,8 @@ RSpec.describe API::Entities::Release do expect(description_html).to be_nil end - context 'when remove_description_html_in_release_api feature flag is disabled' do - before do - stub_feature_flags(remove_description_html_in_release_api: false) - end + context 'when include_html_description option is true' do + let(:include_html_description) { true } it 'renders special references if current user has access' do project.add_reporter(user) @@ -77,18 +76,5 @@ RSpec.describe API::Entities::Release do expect(description_html).not_to include(issue_title) end end - - context 'when remove_description_html_in_release_api_override feature flag is enabled' do - before do - stub_feature_flags(remove_description_html_in_release_api_override: project) - end - - it 'renders special references if current user has access' do - project.add_reporter(user) - - expect(description_html).to include(issue_path) - expect(description_html).to include(issue_title) - end - end end end diff --git a/spec/lib/gitlab/content_security_policy/config_loader_spec.rb b/spec/lib/gitlab/content_security_policy/config_loader_spec.rb index 41a6c06f9c9..19e52d2cf4a 100644 --- a/spec/lib/gitlab/content_security_policy/config_loader_spec.rb +++ b/spec/lib/gitlab/content_security_policy/config_loader_spec.rb @@ -20,9 +20,9 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do end describe '.default_settings_hash' do - it 'returns defaults for all keys' do - settings = described_class.default_settings_hash + let(:settings) { described_class.default_settings_hash } + it 'returns defaults for all keys' do expect(settings['enabled']).to be_truthy expect(settings['report_only']).to be_falsey @@ -35,6 +35,17 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do expect(directives.has_key?('report_uri')).to be_truthy expect(directives['report_uri']).to be_nil + expect(directives['child_src']).to eq(directives['frame_src']) + end + + context 'when in production' do + before do + allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('production')) + end + + it 'is disabled' do + expect(settings['enabled']).to be_falsey + end end context 'when GITLAB_CDN_HOST is set' do @@ -43,10 +54,9 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do end it 'adds GITLAB_CDN_HOST to CSP' do - settings = described_class.default_settings_hash directives = settings['directives'] - expect(directives['script_src']).to eq("'strict-dynamic' 'self' 'unsafe-inline' 'unsafe-eval' https://www.recaptcha.net https://apis.google.com https://example.com") + expect(directives['script_src']).to eq("'strict-dynamic' 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com/recaptcha/ https://www.recaptcha.net https://apis.google.com https://example.com") expect(directives['style_src']).to eq("'self' 'unsafe-inline' https://example.com") end end diff --git a/spec/mailers/emails/profile_spec.rb b/spec/mailers/emails/profile_spec.rb index 8ac1f15d67e..0ca202aa7be 100644 --- a/spec/mailers/emails/profile_spec.rb +++ b/spec/mailers/emails/profile_spec.rb @@ -264,7 +264,7 @@ RSpec.describe Emails::Profile do include_examples 'valid use case' it_behaves_like 'has the correct subject', /Your SSH key has expired/ - it_behaves_like 'has the correct body text', /Your SSH keys with the following fingerprints has expired/ + it_behaves_like 'has the correct body text', /Your SSH keys with the following fingerprints have expired/ end context 'when invalid' do diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb index 81ddcd7cf84..dad3e34404b 100644 --- a/spec/requests/api/releases_spec.rb +++ b/spec/requests/api/releases_spec.rb @@ -50,6 +50,12 @@ RSpec.describe API::Releases do expect(json_response.second['tag_name']).to eq(release_1.tag) end + it 'does not include description_html' do + get api("/projects/#{project.id}/releases", maintainer) + + expect(json_response.map { |h| h['description_html'] }).to contain_exactly(nil, nil) + end + RSpec.shared_examples 'release sorting' do |order_by| subject { get api(url, access_level), params: { sort: sort, order_by: order_by } } @@ -107,6 +113,15 @@ RSpec.describe API::Releases do expect(json_response.second['commit_path']).to eq("/#{release_1.project.full_path}/-/commit/#{release_1.commit.id}") expect(json_response.second['tag_path']).to eq("/#{release_1.project.full_path}/-/tags/#{release_1.tag}") end + + context 'when include_html_description option is true' do + it 'includes description_html field' do + get api("/projects/#{project.id}/releases", maintainer), params: { include_html_description: true } + + expect(json_response.map { |h| h['description_html'] }) + .to contain_exactly(instance_of(String), instance_of(String)) + end + end end it 'returns an upcoming_release status for a future release' do @@ -328,6 +343,12 @@ RSpec.describe API::Releases do .to match_array(release.sources.map(&:url)) end + it 'does not include description_html' do + get api("/projects/#{project.id}/releases/v0.1", maintainer) + + expect(json_response['description_html']).to eq(nil) + end + context 'with evidence' do let!(:evidence) { create(:evidence, release: release) } @@ -403,6 +424,14 @@ RSpec.describe API::Releases do end end + context 'when include_html_description option is true' do + it 'includes description_html field' do + get api("/projects/#{project.id}/releases/v0.1", maintainer), params: { include_html_description: true } + + expect(json_response['description_html']).to be_instance_of(String) + end + end + context 'when user is a guest' do it 'responds 403 Forbidden' do get api("/projects/#{project.id}/releases/v0.1", guest) diff --git a/spec/services/spam/akismet_service_spec.rb b/spec/services/spam/akismet_service_spec.rb index f75b0216b78..1cd049da592 100644 --- a/spec/services/spam/akismet_service_spec.rb +++ b/spec/services/spam/akismet_service_spec.rb @@ -4,12 +4,15 @@ require 'spec_helper' RSpec.describe Spam::AkismetService do let(:fake_akismet_client) { double(:akismet_client) } + let(:ip) { '1.2.3.4' } + let(:user_agent) { 'some user_agent' } + let(:referer) { 'some referer' } let_it_be(:text) { "Would you like to buy some tinned meat product?" } let_it_be(:spam_owner) { create(:user) } subject do - options = { ip_address: '1.2.3.4', user_agent: 'some user_agent', referrer: 'some referrer' } + options = { ip_address: ip, user_agent: user_agent, referer: referer } described_class.new(spam_owner.name, spam_owner.email, text, options) end @@ -56,6 +59,21 @@ RSpec.describe Spam::AkismetService do it_behaves_like 'no activity if Akismet is not enabled', :spam?, :check context 'if Akismet is enabled' do + it 'correctly transforms options for the akismet client' do + expected_check_params = { + type: 'comment', + text: text, + created_at: anything, + author: spam_owner.name, + author_email: spam_owner.email, + # NOTE: The akismet_client needs the option to be named `:referrer`, not `:referer` + referrer: referer + } + + expect(fake_akismet_client).to receive(:check).with(ip, user_agent, expected_check_params) + subject.spam? + end + context 'the text is spam' do before do allow(fake_akismet_client).to receive(:check).and_return([true, false]) @@ -86,19 +104,31 @@ RSpec.describe Spam::AkismetService do end end - context 'if Akismet is not available' do + describe 'error handling' do before do - allow(fake_akismet_client).to receive(:check).and_raise(StandardError.new("oh noes!")) + allow(fake_akismet_client).to receive(:check).and_raise(error) end - specify do - expect(subject.spam?).to be_falsey + context 'StandardError other than ArgumentError is raised' do + let(:error) { Akismet::Error.new("Lovely spam! Wonderful spam!") } + + specify do + expect(subject.spam?).to be_falsey + end + + it 'logs an error' do + expect(Gitlab::AppLogger).to receive(:error).with(/Error during Akismet.*flagging as not spam.*Lovely spam/) + + subject.spam? + end end - it 'logs an error' do - expect(Gitlab::AppLogger).to receive(:error).with(/skipping check/) + context 'ArgumentError is raised in dev' do + let(:error) { ArgumentError } - subject.spam? + it 'raises original error' do + expect { subject.spam? }.to raise_error(error) + end end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c59daa6c919..bd9ba53c04c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -286,9 +286,6 @@ RSpec.configure do |config| # As we're ready to change `master` usages to `main`, let's enable it stub_feature_flags(main_branch_over_master: false) - # Selectively disable by actor https://docs.gitlab.com/ee/development/feature_flags/#selectively-disable-by-actor - stub_feature_flags(remove_description_html_in_release_api_override: false) - # Disable issue respositioning to avoid heavy load on database when importing big projects. # This is only turned on when app is handling heavy project imports. # Can be removed when we find a better way to deal with the problem. |