diff options
author | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2018-10-05 10:29:38 +0200 |
---|---|---|
committer | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2018-10-05 10:29:38 +0200 |
commit | 33cf61716446c9fd1295f8a80bfeb2e600bd8f7d (patch) | |
tree | eb822c06ec5cc3ec0e5adef6a270fdd72fc54b1d | |
parent | a545703e739fea0b7d79cc8f0d59e0a64c0eb15b (diff) | |
parent | 1e9003f4a42fa75b25045701fec5e9aa32cae71a (diff) | |
download | gitlab-ce-33cf61716446c9fd1295f8a80bfeb2e600bd8f7d.tar.gz |
Merge branch 'master' into feature/gb/pipeline-only-except-with-modified-paths
* master:
Require spec helpers loaded by other spec helpers first
Resolve "2FA mobile options should be rephrased"
Add css class to Admin > Project > show page
Trim whitespace when inviting a new user by email
Bump Gitaly to v0.124.0
Banzai project ref- share context more aggresively
Add reliable fetcher for Sidekiq
Allows to filter issues by `Any milestone` in the API
28 files changed, 117 insertions, 30 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 3ba7bd5ba83..ee476f3ae84 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -0.123.0 +0.124.0 @@ -295,6 +295,7 @@ gem 'peek-mysql2', '~> 1.1.0', group: :mysql gem 'peek-pg', '~> 1.3.0', group: :postgres gem 'peek-rblineprof', '~> 0.2.0' gem 'peek-redis', '~> 1.2.0' +gem 'gitlab-sidekiq-fetcher', require: 'sidekiq-reliable-fetch' # Metrics group :metrics do diff --git a/Gemfile.lock b/Gemfile.lock index 301f4132476..9837a195d8c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -301,6 +301,8 @@ GEM mime-types (>= 1.16) posix-spawn (~> 0.3) gitlab-markup (1.6.4) + gitlab-sidekiq-fetcher (0.3.0) + sidekiq (~> 5) gitlab-styles (2.4.1) rubocop (~> 0.54.0) rubocop-gitlab-security (~> 0.1.0) @@ -1031,6 +1033,7 @@ DEPENDENCIES gitlab-flowdock-git-hook (~> 1.0.1) gitlab-gollum-lib (~> 4.2) gitlab-markup (~> 1.6.4) + gitlab-sidekiq-fetcher gitlab-styles (~> 2.4) gitlab_omniauth-ldap (~> 2.0.4) gon (~> 6.2) diff --git a/Gemfile.rails5.lock b/Gemfile.rails5.lock index 1e129bc2b54..9eab07d9659 100644 --- a/Gemfile.rails5.lock +++ b/Gemfile.rails5.lock @@ -304,6 +304,8 @@ GEM mime-types (>= 1.16) posix-spawn (~> 0.3) gitlab-markup (1.6.4) + gitlab-sidekiq-fetcher (0.3.0) + sidekiq (~> 5) gitlab-styles (2.4.1) rubocop (~> 0.54.0) rubocop-gitlab-security (~> 0.1.0) @@ -1040,6 +1042,7 @@ DEPENDENCIES gitlab-flowdock-git-hook (~> 1.0.1) gitlab-gollum-lib (~> 4.2) gitlab-markup (~> 1.6.4) + gitlab-sidekiq-fetcher gitlab-styles (~> 2.4) gitlab_omniauth-ldap (~> 2.0.4) gon (~> 6.2) diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js index e19bbbacf4d..b9dfa22dd49 100644 --- a/app/assets/javascripts/users_select.js +++ b/app/assets/javascripts/users_select.js @@ -592,7 +592,7 @@ function UsersSelect(currentUser, els, options = {}) { if (showEmailUser && data.results.length === 0 && query.term.match(/^[^@]+@[^@]+$/)) { var trimmed = query.term.trim(); emailUser = { - name: "Invite \"" + query.term + "\" by email", + name: "Invite \"" + trimmed + "\" by email", username: trimmed, id: trimmed, invite: true diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index 9e24154e4b6..17e9b59b355 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -428,6 +428,10 @@ class IssuableFinder params[:milestone_title] == Milestone::Upcoming.name end + def filter_by_any_milestone? + params[:milestone_title] == Milestone::Any.title + end + def filter_by_started_milestone? params[:milestone_title] == Milestone::Started.name end @@ -437,6 +441,8 @@ class IssuableFinder if milestones? if filter_by_no_milestone? items = items.left_joins_milestones.where(milestone_id: [-1, nil]) + elsif filter_by_any_milestone? + items = items.any_milestone elsif filter_by_upcoming_milestone? upcoming_ids = Milestone.upcoming_ids_by_projects(projects(items)) items = items.left_joins_milestones.where(milestone_id: upcoming_ids) diff --git a/app/finders/labels_finder.rb b/app/finders/labels_finder.rb index 82e0b2ed9e1..d000af21be3 100644 --- a/app/finders/labels_finder.rb +++ b/app/finders/labels_finder.rb @@ -129,7 +129,7 @@ class LabelsFinder < UnionFinder end def project? - params[:project_id].present? + params[:project].present? || params[:project_id].present? end def projects? @@ -152,7 +152,7 @@ class LabelsFinder < UnionFinder return @project if defined?(@project) if project? - @project = Project.find(params[:project_id]) + @project = params[:project] || Project.find(params[:project_id]) @project = nil unless authorized_to_read_labels?(@project) else @project = nil diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 5f65fceb7af..2aa52bbaeea 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -76,6 +76,7 @@ module Issuable scope :recent, -> { reorder(id: :desc) } scope :of_projects, ->(ids) { where(project_id: ids) } scope :of_milestones, ->(ids) { where(milestone_id: ids) } + scope :any_milestone, -> { where('milestone_id IS NOT NULL') } scope :with_milestone, ->(title) { left_joins_milestones.where(milestones: { title: title }) } scope :opened, -> { with_state(:opened) } scope :only_opened, -> { with_state(:opened) } diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index ccba1c461fc..32f6eefc16a 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -1,6 +1,8 @@ - add_to_breadcrumbs "Projects", admin_projects_path - breadcrumb_title @project.full_name - page_title @project.full_name, "Projects" +- @content_class = "admin-projects" + %h3.page-title Project: #{@project.full_name} = link_to edit_project_path(@project), class: "btn btn-nr float-right" do diff --git a/app/views/profiles/two_factor_auths/_codes.html.haml b/app/views/profiles/two_factor_auths/_codes.html.haml index fb4fff12027..759d39cf5f5 100644 --- a/app/views/profiles/two_factor_auths/_codes.html.haml +++ b/app/views/profiles/two_factor_auths/_codes.html.haml @@ -1,5 +1,5 @@ %p.slead - Should you ever lose your phone, each of these recovery codes can be used one + Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %b will lose access to your account. diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml index cd10b8758f6..94ec0cc5db8 100644 --- a/app/views/profiles/two_factor_auths/show.html.haml +++ b/app/views/profiles/two_factor_auths/show.html.haml @@ -6,13 +6,13 @@ .row.prepend-top-default .col-lg-4 %h4.prepend-top-0 - Register Two-Factor Authentication App + Register Two-Factor Authenticator %p - Use an app on your mobile device to enable two-factor authentication (2FA). + Use an one time password authenticator on your mobile device or computer to enable two-factor authentication (2FA). .col-lg-8 - if current_user.two_factor_otp_enabled? %p - You've already enabled two-factor authentication using mobile authenticator applications. In order to register a different device, you must first disable two-factor authentication. + You've already enabled two-factor authentication using one time password authenticators. In order to register a different device, you must first disable two-factor authentication. %p If you lose your recovery codes you can generate new ones, invalidating all previous codes. %div diff --git a/changelogs/unreleased/40140-2FA-mobile-options-should-be-rephrased.yml b/changelogs/unreleased/40140-2FA-mobile-options-should-be-rephrased.yml new file mode 100644 index 00000000000..8131e2ff54f --- /dev/null +++ b/changelogs/unreleased/40140-2FA-mobile-options-should-be-rephrased.yml @@ -0,0 +1,5 @@ +--- +title: Rephrase 2FA and TOTP documentation and view +merge_request: 21998 +author: Marc Schwede +type: other diff --git a/changelogs/unreleased/51748-filter-any-milestone-via-api.yml b/changelogs/unreleased/51748-filter-any-milestone-via-api.yml new file mode 100644 index 00000000000..30304e5a4ac --- /dev/null +++ b/changelogs/unreleased/51748-filter-any-milestone-via-api.yml @@ -0,0 +1,5 @@ +--- +title: Allows to filter issues by Any milestone in the API +merge_request: 22080 +author: Jacopo Beschi @jacopo-beschi +type: added diff --git a/changelogs/unreleased/52194-trim-extra-whitespace-invite-member.yml b/changelogs/unreleased/52194-trim-extra-whitespace-invite-member.yml new file mode 100644 index 00000000000..d96c2bc7acd --- /dev/null +++ b/changelogs/unreleased/52194-trim-extra-whitespace-invite-member.yml @@ -0,0 +1,5 @@ +--- +title: Trim whitespace when inviting a new user by email +merge_request: 22119 +author: Jacopo Beschi @jacopo-beschi +type: fixed diff --git a/changelogs/unreleased/add_reliable_fetcher.yml b/changelogs/unreleased/add_reliable_fetcher.yml new file mode 100644 index 00000000000..c08c755e546 --- /dev/null +++ b/changelogs/unreleased/add_reliable_fetcher.yml @@ -0,0 +1,5 @@ +--- +title: Use Reliable Sidekiq fetch +merge_request: 21715 +author: +type: fixed diff --git a/changelogs/unreleased/mao-48221-issues_show_sql_count.yml b/changelogs/unreleased/mao-48221-issues_show_sql_count.yml new file mode 100644 index 00000000000..d634d15946e --- /dev/null +++ b/changelogs/unreleased/mao-48221-issues_show_sql_count.yml @@ -0,0 +1,5 @@ +--- +title: Banzai label ref finder - minimize SQL calls by sharing context more aggresively +merge_request: 22070 +author: +type: performance diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 6c1079faad1..bc6b7aed6aa 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -40,6 +40,10 @@ Sidekiq.configure_server do |config| ActiveRecord::Base.clear_all_connections! end + if Feature.enabled?(:gitlab_sidekiq_reliable_fetcher) + Sidekiq::ReliableFetcher.setup_reliable_fetch!(config) + end + # Sidekiq-cron: load recurring jobs from gitlab.yml # UGLY Hack to get nested hash from settingslogic cron_jobs = JSON.parse(Gitlab.config.cron_jobs.to_json) @@ -57,10 +61,10 @@ Sidekiq.configure_server do |config| Gitlab::SidekiqVersioning.install! - config = Gitlab::Database.config || + db_config = Gitlab::Database.config || Rails.application.config.database_configuration[Rails.env] - config['pool'] = Sidekiq.options[:concurrency] - ActiveRecord::Base.establish_connection(config) + db_config['pool'] = Sidekiq.options[:concurrency] + ActiveRecord::Base.establish_connection(db_config) Rails.logger.debug("Connection Pool size for Sidekiq Server is now: #{ActiveRecord::Base.connection.pool.instance_variable_get('@size')}") # Avoid autoload issue such as 'Mail::Parsers::AddressStruct' diff --git a/doc/api/issues.md b/doc/api/issues.md index f4c0f4ea65b..cc1d6834a20 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -37,7 +37,7 @@ GET /issues?my_reaction_emoji=star | ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | `state` | string | no | Return all issues or just those that are `opened` or `closed` | | `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels | -| `milestone` | string | no | The milestone title. `No+Milestone` lists all issues with no milestone | +| `milestone` | string | no | The milestone title. `No+Milestone` lists all issues with no milestone. `Any+Milestone` lists all issues that have an assigned milestone | | `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced][ce-13004] in GitLab 9.5. [Changed to snake_case][ce-18935] in GitLab 11.0)_ | | `author_id` | integer | no | Return issues created by the given user `id`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced][ce-13004] in GitLab 9.5)_ | | `assignee_id` | integer | no | Return issues assigned to the given user `id` _([Introduced][ce-13004] in GitLab 9.5)_ | diff --git a/doc/user/profile/account/two_factor_authentication.md b/doc/user/profile/account/two_factor_authentication.md index e5411662511..bc6ecdf4f32 100644 --- a/doc/user/profile/account/two_factor_authentication.md +++ b/doc/user/profile/account/two_factor_authentication.md @@ -2,18 +2,18 @@ Two-factor Authentication (2FA) provides an additional level of security to your GitLab account. Once enabled, in addition to supplying your username and -password to login, you'll be prompted for a code generated by an application on -your phone. +password to login, you'll be prompted for a code generated by your one time password +authenticator. For example, a password manager on one of your devices. By enabling 2FA, the only way someone other than you can log into your account -is to know your username and password *and* have access to your phone. +is to know your username and password *and* have access to your one time password secret. ## Overview > **Note:** When you enable 2FA, don't forget to back up your recovery codes. -In addition to a phone application, GitLab supports U2F (universal 2nd factor) devices as +In addition to one time authenticators (TOTP), GitLab supports U2F (universal 2nd factor) devices as the second factor of authentication. Once enabled, in addition to supplying your username and password to login, you'll be prompted to activate your U2F device (usually by pressing a button on it), and it will perform secure authentication on your behalf. @@ -24,10 +24,10 @@ from other browsers. ## Enabling 2FA -There are two ways to enable two-factor authentication: via a mobile application +There are two ways to enable two-factor authentication: via a one time password authenticator or a U2F device. -### Enable 2FA via mobile application +### Enable 2FA via one time password authenticator **In GitLab:** @@ -82,7 +82,7 @@ Click on **Register U2F Device** to complete the process. > **Note:** Recovery codes are not generated for U2F devices. -Should you ever lose access to your phone, you can use one of the ten provided +Should you ever lose access to your one time password authenticator, you can use one of the ten provided backup codes to login to your account. We suggest copying or printing them for storage in a safe place. **Each code can be used only once** to log in to your account. @@ -98,7 +98,7 @@ be presented with a second prompt, depending on which type of 2FA you've enabled ### Log in via mobile application -Enter the pin from your phone's application or a recovery code to log in. +Enter the pin from your one time password authenticator's application or a recovery code to log in. ![Two-Factor Authentication on sign in via OTP](img/2fa_auth.png) diff --git a/lib/banzai/cross_project_reference.rb b/lib/banzai/cross_project_reference.rb index 3f1e95d4cc0..43f913a8859 100644 --- a/lib/banzai/cross_project_reference.rb +++ b/lib/banzai/cross_project_reference.rb @@ -13,6 +13,7 @@ module Banzai # Returns a Project, or nil if the reference can't be found def parent_from_ref(ref) return context[:project] || context[:group] unless ref + return context[:project] if context[:project]&.full_path == ref Project.find_by_full_path(ref) end diff --git a/lib/banzai/filter/label_reference_filter.rb b/lib/banzai/filter/label_reference_filter.rb index b92e9e55bb9..04ec38209c7 100644 --- a/lib/banzai/filter/label_reference_filter.rb +++ b/lib/banzai/filter/label_reference_filter.rb @@ -48,7 +48,7 @@ module Banzai include_ancestor_groups: true, only_group_labels: true } else - { project_id: parent.id, + { project: parent, include_ancestor_groups: true } end diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 5b347b1109a..44419ed6a2a 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -637,6 +637,18 @@ describe Projects::IssuesController do project_id: project, id: id end + + it 'avoids (most) N+1s loading labels' do + label = create(:label, project: project).to_reference + labels = create_list(:label, 10, project: project).map(&:to_reference) + issue = create(:issue, project: project, description: 'Test issue') + + control_count = ActiveRecord::QueryRecorder.new { issue.update(description: [issue.description, label].join(' ')) }.count + + # Follow-up to get rid of this `2 * label.count` requirement: https://gitlab.com/gitlab-org/gitlab-ce/issues/52230 + expect { issue.update(description: [issue.description, labels].join(' ')) } + .not_to exceed_query_limit(control_count + 2 * labels.count) + end end describe 'GET #realtime_changes' do diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb index f1192f48b86..ae9b65d1a39 100644 --- a/spec/features/u2f_spec.rb +++ b/spec/features/u2f_spec.rb @@ -42,7 +42,7 @@ describe 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do it 'allows registering a new device with a name' do visit profile_account_path manage_two_factor_authentication - expect(page).to have_content("You've already enabled two-factor authentication using mobile") + expect(page).to have_content("You've already enabled two-factor authentication using one time password authenticators") u2f_device = register_u2f_device @@ -70,7 +70,7 @@ describe 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do it 'allows deleting a device' do visit profile_account_path manage_two_factor_authentication - expect(page).to have_content("You've already enabled two-factor authentication using mobile") + expect(page).to have_content("You've already enabled two-factor authentication using one time password authenticators") first_u2f_device = register_u2f_device second_u2f_device = register_u2f_device(name: 'My other device') diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb index d78451112ec..0689c843104 100644 --- a/spec/finders/issues_finder_spec.rb +++ b/spec/finders/issues_finder_spec.rb @@ -125,6 +125,14 @@ describe IssuesFinder do end end + context 'filtering by any milestone' do + let(:params) { { milestone_title: Milestone::Any.title } } + + it 'returns issues with any assigned milestone' do + expect(issues).to contain_exactly(issue1) + end + end + context 'filtering by upcoming milestone' do let(:params) { { milestone_title: Milestone::Upcoming.name } } diff --git a/spec/lib/banzai/cross_project_reference_spec.rb b/spec/lib/banzai/cross_project_reference_spec.rb index aadfe7637dd..ba995e16be7 100644 --- a/spec/lib/banzai/cross_project_reference_spec.rb +++ b/spec/lib/banzai/cross_project_reference_spec.rb @@ -1,16 +1,21 @@ require 'spec_helper' describe Banzai::CrossProjectReference do - include described_class + let(:including_class) { Class.new.include(described_class).new } + + before do + allow(including_class).to receive(:context).and_return({}) + allow(including_class).to receive(:parent_from_ref).and_call_original + end describe '#parent_from_ref' do context 'when no project was referenced' do it 'returns the project from context' do project = double - allow(self).to receive(:context).and_return({ project: project }) + allow(including_class).to receive(:context).and_return({ project: project }) - expect(parent_from_ref(nil)).to eq project + expect(including_class.parent_from_ref(nil)).to eq project end end @@ -18,15 +23,15 @@ describe Banzai::CrossProjectReference do it 'returns the group from context' do group = double - allow(self).to receive(:context).and_return({ group: group }) + allow(including_class).to receive(:context).and_return({ group: group }) - expect(parent_from_ref(nil)).to eq group + expect(including_class.parent_from_ref(nil)).to eq group end end context 'when referenced project does not exist' do it 'returns nil' do - expect(parent_from_ref('invalid/reference')).to be_nil + expect(including_class.parent_from_ref('invalid/reference')).to be_nil end end @@ -37,7 +42,7 @@ describe Banzai::CrossProjectReference do expect(Project).to receive(:find_by_full_path) .with('cross/reference').and_return(project2) - expect(parent_from_ref('cross/reference')).to eq project2 + expect(including_class.parent_from_ref('cross/reference')).to eq project2 end end end diff --git a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb index e1af5a15371..cbff2fdab14 100644 --- a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb @@ -60,6 +60,7 @@ describe Banzai::Filter::CommitRangeReferenceFilter do exp = act = "See #{commit1.id.reverse}...#{commit2.id}" allow(project.repository).to receive(:commit).with(commit1.id.reverse) + allow(project.repository).to receive(:commit).with(commit2.id) expect(reference_filter(act).to_html).to eq exp end diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index 1e2e13a723c..9f6cf12f9a7 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -56,6 +56,7 @@ describe API::Issues do let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) } let(:no_milestone_title) { URI.escape(Milestone::None.title) } + let(:any_milestone_title) { URI.escape(Milestone::Any.title) } before(:all) do project.add_reporter(user) @@ -811,6 +812,15 @@ describe API::Issues do expect(json_response.first['id']).to eq(confidential_issue.id) end + it 'returns an array of issues with any milestone' do + get api("#{base_url}/issues?milestone=#{any_milestone_title}", user) + + response_ids = json_response.map { |issue| issue['id'] } + + expect_paginated_array_response(size: 2) + expect(response_ids).to contain_exactly(closed_issue.id, issue.id) + end + it 'sorts by created_at descending by default' do get api("#{base_url}/issues", user) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d1337325973..cd69160be10 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -34,6 +34,11 @@ Rainbow.enabled = false # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. # Requires helpers, and shared contexts/examples first since they're used in other support files + +# Load these first since they may be required by other helpers +require Rails.root.join("spec/support/helpers/git_helpers.rb") + +# Then the rest Dir[Rails.root.join("spec/support/helpers/*.rb")].each { |f| require f } Dir[Rails.root.join("spec/support/shared_contexts/*.rb")].each { |f| require f } Dir[Rails.root.join("spec/support/shared_examples/*.rb")].each { |f| require f } |