diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-22 09:08:14 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-22 09:08:14 +0300 |
commit | f9a4c3a3b853533336efabf7631c7981c8ac7673 (patch) | |
tree | fc13e54ade7a465b75a1c167dbf0af002290c63a | |
parent | 598b0e97df747c943cff27e2bdd426c959073e07 (diff) |
Add latest changes from gitlab-org/gitlab@master
-rw-r--r-- | .gitlab/ci/package-and-test-nightly/main.gitlab-ci.yml | 5 | ||||
-rw-r--r-- | .gitlab/ci/package-and-test/main.gitlab-ci.yml | 1 | ||||
-rw-r--r-- | .gitlab/ci/rules.gitlab-ci.yml | 4 | ||||
-rw-r--r-- | GITALY_SERVER_VERSION | 2 | ||||
-rw-r--r-- | app/models/abuse/trust_score.rb | 1 | ||||
-rw-r--r-- | app/models/user.rb | 30 | ||||
-rw-r--r-- | app/models/user_custom_attribute.rb | 8 | ||||
-rw-r--r-- | app/views/shared/notes/_notes_with_form.html.haml | 2 | ||||
-rw-r--r-- | doc/administration/geo/setup/index.md | 12 | ||||
-rw-r--r-- | locale/gitlab.pot | 2 | ||||
-rw-r--r-- | qa/qa/page/component/snippet.rb | 8 | ||||
-rw-r--r-- | qa/qa/page/group/menu.rb | 2 | ||||
-rw-r--r-- | qa/qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb | 14 | ||||
-rw-r--r-- | spec/models/user_custom_attribute_spec.rb | 27 | ||||
-rw-r--r-- | spec/models/user_spec.rb | 139 |
15 files changed, 238 insertions, 19 deletions
diff --git a/.gitlab/ci/package-and-test-nightly/main.gitlab-ci.yml b/.gitlab/ci/package-and-test-nightly/main.gitlab-ci.yml index 85de1a28b66..f7fdc0175fe 100644 --- a/.gitlab/ci/package-and-test-nightly/main.gitlab-ci.yml +++ b/.gitlab/ci/package-and-test-nightly/main.gitlab-ci.yml @@ -167,7 +167,6 @@ e2e-test-report: upload-knapsack-report: extends: - .upload-knapsack-report - - .rules:report:process-results export-test-metrics: extends: @@ -177,6 +176,10 @@ relate-test-failures: extends: - .relate-test-failures +generate-test-session: + extends: + - .generate-test-session + notify-slack: extends: - .notify-slack diff --git a/.gitlab/ci/package-and-test/main.gitlab-ci.yml b/.gitlab/ci/package-and-test/main.gitlab-ci.yml index e90c0bbc7c4..2832ac1171c 100644 --- a/.gitlab/ci/package-and-test/main.gitlab-ci.yml +++ b/.gitlab/ci/package-and-test/main.gitlab-ci.yml @@ -502,7 +502,6 @@ e2e-test-report: upload-knapsack-report: extends: - .upload-knapsack-report - - .rules:report:process-results export-test-metrics: extends: diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index bb16caa68c5..f49b2e2e459 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -1475,6 +1475,7 @@ allow_failure: true variables: SKIP_REPORT_IN_ISSUES: "false" + PROCESS_TEST_RESULTS: "true" QA_SAVE_TEST_METRICS: "true" QA_EXPORT_TEST_METRICS: "false" @@ -1482,6 +1483,8 @@ rules: - if: '$QA_RUN_TESTS_ON_GDK !~ /true|yes|1/i' when: never + - <<: *if-default-branch-schedule-nightly # already executed in the 2-hourly schedule + when: never - !reference [".qa:rules:package-and-test-common", rules] - !reference [".qa:rules:package-and-test-schedule", rules] @@ -1506,6 +1509,7 @@ allow_failure: true variables: KNAPSACK_GENERATE_REPORT: "true" + PROCESS_TEST_RESULTS: "true" SKIP_REPORT_IN_ISSUES: "false" QA_SAVE_TEST_METRICS: "true" QA_EXPORT_TEST_METRICS: "false" diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 43c6a2652b9..87443f83037 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -da80ab3efcbf3dc0289aacf698ffeabc3c381275 +e66b5c2f3d56234280470d45f769779619553280 diff --git a/app/models/abuse/trust_score.rb b/app/models/abuse/trust_score.rb index 9ad7c9b14b1..b7ed504a0ba 100644 --- a/app/models/abuse/trust_score.rb +++ b/app/models/abuse/trust_score.rb @@ -3,6 +3,7 @@ module Abuse class TrustScore < ApplicationRecord MAX_EVENTS = 100 + SPAMCHECK_HAM_THRESHOLD = 0.5 self.table_name = 'abuse_trust_scores' diff --git a/app/models/user.rb b/app/models/user.rb index 5d31f9e54b4..c028dd3d865 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1670,7 +1670,7 @@ class User < ApplicationRecord new_note = format(_("User deleted own account on %{timestamp}"), timestamp: Time.zone.now) self.note = "#{new_note}\n#{note}".strip - block + block_or_ban DeleteUserWorker.perform_in(DELETION_DELAY_IN_DAYS, deleted_by.id, id, params.to_h) else @@ -2256,6 +2256,10 @@ class User < ApplicationRecord namespace_commit_emails.find_by(namespace: project.root_namespace) end + def spammer? + spam_score > Abuse::TrustScore::SPAMCHECK_HAM_THRESHOLD + end + def spam_score abuse_trust_scores.spamcheck.average(:score) || 0.0 end @@ -2313,6 +2317,30 @@ class User < ApplicationRecord private + def block_or_ban + if spammer? && account_age_in_days < 7 + ban_and_report + else + block + end + end + + def ban_and_report + msg = 'Potential spammer account deletion' + attrs = { user_id: id, reporter: User.security_bot, category: 'spam' } + abuse_report = AbuseReport.find_by(attrs) + + if abuse_report.nil? + abuse_report = AbuseReport.create!(attrs.merge(message: msg)) + else + abuse_report.update(message: "#{abuse_report.message}\n\n#{msg}") + end + + UserCustomAttribute.set_banned_by_abuse_report(abuse_report) + + ban + end + def pbkdf2? return false unless otp_backup_codes&.any? diff --git a/app/models/user_custom_attribute.rb b/app/models/user_custom_attribute.rb index 9a186cb9038..63a5ee9770f 100644 --- a/app/models/user_custom_attribute.rb +++ b/app/models/user_custom_attribute.rb @@ -35,6 +35,14 @@ class UserCustomAttribute < ApplicationRecord .select(:value) end + def set_banned_by_abuse_report(abuse_report) + return unless abuse_report + + custom_attribute = { user_id: abuse_report.user.id, key: AUTO_BANNED_BY_ABUSE_REPORT_ID, value: abuse_report.id } + + upsert_custom_attributes([custom_attribute]) + end + private def blocked_users diff --git a/app/views/shared/notes/_notes_with_form.html.haml b/app/views/shared/notes/_notes_with_form.html.haml index eb36de8167c..0fed59aaff3 100644 --- a/app/views/shared/notes/_notes_with_form.html.haml +++ b/app/views/shared/notes/_notes_with_form.html.haml @@ -1,7 +1,7 @@ - issuable = @issue || @merge_request - discussion_locked = issuable&.discussion_locked? -%ul#notes-list.notes.main-notes-list.timeline +%ul#notes-list.notes.main-notes-list.timeline{ data: { 'qa_selector': 'notes_list' } } = render "shared/notes/notes" = render 'shared/notes/edit_form', project: @project diff --git a/doc/administration/geo/setup/index.md b/doc/administration/geo/setup/index.md index da7e55509e7..6674ea7bd0d 100644 --- a/doc/administration/geo/setup/index.md +++ b/doc/administration/geo/setup/index.md @@ -21,7 +21,12 @@ type: howto ## Using Omnibus GitLab -If you installed GitLab using the Omnibus packages (highly recommended): +If you installed GitLab using the Omnibus packages (highly recommended), the process for setting up Geo depends on whether you need to set up +a single-node Geo site or a multi-node Geo site. + +### Single-node Geo sites + +If both Geo sites are based on the [1K reference architecture](../../reference_architectures/1k_users.md): 1. [Set up the database replication](database.md) (`primary (read-write) <-> secondary (read-only)` topology). 1. [Configure GitLab](../replication/configuration.md) to set the **primary** and **secondary** sites. @@ -29,6 +34,11 @@ If you installed GitLab using the Omnibus packages (highly recommended): 1. Optional: [Configure a secondary LDAP server](../../auth/ldap/index.md) for the **secondary** sites. See [notes on LDAP](../index.md#ldap). 1. Optional: [Configure Geo secondary proxying](../secondary_proxy/index.md) to use a single, unified URL for all Geo sites. This step is recommended to accelerate most read requests while transparently proxying writes to the primary Geo site. 1. Follow the [Using a Geo Site](../replication/usage.md) guide. + +### Multi-node Geo sites + +If one or more of your sites is using the [2K reference architecture](../../reference_architectures/2k_users.md) or larger, see +[Configure Geo for multiple nodes](../replication/multiple_servers.md). ## Using GitLab Charts diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 03d60628305..f3bd7c3eef6 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -39754,7 +39754,7 @@ msgstr "" msgid "ScanExecutionPolicy|Run a %{scan} scan on runner that %{tags}" msgstr "" -msgid "ScanExecutionPolicy|Run a %{scan} scan with %{dastProfiles} with tags %{tags}" +msgid "ScanExecutionPolicy|Run a %{scan} scan with %{dastProfiles} on runner that %{tags}" msgstr "" msgid "ScanExecutionPolicy|Scanner profile" diff --git a/qa/qa/page/component/snippet.rb b/qa/qa/page/component/snippet.rb index 05d59acd8e8..336dff80cdd 100644 --- a/qa/qa/page/component/snippet.rb +++ b/qa/qa/page/component/snippet.rb @@ -70,6 +70,10 @@ module QA element :note_author_content end + base.view 'app/views/shared/notes/_notes_with_form.html.haml' do + element :notes_list + end + base.view 'app/views/projects/notes/_more_actions_dropdown.html.haml' do element :more_actions_dropdown element :delete_comment_button @@ -216,6 +220,10 @@ module QA end end + def within_notes_list(&block) + within_element :notes_list, &block + end + def has_syntax_highlighting?(language) within_element(:blob_viewer_file_content) do find('.line')['lang'].to_s == language diff --git a/qa/qa/page/group/menu.rb b/qa/qa/page/group/menu.rb index 2850382b672..3444a21202a 100644 --- a/qa/qa/page/group/menu.rb +++ b/qa/qa/page/group/menu.rb @@ -16,6 +16,8 @@ module QA end def click_group_members_item + return go_to_members if Runtime::Env.super_sidebar_enabled? + hover_group_information do within_submenu do click_element(:sidebar_menu_item_link, menu_item: 'Members') diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb index c971ab869cd..c88bd808299 100644 --- a/qa/qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb @@ -66,15 +66,19 @@ module QA end def verify_comment_content(author, comment_content) - Page::Dashboard::Snippet::Show.perform do |comment| - expect(comment).to have_comment_author(author) - expect(comment).to have_comment_content(comment_content) + Page::Dashboard::Snippet::Show.perform do |snippet| + expect(snippet).to have_comment_author(author) + expect(snippet).to have_comment_content(comment_content) end end def verify_comment_deleted - expect(page).not_to have_content(comment_author.username) - expect(page).not_to have_content(edited_comment_content) + Page::Dashboard::Snippet::Show.perform do |snippet| + snippet.within_notes_list do + expect(snippet).not_to have_content(comment_author.username) + expect(snippet).not_to have_content(edited_comment_content) + end + end end end end diff --git a/spec/models/user_custom_attribute_spec.rb b/spec/models/user_custom_attribute_spec.rb index 67c144d7caa..934956926f0 100644 --- a/spec/models/user_custom_attribute_spec.rb +++ b/spec/models/user_custom_attribute_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe UserCustomAttribute do +RSpec.describe UserCustomAttribute, feature_category: :user_profile do describe 'assocations' do it { is_expected.to belong_to(:user) } end @@ -40,6 +40,31 @@ RSpec.describe UserCustomAttribute do end end + describe '.set_banned_by_abuse_report' do + let_it_be(:user) { create(:user) } + let(:abuse_report) { create(:abuse_report, user: user) } + + subject { UserCustomAttribute.set_banned_by_abuse_report(abuse_report) } + + it 'adds the abuse report ID to user custom attributes' do + subject + + custom_attribute = user.custom_attributes.by_key(UserCustomAttribute::AUTO_BANNED_BY_ABUSE_REPORT_ID).first + expect(custom_attribute.value).to eq(abuse_report.id.to_s) + end + + context 'when abuse report is nil' do + let(:abuse_report) { nil } + + it 'does not update custom attributes' do + subject + + custom_attribute = user.custom_attributes.by_key(UserCustomAttribute::AUTO_BANNED_BY_ABUSE_REPORT_ID).first + expect(custom_attribute).to be_nil + end + end + end + describe '#upsert_custom_attributes' do subject { UserCustomAttribute.upsert_custom_attributes(custom_attributes) } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index f5b274301ca..a2d87d32d44 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -2848,6 +2848,56 @@ RSpec.describe User, feature_category: :user_profile do end end + describe '#spammer?' do + let_it_be(:user) { create(:user) } + + context 'when the user is a spammer' do + before do + allow(user).to receive(:spam_score).and_return(0.9) + end + + it 'classifies the user as a spammer' do + expect(user).to be_spammer + end + end + + context 'when the user is not a spammer' do + before do + allow(user).to receive(:spam_score).and_return(0.1) + end + + it 'does not classify the user as a spammer' do + expect(user).not_to be_spammer + end + end + end + + describe '#spam_score' do + let_it_be(:user) { create(:user) } + + context 'when the user is a spammer' do + before do + create(:abuse_trust_score, user: user, score: 0.8) + create(:abuse_trust_score, user: user, score: 0.9) + end + + it 'returns the expected score' do + expect(user.spam_score).to be_within(0.01).of(0.85) + end + end + + context 'when the user is not a spammer' do + before do + create(:abuse_trust_score, user: user, score: 0.1) + create(:abuse_trust_score, user: user, score: 0.0) + end + + it 'returns the expected score' do + expect(user.spam_score).to be_within(0.01).of(0.05) + end + end + end + describe '.find_for_database_authentication' do it 'strips whitespace from login' do user = create(:user) @@ -5868,13 +5918,90 @@ RSpec.describe User, feature_category: :user_profile do context 'when target user is the same as deleted_by' do let(:deleted_by) { user } - it 'blocks the user and schedules the record for deletion with the correct delay' do - freeze_time do - expect(DeleteUserWorker).to receive(:perform_in).with(7.days, user.id, user.id, {}) + subject { user.delete_async(deleted_by: deleted_by) } - user.delete_async(deleted_by: deleted_by) + shared_examples 'schedules the record for deletion with the correct delay' do + it 'schedules the record for deletion with the correct delay' do + freeze_time do + expect(DeleteUserWorker).to receive(:perform_in).with(7.days, user.id, user.id, {}) - expect(user).to be_blocked + subject + end + end + end + + it_behaves_like 'schedules the record for deletion with the correct delay' + + it 'blocks the user' do + subject + + expect(user).to be_blocked + expect(user).not_to be_banned + end + + context 'when the user is a spammer' do + before do + allow(user).to receive(:spammer?).and_return(true) + end + + context 'when the user acount is less than 7 days old' do + it_behaves_like 'schedules the record for deletion with the correct delay' + + it 'creates an abuse report with the correct data' do + expect { subject }.to change { AbuseReport.count }.from(0).to(1) + expect(AbuseReport.last.attributes).to include({ + reporter_id: User.security_bot.id, + user_id: user.id, + category: "spam", + message: 'Potential spammer account deletion' + }.stringify_keys) + end + + it 'adds custom attribute to the user with the correct values' do + subject + + custom_attribute = user.custom_attributes.by_key(UserCustomAttribute::AUTO_BANNED_BY_ABUSE_REPORT_ID).first + expect(custom_attribute.value).to eq(AbuseReport.last.id.to_s) + end + + it 'bans the user' do + subject + + expect(user).to be_banned + end + + context 'when there is an existing abuse report' do + let!(:abuse_report) { create(:abuse_report, user: user, reporter: User.security_bot, message: 'Existing') } + + it 'updates the abuse report' do + subject + abuse_report.reload + + expect(abuse_report.message).to eq("Existing\n\nPotential spammer account deletion") + end + + it 'adds custom attribute to the user with the correct values' do + subject + + custom_attribute = user.custom_attributes.by_key(UserCustomAttribute::AUTO_BANNED_BY_ABUSE_REPORT_ID).first + expect(custom_attribute.value).to eq(abuse_report.id.to_s) + end + end + end + + context 'when the user acount is greater than 7 days old' do + before do + allow(user).to receive(:account_age_in_days).and_return(8) + end + + it_behaves_like 'schedules the record for deletion with the correct delay' + + it 'blocks the user' do + subject + + expect(user).to be_blocked + expect(user).not_to be_banned + end end end @@ -5894,7 +6021,7 @@ RSpec.describe User, feature_category: :user_profile do it 'schedules user for deletion without blocking them' do expect(DeleteUserWorker).to receive(:perform_async).with(user.id, user.id, {}) - user.delete_async(deleted_by: deleted_by) + subject expect(user).not_to be_blocked end |