From 59e5393827e9e9eddb9bb0a960f1cda1f6d9511d Mon Sep 17 00:00:00 2001 From: Hiroyuki Sato Date: Wed, 23 Aug 2017 19:54:14 +0900 Subject: [PATCH 01/35] Fuzzy search issuable title or description --- app/models/concerns/issuable.rb | 11 ++- lib/gitlab/sql/pattern.rb | 23 +++++ spec/lib/gitlab/sql/pattern_spec.rb | 120 ++++++++++++++++++++++++++ spec/models/concerns/issuable_spec.rb | 42 ++++++--- 4 files changed, 181 insertions(+), 15 deletions(-) diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 3731b7c8577..681c3241dbb 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -6,6 +6,7 @@ # module Issuable extend ActiveSupport::Concern + include Gitlab::SQL::Pattern include CacheMarkdownField include Participable include Mentionable @@ -122,7 +123,9 @@ module Issuable # # Returns an ActiveRecord::Relation. def search(query) - where(arel_table[:title].matches("%#{query}%")) + title = to_fuzzy_arel(:title, query) + + where(title) end # Searches for records with a matching title or description. @@ -133,10 +136,10 @@ module Issuable # # Returns an ActiveRecord::Relation. def full_search(query) - t = arel_table - pattern = "%#{query}%" + title = to_fuzzy_arel(:title, query) + description = to_fuzzy_arel(:description, query) - where(t[:title].matches(pattern).or(t[:description].matches(pattern))) + where(title&.or(description)) end def sort(method, excluded_labels: []) diff --git a/lib/gitlab/sql/pattern.rb b/lib/gitlab/sql/pattern.rb index b42bc67ccfc..7c2d1d8f887 100644 --- a/lib/gitlab/sql/pattern.rb +++ b/lib/gitlab/sql/pattern.rb @@ -4,6 +4,7 @@ module Gitlab extend ActiveSupport::Concern MIN_CHARS_FOR_PARTIAL_MATCHING = 3 + REGEX_QUOTED_WORD = /(?<=^| )"[^"]+"(?= |$)/ class_methods do def to_pattern(query) @@ -17,6 +18,28 @@ module Gitlab def partial_matching?(query) query.length >= MIN_CHARS_FOR_PARTIAL_MATCHING end + + def to_fuzzy_arel(column, query) + words = select_fuzzy_words(query) + + matches = words.map { |word| arel_table[column].matches(to_pattern(word)) } + + matches.reduce { |result, match| result.and(match) } + end + + def select_fuzzy_words(query) + quoted_words = query.scan(REGEX_QUOTED_WORD) + + query = quoted_words.reduce(query) { |q, quoted_word| q.sub(quoted_word, '') } + + words = query.split(/\s+/) + + quoted_words.map! { |quoted_word| quoted_word[1..-2] } + + words.concat(quoted_words) + + words.select { |word| partial_matching?(word) } + end end end end diff --git a/spec/lib/gitlab/sql/pattern_spec.rb b/spec/lib/gitlab/sql/pattern_spec.rb index 9d7b2136dab..0b0e905483f 100644 --- a/spec/lib/gitlab/sql/pattern_spec.rb +++ b/spec/lib/gitlab/sql/pattern_spec.rb @@ -52,4 +52,124 @@ describe Gitlab::SQL::Pattern do end end end + + describe '.select_fuzzy_words' do + subject(:select_fuzzy_words) { Issue.select_fuzzy_words(query) } + + context 'with a word equal to 3 chars' do + let(:query) { 'foo' } + + it 'returns array cotaining a word' do + expect(select_fuzzy_words).to match_array(['foo']) + end + end + + context 'with a word shorter than 3 chars' do + let(:query) { 'fo' } + + it 'returns empty array' do + expect(select_fuzzy_words).to match_array([]) + end + end + + context 'with two words both equal to 3 chars' do + let(:query) { 'foo baz' } + + it 'returns array containing two words' do + expect(select_fuzzy_words).to match_array(%w[foo baz]) + end + end + + context 'with two words divided by two speces both equal to 3 chars' do + let(:query) { 'foo baz' } + + it 'returns array containing two words' do + expect(select_fuzzy_words).to match_array(%w[foo baz]) + end + end + + context 'with two words equal to 3 chars and shorter than 3 chars' do + let(:query) { 'foo ba' } + + it 'returns array containing a word' do + expect(select_fuzzy_words).to match_array(['foo']) + end + end + + context 'with a multi-word surrounded by double quote' do + let(:query) { '"really bar"' } + + it 'returns array containing a multi-word' do + expect(select_fuzzy_words).to match_array(['really bar']) + end + end + + context 'with a multi-word surrounded by double quote and two words' do + let(:query) { 'foo "really bar" baz' } + + it 'returns array containing a multi-word and tow words' do + expect(select_fuzzy_words).to match_array(['foo', 'really bar', 'baz']) + end + end + + context 'with a multi-word surrounded by double quote missing a spece before the first double quote' do + let(:query) { 'foo"really bar"' } + + it 'returns array containing two words with double quote' do + expect(select_fuzzy_words).to match_array(['foo"really', 'bar"']) + end + end + + context 'with a multi-word surrounded by double quote missing a spece after the second double quote' do + let(:query) { '"really bar"baz' } + + it 'returns array containing two words with double quote' do + expect(select_fuzzy_words).to match_array(['"really', 'bar"baz']) + end + end + + context 'with two multi-word surrounded by double quote and two words' do + let(:query) { 'foo "really bar" baz "awesome feature"' } + + it 'returns array containing two multi-words and tow words' do + expect(select_fuzzy_words).to match_array(['foo', 'really bar', 'baz', 'awesome feature']) + end + end + end + + describe '.to_fuzzy_arel' do + subject(:to_fuzzy_arel) { Issue.to_fuzzy_arel(:title, query) } + + context 'with a word equal to 3 chars' do + let(:query) { 'foo' } + + it 'returns a single ILIKE condition' do + expect(to_fuzzy_arel.to_sql).to eq(%("issues"."title" ILIKE '%foo%')) + end + end + + context 'with a word shorter than 3 chars' do + let(:query) { 'fo' } + + it 'returns nil' do + expect(to_fuzzy_arel).to be_nil + end + end + + context 'with two words both equal to 3 chars' do + let(:query) { 'foo baz' } + + it 'returns a joining ILIKE condition using a AND' do + expect(to_fuzzy_arel.to_sql).to eq(%("issues"."title" ILIKE '%foo%' AND "issues"."title" ILIKE '%baz%')) + end + end + + context 'with a multi-word surrounded by double quote and two words' do + let(:query) { 'foo "really bar" baz' } + + it 'returns a joining ILIKE condition using a AND' do + expect(to_fuzzy_arel.to_sql).to eq(%("issues"."title" ILIKE '%foo%' AND "issues"."title" ILIKE '%baz%' AND "issues"."title" ILIKE '%really bar%')) + end + end + end end diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb index dfbe1a7c192..37f6fd3a25b 100644 --- a/spec/models/concerns/issuable_spec.rb +++ b/spec/models/concerns/issuable_spec.rb @@ -66,56 +66,76 @@ describe Issuable do end describe ".search" do - let!(:searchable_issue) { create(:issue, title: "Searchable issue") } + let!(:searchable_issue) { create(:issue, title: "Searchable awesome issue") } - it 'returns notes with a matching title' do + it 'returns issues with a matching title' do expect(issuable_class.search(searchable_issue.title)) .to eq([searchable_issue]) end - it 'returns notes with a partially matching title' do + it 'returns issues with a partially matching title' do expect(issuable_class.search('able')).to eq([searchable_issue]) end - it 'returns notes with a matching title regardless of the casing' do + it 'returns issues with a matching title regardless of the casing' do expect(issuable_class.search(searchable_issue.title.upcase)) .to eq([searchable_issue]) end + + it 'returns issues with a fuzzy matching title' do + expect(issuable_class.search('searchable issue')).to eq([searchable_issue]) + end + + it 'returns all issues with a query shorter than 3 chars' do + expect(issuable_class.search('zz')).to eq(issuable_class.all) + end end describe ".full_search" do let!(:searchable_issue) do - create(:issue, title: "Searchable issue", description: 'kittens') + create(:issue, title: "Searchable awesome issue", description: 'Many cute kittens') end - it 'returns notes with a matching title' do + it 'returns issues with a matching title' do expect(issuable_class.full_search(searchable_issue.title)) .to eq([searchable_issue]) end - it 'returns notes with a partially matching title' do + it 'returns issues with a partially matching title' do expect(issuable_class.full_search('able')).to eq([searchable_issue]) end - it 'returns notes with a matching title regardless of the casing' do + it 'returns issues with a matching title regardless of the casing' do expect(issuable_class.full_search(searchable_issue.title.upcase)) .to eq([searchable_issue]) end - it 'returns notes with a matching description' do + it 'returns issues with a fuzzy matching title' do + expect(issuable_class.full_search('searchable issue')).to eq([searchable_issue]) + end + + it 'returns issues with a matching description' do expect(issuable_class.full_search(searchable_issue.description)) .to eq([searchable_issue]) end - it 'returns notes with a partially matching description' do + it 'returns issues with a partially matching description' do expect(issuable_class.full_search(searchable_issue.description)) .to eq([searchable_issue]) end - it 'returns notes with a matching description regardless of the casing' do + it 'returns issues with a matching description regardless of the casing' do expect(issuable_class.full_search(searchable_issue.description.upcase)) .to eq([searchable_issue]) end + + it 'returns issues with a fuzzy matching description' do + expect(issuable_class.full_search('many kittens')).to eq([searchable_issue]) + end + + it 'returns all issues with a query shorter than 3 chars' do + expect(issuable_class.search('zz')).to eq(issuable_class.all) + end end describe '.to_ability_name' do From c12ab72f05386903d1af78d0e766ee970af09a44 Mon Sep 17 00:00:00 2001 From: Hiroyuki Sato Date: Wed, 30 Aug 2017 23:37:23 +0900 Subject: [PATCH 02/35] Fix broken feature specs --- spec/features/boards/add_issues_modal_spec.rb | 4 ++-- spec/features/boards/boards_spec.rb | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb index a6ad5981f8f..c480b5b7e34 100644 --- a/spec/features/boards/add_issues_modal_spec.rb +++ b/spec/features/boards/add_issues_modal_spec.rb @@ -8,8 +8,8 @@ describe 'Issue Boards add issue modal', :js do let!(:label) { create(:label, project: project) } let!(:list1) { create(:list, board: board, label: planning, position: 0) } let!(:list2) { create(:list, board: board, label: label, position: 1) } - let!(:issue) { create(:issue, project: project) } - let!(:issue2) { create(:issue, project: project) } + let!(:issue) { create(:issue, project: project, title: 'abc', description: 'def') } + let!(:issue2) { create(:issue, project: project, title: 'hij', description: 'klm') } before do project.team << [user, :master] diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index ce458431c55..c04b7ca89b3 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -71,15 +71,15 @@ describe 'Issue Boards', js: true do let!(:list2) { create(:list, board: board, label: development, position: 1) } let!(:confidential_issue) { create(:labeled_issue, :confidential, project: project, author: user, labels: [planning], relative_position: 9) } - let!(:issue1) { create(:labeled_issue, project: project, assignees: [user], labels: [planning], relative_position: 8) } - let!(:issue2) { create(:labeled_issue, project: project, author: user2, labels: [planning], relative_position: 7) } - let!(:issue3) { create(:labeled_issue, project: project, labels: [planning], relative_position: 6) } - let!(:issue4) { create(:labeled_issue, project: project, labels: [planning], relative_position: 5) } - let!(:issue5) { create(:labeled_issue, project: project, labels: [planning], milestone: milestone, relative_position: 4) } - let!(:issue6) { create(:labeled_issue, project: project, labels: [planning, development], relative_position: 3) } - let!(:issue7) { create(:labeled_issue, project: project, labels: [development], relative_position: 2) } - let!(:issue8) { create(:closed_issue, project: project) } - let!(:issue9) { create(:labeled_issue, project: project, labels: [planning, testing, bug, accepting], relative_position: 1) } + let!(:issue1) { create(:labeled_issue, project: project, title: 'aaa', description: '111', assignees: [user], labels: [planning], relative_position: 8) } + let!(:issue2) { create(:labeled_issue, project: project, title: 'bbb', description: '222', author: user2, labels: [planning], relative_position: 7) } + let!(:issue3) { create(:labeled_issue, project: project, title: 'ccc', description: '333', labels: [planning], relative_position: 6) } + let!(:issue4) { create(:labeled_issue, project: project, title: 'ddd', description: '444', labels: [planning], relative_position: 5) } + let!(:issue5) { create(:labeled_issue, project: project, title: 'eee', description: '555', labels: [planning], milestone: milestone, relative_position: 4) } + let!(:issue6) { create(:labeled_issue, project: project, title: 'fff', description: '666', labels: [planning, development], relative_position: 3) } + let!(:issue7) { create(:labeled_issue, project: project, title: 'ggg', description: '777', labels: [development], relative_position: 2) } + let!(:issue8) { create(:closed_issue, project: project, title: 'hhh', description: '888') } + let!(:issue9) { create(:labeled_issue, project: project, title: 'iii', description: '999', labels: [planning, testing, bug, accepting], relative_position: 1) } before do visit project_board_path(project, board) From 6edeff3d9cd78d4d89900122e0d66a7c5e53f43f Mon Sep 17 00:00:00 2001 From: Hiroyuki Sato Date: Thu, 31 Aug 2017 07:49:19 +0900 Subject: [PATCH 03/35] Fix MySQL spec errors --- spec/lib/gitlab/sql/pattern_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/lib/gitlab/sql/pattern_spec.rb b/spec/lib/gitlab/sql/pattern_spec.rb index 0b0e905483f..a780776d48e 100644 --- a/spec/lib/gitlab/sql/pattern_spec.rb +++ b/spec/lib/gitlab/sql/pattern_spec.rb @@ -144,7 +144,7 @@ describe Gitlab::SQL::Pattern do let(:query) { 'foo' } it 'returns a single ILIKE condition' do - expect(to_fuzzy_arel.to_sql).to eq(%("issues"."title" ILIKE '%foo%')) + expect(to_fuzzy_arel.to_sql).to match(/title.*I?LIKE '\%foo\%'/) end end @@ -159,16 +159,16 @@ describe Gitlab::SQL::Pattern do context 'with two words both equal to 3 chars' do let(:query) { 'foo baz' } - it 'returns a joining ILIKE condition using a AND' do - expect(to_fuzzy_arel.to_sql).to eq(%("issues"."title" ILIKE '%foo%' AND "issues"."title" ILIKE '%baz%')) + it 'returns a joining LIKE condition using a AND' do + expect(to_fuzzy_arel.to_sql).to match(/title.+I?LIKE '\%foo\%' AND .*title.*I?LIKE '\%baz\%'/) end end context 'with a multi-word surrounded by double quote and two words' do let(:query) { 'foo "really bar" baz' } - it 'returns a joining ILIKE condition using a AND' do - expect(to_fuzzy_arel.to_sql).to eq(%("issues"."title" ILIKE '%foo%' AND "issues"."title" ILIKE '%baz%' AND "issues"."title" ILIKE '%really bar%')) + it 'returns a joining LIKE condition using a AND' do + expect(to_fuzzy_arel.to_sql).to match(/title.+I?LIKE '\%foo\%' AND .*title.*I?LIKE '\%baz\%' AND .*title.*I?LIKE '\%really bar\%'/) end end end From 372075110c61ef64de9dd758270ddb45c594f429 Mon Sep 17 00:00:00 2001 From: Hiroyuki Sato Date: Thu, 31 Aug 2017 07:58:01 +0900 Subject: [PATCH 04/35] Add changelog entry --- changelogs/unreleased/fuzzy-issue-search.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelogs/unreleased/fuzzy-issue-search.yml diff --git a/changelogs/unreleased/fuzzy-issue-search.yml b/changelogs/unreleased/fuzzy-issue-search.yml new file mode 100644 index 00000000000..8195e97ed59 --- /dev/null +++ b/changelogs/unreleased/fuzzy-issue-search.yml @@ -0,0 +1,5 @@ +--- +title: Support a multi-word fuzzy seach issues/merge requests on search bar +merge_request: 13780 +author: Hiroyuki Sato +type: changed From 88472420bfd9c1500b7affb365f31964703b1908 Mon Sep 17 00:00:00 2001 From: Chris Peressini Date: Tue, 29 Aug 2017 12:28:23 +0000 Subject: [PATCH 05/35] Change hint format for main filtered search dropdown Change hint format from `type` to `type:value` so it matches the required syntax to perform filtering Fixes #29786 --- app/assets/javascripts/filtered_search/dropdown_hint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/filtered_search/dropdown_hint.js b/app/assets/javascripts/filtered_search/dropdown_hint.js index 1c5ca1d3cf9..23040cd9eb8 100644 --- a/app/assets/javascripts/filtered_search/dropdown_hint.js +++ b/app/assets/javascripts/filtered_search/dropdown_hint.js @@ -61,7 +61,7 @@ class DropdownHint extends gl.FilteredSearchDropdown { .map(tokenKey => ({ icon: `fa-${tokenKey.icon}`, hint: tokenKey.key, - tag: `<${tokenKey.tag}>`, + tag: `:${tokenKey.tag}`, type: tokenKey.type, })); From 9994f599abac0da450ab5c05a580973faaca9675 Mon Sep 17 00:00:00 2001 From: Hiroyuki Sato Date: Sun, 3 Sep 2017 12:58:56 +0900 Subject: [PATCH 06/35] Add `Searching for specific terms` section [ci skip] --- doc/user/search/index.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/user/search/index.md b/doc/user/search/index.md index f5c7ce49e8e..609d66d1dcb 100644 --- a/doc/user/search/index.md +++ b/doc/user/search/index.md @@ -40,6 +40,18 @@ The same process is valid for merge requests. Navigate to your project's **Merge and click **Search or filter results...**. Merge requests can be filtered by author, assignee, milestone, and label. +### Searching for specific terms + +You can filter issues by specific terms included in titles or descriptions. + +* Syntax + * Searches look for all the words in a query, in any order - e.g.: searching + issues for `display bug` will return all issues matching both those words, in any order. + * To find the exact term, use double quotes: `"display bug"` +* Limitation + * For a performance reason, the terms shorter than 3 chars are ignored - e.g.: searching + issues for `included in titles` is same with `included titles` + ### Issues and merge requests per group Similar to **Issues and merge requests per project**, you can also search for issues From 706d49b2590cfd70306f14cffdbadd237620a993 Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Mon, 4 Sep 2017 03:58:54 +0200 Subject: [PATCH 07/35] Added dynamic skip reason to SystemCheck --- lib/system_check/base_check.rb | 19 +++++++++++++++ lib/system_check/simple_executor.rb | 4 ++-- spec/lib/system_check/simple_executor_spec.rb | 24 ++++++++++++++++++- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/lib/system_check/base_check.rb b/lib/system_check/base_check.rb index 7f9e2ffffc2..0f5742dd67f 100644 --- a/lib/system_check/base_check.rb +++ b/lib/system_check/base_check.rb @@ -62,6 +62,25 @@ module SystemCheck call_or_return(@skip_reason) || 'skipped' end + # Define a reason why we skipped the SystemCheck (during runtime) + # + # This is used when you need dynamic evaluation like when you have + # multiple reasons why a check can fail + # + # @param [String] reason to be displayed + def skip_reason=(reason) + @skip_reason = reason + end + + # Skip reason defined during runtime + # + # This value have precedence over the one defined in the subclass + # + # @return [String] the reason + def skip_reason + @skip_reason + end + # Does the check support automatically repair routine? # # @return [Boolean] whether check implemented `#repair!` method or not diff --git a/lib/system_check/simple_executor.rb b/lib/system_check/simple_executor.rb index 6604b1078cf..00221f77cf4 100644 --- a/lib/system_check/simple_executor.rb +++ b/lib/system_check/simple_executor.rb @@ -23,7 +23,7 @@ module SystemCheck # # @param [BaseCheck] check class def <<(check) - raise ArgumentError unless check < BaseCheck + raise ArgumentError unless check.is_a?(Class) && check < BaseCheck @checks << check end @@ -48,7 +48,7 @@ module SystemCheck # When implements skip method, we run it first, and if true, skip the check if check.can_skip? && check.skip? - $stdout.puts check_klass.skip_reason.color(:magenta) + $stdout.puts check.skip_reason.try(:color, :magenta) || check_klass.skip_reason.color(:magenta) return end diff --git a/spec/lib/system_check/simple_executor_spec.rb b/spec/lib/system_check/simple_executor_spec.rb index 4de5da984ba..9da3648400e 100644 --- a/spec/lib/system_check/simple_executor_spec.rb +++ b/spec/lib/system_check/simple_executor_spec.rb @@ -35,6 +35,20 @@ describe SystemCheck::SimpleExecutor do end end + class DynamicSkipCheck < SystemCheck::BaseCheck + set_name 'dynamic skip check' + set_skip_reason 'this is a skip reason' + + def skip? + self.skip_reason = 'this is a dynamic skip reason' + true + end + + def check? + raise 'should not execute this' + end + end + class MultiCheck < SystemCheck::BaseCheck set_name 'multi check' @@ -127,6 +141,10 @@ describe SystemCheck::SimpleExecutor do expect(subject.checks.size).to eq(1) end + + it 'errors out when passing multiple items' do + expect { subject << [SimpleCheck, OtherCheck] }.to raise_error(ArgumentError) + end end subject { described_class.new('Test') } @@ -205,10 +223,14 @@ describe SystemCheck::SimpleExecutor do subject.run_check(SkipCheck) end - it 'displays #skip_reason' do + it 'displays .skip_reason' do expect { subject.run_check(SkipCheck) }.to output(/this is a skip reason/).to_stdout end + it 'displays #skip_reason' do + expect { subject.run_check(DynamicSkipCheck) }.to output(/this is a dynamic skip reason/).to_stdout + end + it 'does not execute #check when #skip? is true' do expect_any_instance_of(SkipCheck).not_to receive(:check?) From eb79e5689e15cde3e1f6902feb62953fd49df6ee Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Mon, 4 Sep 2017 03:59:37 +0200 Subject: [PATCH 08/35] Refactored app/init script check to use dynamic skip reason --- .../app/init_script_up_to_date_check.rb | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/system_check/app/init_script_up_to_date_check.rb b/lib/system_check/app/init_script_up_to_date_check.rb index 015c7ed1731..53a47eb0f42 100644 --- a/lib/system_check/app/init_script_up_to_date_check.rb +++ b/lib/system_check/app/init_script_up_to_date_check.rb @@ -7,26 +7,22 @@ module SystemCheck set_skip_reason 'skipped (omnibus-gitlab has no init script)' def skip? - omnibus_gitlab? + return true if omnibus_gitlab? + + unless init_file_exists? + self.skip_reason = "can't check because of previous errors" + + true + end end - def multi_check + def check? recipe_path = Rails.root.join('lib/support/init.d/', 'gitlab') - unless File.exist?(SCRIPT_PATH) - $stdout.puts "can't check because of previous errors".color(:magenta) - return - end - recipe_content = File.read(recipe_path) script_content = File.read(SCRIPT_PATH) - if recipe_content == script_content - $stdout.puts 'yes'.color(:green) - else - $stdout.puts 'no'.color(:red) - show_error - end + recipe_content == script_content end def show_error @@ -38,6 +34,12 @@ module SystemCheck ) fix_and_rerun end + + private + + def init_file_exists? + File.exist?(SCRIPT_PATH) + end end end end From 71000b394bb7ddf46d3037d62607d159706530f7 Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Mon, 4 Sep 2017 04:25:58 +0200 Subject: [PATCH 09/35] Refactored Incoming Email checks to use SystemCheck library --- .../foreman_configured_check.rb | 23 ++++ .../imap_authentication_check.rb | 45 +++++++ .../incoming_email/initd_configured_check.rb | 32 +++++ .../incoming_email/mail_room_running_check.rb | 43 ++++++ lib/tasks/gitlab/check.rake | 125 ++---------------- 5 files changed, 151 insertions(+), 117 deletions(-) create mode 100644 lib/system_check/incoming_email/foreman_configured_check.rb create mode 100644 lib/system_check/incoming_email/imap_authentication_check.rb create mode 100644 lib/system_check/incoming_email/initd_configured_check.rb create mode 100644 lib/system_check/incoming_email/mail_room_running_check.rb diff --git a/lib/system_check/incoming_email/foreman_configured_check.rb b/lib/system_check/incoming_email/foreman_configured_check.rb new file mode 100644 index 00000000000..1db7bf2b782 --- /dev/null +++ b/lib/system_check/incoming_email/foreman_configured_check.rb @@ -0,0 +1,23 @@ +module SystemCheck + module IncomingEmail + class ForemanConfiguredCheck < SystemCheck::BaseCheck + set_name 'Foreman configured correctly?' + + def check? + path = Rails.root.join('Procfile') + + File.exist?(path) && File.read(path) =~ /^mail_room:/ + end + + def show_error + try_fixing_it( + 'Enable mail_room in your Procfile.' + ) + for_more_information( + 'doc/administration/reply_by_email.md' + ) + fix_and_rerun + end + end + end +end diff --git a/lib/system_check/incoming_email/imap_authentication_check.rb b/lib/system_check/incoming_email/imap_authentication_check.rb new file mode 100644 index 00000000000..dee108d987b --- /dev/null +++ b/lib/system_check/incoming_email/imap_authentication_check.rb @@ -0,0 +1,45 @@ +module SystemCheck + module IncomingEmail + class ImapAuthenticationCheck < SystemCheck::BaseCheck + set_name 'IMAP server credentials are correct?' + + def check? + if mailbox_config + begin + imap = Net::IMAP.new(config[:host], port: config[:port], ssl: config[:ssl]) + imap.starttls if config[:start_tls] + imap.login(config[:email], config[:password]) + connected = true + rescue + connected = false + end + end + + connected + end + + def show_error + try_fixing_it( + 'Check that the information in config/gitlab.yml is correct' + ) + for_more_information( + 'doc/administration/reply_by_email.md' + ) + fix_and_rerun + end + + private + + def mailbox_config + return @config if @config + + config_path = Rails.root.join('config', 'mail_room.yml').to_s + erb = ERB.new(File.read(config_path)) + erb.filename = config_path + config_file = YAML.load(erb.result) + + @config = config_file[:mailboxes]&.first + end + end + end +end diff --git a/lib/system_check/incoming_email/initd_configured_check.rb b/lib/system_check/incoming_email/initd_configured_check.rb new file mode 100644 index 00000000000..ea23b8ef49c --- /dev/null +++ b/lib/system_check/incoming_email/initd_configured_check.rb @@ -0,0 +1,32 @@ +module SystemCheck + module IncomingEmail + class InitdConfiguredCheck < SystemCheck::BaseCheck + set_name 'Init.d configured correctly?' + + def skip? + omnibus_gitlab? + end + + def check? + mail_room_configured? + end + + def show_error + try_fixing_it( + 'Enable mail_room in the init.d configuration.' + ) + for_more_information( + 'doc/administration/reply_by_email.md' + ) + fix_and_rerun + end + + private + + def mail_room_configured? + path = '/etc/default/gitlab' + File.exist?(path) && File.read(path).include?('mail_room_enabled=true') + end + end + end +end diff --git a/lib/system_check/incoming_email/mail_room_running_check.rb b/lib/system_check/incoming_email/mail_room_running_check.rb new file mode 100644 index 00000000000..c1807501829 --- /dev/null +++ b/lib/system_check/incoming_email/mail_room_running_check.rb @@ -0,0 +1,43 @@ +module SystemCheck + module IncomingEmail + class MailRoomRunningCheck < SystemCheck::BaseCheck + set_name 'MailRoom running?' + + def skip? + return true if omnibus_gitlab? + + unless mail_room_configured? + self.skip_reason = "can't check because of previous errors" + true + end + end + + def check? + mail_room_running? + end + + def show_error + try_fixing_it( + sudo_gitlab('RAILS_ENV=production bin/mail_room start') + ) + for_more_information( + see_installation_guide_section('Install Init Script'), + 'see log/mail_room.log for possible errors' + ) + fix_and_rerun + end + + private + + def mail_room_configured? + path = '/etc/default/gitlab' + File.exist?(path) && File.read(path).include?('mail_room_enabled=true') + end + + def mail_room_running? + ps_ux, _ = Gitlab::Popen.popen(%w(ps uxww)) + ps_ux.include?("mail_room") + end + end + end +end diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 1bd36bbe20a..ce626d58c66 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -308,132 +308,23 @@ namespace :gitlab do desc "GitLab | Check the configuration of Reply by email" task check: :environment do warn_user_is_not_gitlab - start_checking "Reply by email" if Gitlab.config.incoming_email.enabled - check_imap_authentication + checks = [ + SystemCheck::IncomingEmail::ImapAuthenticationCheck + ] if Rails.env.production? - check_initd_configured_correctly - check_mail_room_running + checks << SystemCheck::IncomingEmail::InitdConfiguredCheck + checks << SystemCheck::IncomingEmail::MailRoomRunningCheck else - check_foreman_configured_correctly + checks << SystemCheck::IncomingEmail::ForemanConfiguredCheck end + + SystemCheck.run('Reply by email', checks) else puts 'Reply by email is disabled in config/gitlab.yml' end - - finished_checking "Reply by email" - end - - # Checks - ######################## - - def check_initd_configured_correctly - return if omnibus_gitlab? - - print "Init.d configured correctly? ... " - - path = "/etc/default/gitlab" - - if File.exist?(path) && File.read(path).include?("mail_room_enabled=true") - puts "yes".color(:green) - else - puts "no".color(:red) - try_fixing_it( - "Enable mail_room in the init.d configuration." - ) - for_more_information( - "doc/administration/reply_by_email.md" - ) - fix_and_rerun - end - end - - def check_foreman_configured_correctly - print "Foreman configured correctly? ... " - - path = Rails.root.join("Procfile") - - if File.exist?(path) && File.read(path) =~ /^mail_room:/ - puts "yes".color(:green) - else - puts "no".color(:red) - try_fixing_it( - "Enable mail_room in your Procfile." - ) - for_more_information( - "doc/administration/reply_by_email.md" - ) - fix_and_rerun - end - end - - def check_mail_room_running - return if omnibus_gitlab? - - print "MailRoom running? ... " - - path = "/etc/default/gitlab" - - unless File.exist?(path) && File.read(path).include?("mail_room_enabled=true") - puts "can't check because of previous errors".color(:magenta) - return - end - - if mail_room_running? - puts "yes".color(:green) - else - puts "no".color(:red) - try_fixing_it( - sudo_gitlab("RAILS_ENV=production bin/mail_room start") - ) - for_more_information( - see_installation_guide_section("Install Init Script"), - "see log/mail_room.log for possible errors" - ) - fix_and_rerun - end - end - - def check_imap_authentication - print "IMAP server credentials are correct? ... " - - config_path = Rails.root.join('config', 'mail_room.yml').to_s - erb = ERB.new(File.read(config_path)) - erb.filename = config_path - config_file = YAML.load(erb.result) - - config = config_file[:mailboxes].first - - if config - begin - imap = Net::IMAP.new(config[:host], port: config[:port], ssl: config[:ssl]) - imap.starttls if config[:start_tls] - imap.login(config[:email], config[:password]) - connected = true - rescue - connected = false - end - end - - if connected - puts "yes".color(:green) - else - puts "no".color(:red) - try_fixing_it( - "Check that the information in config/gitlab.yml is correct" - ) - for_more_information( - "doc/administration/reply_by_email.md" - ) - fix_and_rerun - end - end - - def mail_room_running? - ps_ux, _ = Gitlab::Popen.popen(%w(ps uxww)) - ps_ux.include?("mail_room") end end From 2b90f441d98c63f771f154f26b5a824fe32ef11f Mon Sep 17 00:00:00 2001 From: M M Arif Date: Sat, 26 Aug 2017 12:21:10 +0000 Subject: [PATCH 10/35] Upload New File --- .../gpg_signed_commits/img/git-gpg2-config.png | Bin 0 -> 17145 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/user/project/gpg_signed_commits/img/git-gpg2-config.png diff --git a/doc/user/project/gpg_signed_commits/img/git-gpg2-config.png b/doc/user/project/gpg_signed_commits/img/git-gpg2-config.png new file mode 100644 index 0000000000000000000000000000000000000000..4b8025a00a4553b6c3d5629b5b53f731e9b1f1a0 GIT binary patch literal 17145 zcmdsf^+QzA);1-ml!$amOC#MQf^-N-cZ+n_03t0gbeBqrG)Q-McQ;7G3^BmKd;`As zzW4pU_ufC?+dmBF%sFSDz1LoQt>;;5F=6kOq_LlpK1D)8!j_ehR7FBURX`k{KSoD< znwGgHA^xB_zm@&)7}0=_%|a39Brfl?T-59>T-=SF%#keZ>}}22oK2m~&F!2&+PfU1 zwum7iy+o3g6#w9nez4@39_b42Ih}DGPT>xpv&2FVD98WNH_aT>KqC+MP@@{gMKH%a zw$46RK`>{ho9m<&lauC#C;OavlX8JG;WAS^myjjE$| z^p=qoiuR0jU0Fuvr5O5WT=j-1i|aF45sjXj$Ke2~farZnnq~=8WQttFgvdZEvzv_+qI_$st6hZU9=GBJsPRojevlESi3+Df``{FuT}l(^8) zUi1EpjNa)i{%4fWha;y3kfIxQEPeIhWMOlUaw$-=dV?3|nrQi_!x(0L;%~j<$~B5* zTT{mxPnOxi{XE92P_fCy8!-t(cnWDi_oOl0_LEMJqycg3DAo>&c87~83#97wT&;cOw|*5CbAC`*5*-*Njmu*(Thit( zW{KMMryBi>l|@<`_>sijZ6Et5T-Z(R5V}&{oYk$&&dr#Fr+d-{?6%I#(onL5@TtQ6 zGB9;$fC%9;VPp_rWBv6i9>`VL&~)CSa|@Mhi}H?T&+hlWlknV$&&|I zNu%f#9^cS&2waf3Ls}AtEIk|S7PSXLnpgmo}~+zhjg@WM!J$!iKk~B1olDBa+(;TNuvpQQ-nOq6ua6&e;B-gi#WZ!&@6I)ZV zGlNc1TbU?3o=Bw)k!D9i#@?_}L$2^m?Vk06OKp>&>L6DwOz@F%%`^?=xcf2=1ls$` zZUo_Fgf-+pl4qnGT5*JPL&Thk-{yNcg0JgT9LNtY|Hbmn3OQoGK_gaIBEI2IV!xE zb|y}O7zV}ElU7vRXV0HI4d0GWOnB~OxX;!)n!Z+NKW@)+pZDzf z4QV3#U1|##`#~LUQUj%^*RvNdT$XRYeECufzq=totmbAc_m`5~%TUITCRYi&9m^IQ zR0CR`Wz_D=Cup~eELT=7X+Nc^P6C`GMr(To;?V=gPnP}0Jv)%~jzobshxx$fW1S-_ zuz*A+^ee9)WgCT-|JQDGF+DIw$^u|3yi@A8{hffaV6#yNwcn?e`Cz#m$cD7FtlLz> zpF4B?_kNO+jT^2;TqyfvuA>vbFXmd?gX~}PuMvxFS&tRn`iQ_kp)ON#2XWw2B>k9H z9f~V+dHeC>ANnGM9&QRq3x(jC$C}f{Y@>nQAaj9FHWwFCbW81(YZ7ybjQ>v?_!=_#INi%zLY8exo} zZICC@>2dv5*b*@5(*mBG3<5UOqjHx$zIGSC#lt%VIo=%BWRbV>DdJD?I5sQ=hJ+B6 zxg(uZQuckG-zUBWV;l&$j#u!0AjZayAVoWyla-WTQAZ<{U4wZ8lTF$nkv0oZ`8d%-p#l-F`J&yBJ z)G^%Y*q$4h_1vb&ETJvBaS(KGcETJQC|!@Eb@lXe!5u8_`(UFLE|bNIbEwx-aY8)Ub*PMbC{0Rdm?irS~*x@@_I$W7_U=aBuiq%-=ac;zmZaGleaC@XFh-2_^@u0eez*1U_F34@g#Qr zVeOmoTzTz!mjeE!CL>D_WrlT*tfXYltQJk}T6u_7>(;>!uuSXQMdeK zd>79K44|MUZM#+F=Igze#dfxmonRkww3i{bWHXiK%6HsU)g?D^MHcFhFV}vzo?Y!^ zp}rtZ{mRXXfE)2TV#v^~O_e+^=c7+}5xguZq5z-Hp77?)(gDY?I+kJpjViMzL9$+f zw~W(D8}DmmU|Ou>w7s3pTGdaI*lMo`V5%sB6Wy1EHTr_WJP-ZfdxBthHSnN9wJ&G5eXvMhr3C8L3Bd4lA=7mB$EUHg zqnnRZHvqy&?LK729@IEoaTW6?FqW9~&&-QwZ}>mamu^EyK-cc^&3uFM;o3%1~z8>MPc@+d0&O*W8yT`>cdSVDh~1CP2Zr)|{QcXfqziAd0hZm**{F zq)vRa->7{IKJ`qiY(VdRW@f&kNh(Juea^H^F%i0QTL$ z3FAfZr<|fCxnJPeP`z#TrTE5!mE_5q6?$s}#0toP@U*h*ZmDt$>`@An*wz|0r9>P$ z3k0(JZchevG*Q5AdRQqrwL;V0C z5ORC^cS;BV|KF5ic6@wXt{(k?86d2RjDkWVcm|sYArN`y*RNyhUH21RNN8x@DXD=G zJ^Y(a{>e+;`XhENqUAh$fQyK^1id#xNEgwV0`DO)qWzok#1y8dG(|;P`>wqKX^-c= z`1yN=5%Ihx-y?>YfneEg`(sYWHY&5MSc<_2Th>gj$gL-JdNMff~ASMv+#jeT+Y;C09pUc8PpF7aLeC-T}U>4YM!k9~lso7#G38Qxl$?$r)m7;hb-vpV}c(R_oC@1_yjOy^NONINfL7qa&TOd#b zNi9!dt<@j3v$Hea!Ief;#D=&=7p%!z|Ej^6Bg1u&W z0wjfZ1pp0eW`*h{i}_rqW62=Ig1m~5%ZH!u{g<1(lOANFSGI3C7}@Z05`9-Zy6lOw zHSH_S!qqxUZND`GPFw`L6UdYp?BFXZjqH35B^$n*cpVJG+{hNMtu{loU;lH(05uFh zkK8HOy4<)k6FaJEG0j7nvTL0$B}(LEF*|C#Z38X>j@t(>+I~7wB;HWAs|pi4@okXu z;FD^0Emn|l(_^%kwt=+(Mdv`yeBAarYBJ);?5L5`Bl7@S!u`&fvOw)&eQ)g%i3F55 znF32A$SL(Nb9XzZ5~Ja~eW)cF)F(>iBwfdnlu3;3B!XP`Xlu|s$I73O0Z=81$f9i9BStC0(a>> zq4ycKOD(m(yO_RgRmcKf^SN5Hm})qV=za!8qLM>S>~jZ93d&uD+6~;qLH%LN-Jx2@ zFvc!%OiyCecKIiD*H13R@+1(E^RV7Wm`|Us_c3Of^~W>OF)*OKFVPdczBrVB|Ni|G zO-7oo4iq=xZcz?nXN8WdDL~md4`&U@3xU!VSF}sr(lyXQ_<5B8R^gKdqIIBo$LqSTmJ zoFsXGaf4hKN2)oHp14;y!s0%!5KCBpi`i8Z_4^o%5g?f6MLR_9Iu`jzX! z&9fc(w8p}v%1Q>B+%$iC7yQ)er#&?a=AYDYIyrve45fW&t@%b}7o5?X>iScI{juQ+ z=dbDTHh%6f9>!XbjfvvhmqYV>`8q#22n#vHjm4ql_C2m<+yIKl+2)18l2!+^t8tC(Vy!^}@WJ>85+?jS7fSF1U!t2*CKgcN~uPQJvQ^(h-jh z%cPAKmoVj_Zi_3&0D}@hw=3K0Uy^U$c(StXca+18g+v4{x~6@fMskMf@nOM!Ee>X= zHv*HozHUL6l1c_?&2+xJBGWqI{LKP+oO09w~~A;7t#%;a|(I z+wc7~mqJM3BMP50)hgGCn6N{ynq?)<3)>a

bM6@K9x?zQXt4QKA9#$A>j53}Rvi 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 Moswk9Tca=k2NGj6@&Et; literal 0 HcmV?d00001 From da426369fd7813bf5245e76b5322839442cdcb5f Mon Sep 17 00:00:00 2001 From: M M Arif Date: Fri, 1 Sep 2017 12:16:50 +0000 Subject: [PATCH 11/35] Delete git-gpg2-config.png --- .../gpg_signed_commits/img/git-gpg2-config.png | Bin 17145 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 doc/user/project/gpg_signed_commits/img/git-gpg2-config.png diff --git a/doc/user/project/gpg_signed_commits/img/git-gpg2-config.png b/doc/user/project/gpg_signed_commits/img/git-gpg2-config.png deleted file mode 100644 index 4b8025a00a4553b6c3d5629b5b53f731e9b1f1a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17145 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

bM6@K9x?zQXt4QKA9#$A>j53}Rvi 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 Moswk9Tca=k2NGj6@&Et; From ee6ca17c5f4950e62fb483fd56b43293d0f80fc3 Mon Sep 17 00:00:00 2001 From: M M Arif Date: Fri, 1 Sep 2017 21:55:18 +0800 Subject: [PATCH 12/35] Added changelog --- .../unreleased/36859-update-gpg-docs-with-gpg2.yml | 5 +++++ .../project/repository/gpg_signed_commits/index.md | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 changelogs/unreleased/36859-update-gpg-docs-with-gpg2.yml diff --git a/changelogs/unreleased/36859-update-gpg-docs-with-gpg2.yml b/changelogs/unreleased/36859-update-gpg-docs-with-gpg2.yml new file mode 100644 index 00000000000..e48a5704fdd --- /dev/null +++ b/changelogs/unreleased/36859-update-gpg-docs-with-gpg2.yml @@ -0,0 +1,5 @@ +--- +title: Update gpg documentation with gpg2 +merge_request: 13851 +author: M M Arif +type: other diff --git a/doc/user/project/repository/gpg_signed_commits/index.md b/doc/user/project/repository/gpg_signed_commits/index.md index ff419d714f9..859de10590a 100644 --- a/doc/user/project/repository/gpg_signed_commits/index.md +++ b/doc/user/project/repository/gpg_signed_commits/index.md @@ -30,6 +30,16 @@ to be met: ## Generating a GPG key +>**Notes:** +- If your Operating System has `gpg2` installed, replace `gpg` with `gpg2` in + the following commands. +- If Git is using `gpg` and you get errors like `secret key not available` or + `gpg: signing failed: secret key not available`, run the following command to + change to `gpg2`: + ``` + git config --global gpg.program gpg2 + ``` + If you don't already have a GPG key, the following steps will help you get started: From b69579742b5379760ccc868d359a9b6d1d225861 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Fri, 25 Aug 2017 12:01:34 +0200 Subject: [PATCH 13/35] API: Add GPG key management --- .../unreleased/api-gpg-key-management.yml | 5 + lib/api/entities.rb | 4 + lib/api/users.rb | 70 ++++++++ spec/requests/api/users_spec.rb | 168 ++++++++++++++++++ 4 files changed, 247 insertions(+) create mode 100644 changelogs/unreleased/api-gpg-key-management.yml diff --git a/changelogs/unreleased/api-gpg-key-management.yml b/changelogs/unreleased/api-gpg-key-management.yml new file mode 100644 index 00000000000..0be35a5823b --- /dev/null +++ b/changelogs/unreleased/api-gpg-key-management.yml @@ -0,0 +1,5 @@ +--- +title: 'API: Add GPG key management' +merge_request: 13828 +author: Robert Schilling +type: added diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 0092cc14e74..031dd02c6eb 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -491,6 +491,10 @@ module API expose :user, using: Entities::UserPublic end + class GPGKey < Grape::Entity + expose :id, :key, :created_at + end + class Note < Grape::Entity # Only Issue and MergeRequest have iid NOTEABLE_TYPES_WITH_IID = %w(Issue MergeRequest).freeze diff --git a/lib/api/users.rb b/lib/api/users.rb index 96f47bb618a..82991dc9d16 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -492,6 +492,76 @@ module API destroy_conditionally!(key) end + desc "Get the currently authenticated user's GPG keys" do + detail 'This feature was added in GitLab 10.0' + success Entities::GPGKey + end + params do + use :pagination + end + get 'gpg_keys' do + present paginate(current_user.gpg_keys), with: Entities::GPGKey + end + + desc 'Get a single GPG key owned by currently authenticated user' do + detail 'This feature was added in GitLab 10.0' + success Entities::GPGKey + end + params do + requires :key_id, type: Integer, desc: 'The ID of the GPG key' + end + get 'gpg_keys/:key_id' do + key = current_user.gpg_keys.find_by(id: params[:key_id]) + not_found!('GPG Key') unless key + + present key, with: Entities::GPGKey + end + + desc 'Add a new GPG key to the currently authenticated user' do + detail 'This feature was added in GitLab 10.0' + success Entities::GPGKey + end + params do + requires :key, type: String, desc: 'The new GPG key' + end + post 'gpg_keys' do + key = current_user.gpg_keys.new(declared_params) + + if key.save + present key, with: Entities::GPGKey + else + render_validation_error!(key) + end + end + + desc 'Revoke a GPG key owned by currently authenticated user' do + detail 'This feature was added in GitLab 10.0' + end + params do + requires :key_id, type: Integer, desc: 'The ID of the GPG key' + end + post 'gpg_keys/:key_id/revoke' do + key = current_user.gpg_keys.find_by(id: params[:key_id]) + not_found!('GPG Key') unless key + + key.revoke + status :accepted + end + + desc 'Delete a GPG key from the currently authenticated user' do + detail 'This feature was added in GitLab 10.0' + end + params do + requires :key_id, type: Integer, desc: 'The ID of the SSH key' + end + delete 'gpg_keys/:key_id' do + key = current_user.gpg_keys.find_by(id: params[:key_id]) + not_found!('GPG Key') unless key + + status 204 + key.destroy + end + desc "Get the currently authenticated user's email addresses" do success Entities::Email end diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 5fef4437997..c86a99eb6eb 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -4,6 +4,7 @@ describe API::Users do let(:user) { create(:user) } let(:admin) { create(:admin) } let(:key) { create(:key, user: user) } + let(:gpg_key) { create(:gpg_key, user: user) } let(:email) { create(:email, user: user) } let(:omniauth_user) { create(:omniauth_user) } let(:ldap_user) { create(:omniauth_user, provider: 'ldapmain') } @@ -1153,6 +1154,173 @@ describe API::Users do end end + describe 'GET /user/gpg_keys' do + context 'when unauthenticated' do + it 'returns authentication error' do + get api('/user/gpg_keys') + + expect(response).to have_http_status(401) + end + end + + context 'when authenticated' do + it 'returns array of GPG keys' do + user.gpg_keys << gpg_key + user.save + + get api('/user/gpg_keys', user) + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.first['key']).to eq(gpg_key.key) + end + + context 'scopes' do + let(:path) { '/user/gpg_keys' } + let(:api_call) { method(:api) } + + include_examples 'allows the "read_user" scope' + end + end + end + + describe 'GET /user/gpg_keys/:key_id' do + it 'returns a single key' do + user.gpg_keys << gpg_key + user.save + + get api("/user/gpg_keys/#{gpg_key.id}", user) + + expect(response).to have_http_status(200) + expect(json_response['key']).to eq(gpg_key.key) + end + + it 'returns 404 Not Found within invalid ID' do + get api('/user/gpg_keys/42', user) + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 GPG Key Not Found') + end + + it "returns 404 error if admin accesses user's GPG key" do + user.gpg_keys << gpg_key + user.save + + get api("/user/gpg_keys/#{gpg_key.id}", admin) + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 GPG Key Not Found') + end + + it 'returns 404 for invalid ID' do + get api('/users/gpg_keys/ASDF', admin) + + expect(response).to have_http_status(404) + end + + context 'scopes' do + let(:path) { "/user/gpg_keys/#{gpg_key.id}" } + let(:api_call) { method(:api) } + + include_examples 'allows the "read_user" scope' + end + end + + describe 'POST /user/gpg_keys' do + it 'creates a GPG key' do + key_attrs = attributes_for :gpg_key + expect do + post api('/user/gpg_keys', user), key_attrs + + expect(response).to have_http_status(201) + end.to change { user.gpg_keys.count }.by(1) + end + + it 'returns a 401 error if unauthorized' do + post api('/user/gpg_keys'), key: 'some key' + + expect(response).to have_http_status(401) + end + + it 'does not create GPG key without key' do + post api('/user/gpg_keys', user) + + expect(response).to have_http_status(400) + expect(json_response['error']).to eq('key is missing') + end + end + + describe 'POST /user/gpg_keys/:key_id/revoke' do + it 'revokes existing GPG key' do + user.gpg_keys << gpg_key + user.save + + expect do + post api("/user/gpg_keys/#{gpg_key.id}/revoke", user) + + expect(response).to have_http_status(:accepted) + end.to change { user.gpg_keys.count}.by(-1) + end + + it 'returns 404 if key ID not found' do + post api('/user/gpg_keys/42/revoke', user) + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 GPG Key Not Found') + end + + it 'returns 401 error if unauthorized' do + user.gpg_keys << gpg_key + user.save + + post api("/user/gpg_keys/#{gpg_key.id}/revoke") + + expect(response).to have_http_status(401) + end + + it 'returns a 404 for invalid ID' do + post api('/users/gpg_keys/ASDF/revoke', admin) + + expect(response).to have_http_status(404) + end + end + + describe 'DELETE /user/gpg_keys/:key_id' do + it 'deletes existing GPG key' do + user.gpg_keys << gpg_key + user.save + + expect do + delete api("/user/gpg_keys/#{gpg_key.id}", user) + + expect(response).to have_http_status(204) + end.to change { user.gpg_keys.count}.by(-1) + end + + it 'returns 404 if key ID not found' do + delete api('/user/gpg_keys/42', user) + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 GPG Key Not Found') + end + + it 'returns 401 error if unauthorized' do + user.gpg_keys << gpg_key + user.save + + delete api("/user/gpg_keys/#{gpg_key.id}") + + expect(response).to have_http_status(401) + end + + it 'returns a 404 for invalid ID' do + delete api('/users/gpg_keys/ASDF', admin) + + expect(response).to have_http_status(404) + end + end + describe "GET /user/emails" do context "when unauthenticated" do it "returns authentication error" do From 97371848c5fccb7ba066cc0c50c0d3ed15ec5971 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Fri, 25 Aug 2017 12:24:41 +0200 Subject: [PATCH 14/35] API: Add GPG key management for admins --- lib/api/users.rb | 80 ++++++++++++++++ spec/requests/api/users_spec.rb | 158 ++++++++++++++++++++++++++++++++ 2 files changed, 238 insertions(+) diff --git a/lib/api/users.rb b/lib/api/users.rb index 82991dc9d16..1825c90a23b 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -233,6 +233,86 @@ module API destroy_conditionally!(key) end + desc 'Add a GPG key to a specified user. Available only for admins.' do + detail 'This feature was added in GitLab 10.0' + success Entities::GPGKey + end + params do + requires :id, type: Integer, desc: 'The ID of the user' + requires :key, type: String, desc: 'The new GPG key' + end + post ':id/gpg_keys' do + authenticated_as_admin! + + user = User.find_by(id: params.delete(:id)) + not_found!('User') unless user + + key = user.gpg_keys.new(declared_params(include_missing: false)) + + if key.save + present key, with: Entities::GPGKey + else + render_validation_error!(key) + end + end + + desc 'Get the GPG keys of a specified user. Available only for admins.' do + detail 'This feature was added in GitLab 10.0' + success Entities::GPGKey + end + params do + requires :id, type: Integer, desc: 'The ID of the user' + use :pagination + end + get ':id/gpg_keys' do + authenticated_as_admin! + + user = User.find_by(id: params[:id]) + not_found!('User') unless user + + present paginate(user.gpg_keys), with: Entities::GPGKey + end + + desc 'Delete an existing GPG key from a specified user. Available only for admins.' do + detail 'This feature was added in GitLab 10.0' + end + params do + requires :id, type: Integer, desc: 'The ID of the user' + requires :key_id, type: Integer, desc: 'The ID of the GPG key' + end + delete ':id/gpg_keys/:key_id' do + authenticated_as_admin! + + user = User.find_by(id: params[:id]) + not_found!('User') unless user + + key = user.gpg_keys.find_by(id: params[:key_id]) + not_found!('GPG Key') unless key + + status 204 + key.destroy + end + + desc 'Revokes an existing GPG key from a specified user. Available only for admins.' do + detail 'This feature was added in GitLab 10.0' + end + params do + requires :id, type: Integer, desc: 'The ID of the user' + requires :key_id, type: Integer, desc: 'The ID of the GPG key' + end + post ':id/gpg_keys/:key_id/revoke' do + authenticated_as_admin! + + user = User.find_by(id: params[:id]) + not_found!('User') unless user + + key = user.gpg_keys.find_by(id: params[:key_id]) + not_found!('GPG Key') unless key + + key.revoke + status :accepted + end + desc 'Add an email address to a specified user. Available only for admins.' do success Entities::Email end diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index c86a99eb6eb..37cb95a16e3 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -754,6 +754,164 @@ describe API::Users do end end + describe 'POST /users/:id/keys' do + before do + admin + end + + it 'does not create invalid GPG key' do + post api("/users/#{user.id}/gpg_keys", admin) + + expect(response).to have_http_status(400) + expect(json_response['error']).to eq('key is missing') + end + + it 'creates GPG key' do + key_attrs = attributes_for :gpg_key + expect do + post api("/users/#{user.id}/gpg_keys", admin), key_attrs + + expect(response).to have_http_status(201) + end.to change { user.gpg_keys.count }.by(1) + end + + it 'returns 400 for invalid ID' do + post api('/users/999999/gpg_keys', admin) + + expect(response).to have_http_status(400) + end + end + + describe 'GET /user/:id/gpg_keys' do + before do + admin + end + + context 'when unauthenticated' do + it 'returns authentication error' do + get api("/users/#{user.id}/gpg_keys") + + expect(response).to have_http_status(401) + end + end + + context 'when authenticated' do + it 'returns 404 for non-existing user' do + get api('/users/999999/gpg_keys', admin) + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 User Not Found') + end + + it 'returns 404 error if key not foud' do + delete api("/users/#{user.id}/gpg_keys/42", admin) + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 GPG Key Not Found') + end + + it 'returns array of GPG keys' do + user.gpg_keys << gpg_key + user.save + + get api("/users/#{user.id}/gpg_keys", admin) + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.first['key']).to eq(gpg_key.key) + end + end + end + + describe 'DELETE /user/:id/gpg_keys/:key_id' do + before do + admin + end + + context 'when unauthenticated' do + it 'returns authentication error' do + delete api("/users/#{user.id}/keys/42") + + expect(response).to have_http_status(401) + end + end + + context 'when authenticated' do + it 'deletes existing key' do + user.gpg_keys << gpg_key + user.save + + expect do + delete api("/users/#{user.id}/gpg_keys/#{gpg_key.id}", admin) + + expect(response).to have_http_status(204) + end.to change { user.gpg_keys.count }.by(-1) + end + + it 'returns 404 error if user not found' do + user.keys << key + user.save + + delete api("/users/999999/gpg_keys/#{gpg_key.id}", admin) + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 User Not Found') + end + + it 'returns 404 error if key not foud' do + delete api("/users/#{user.id}/gpg_keys/42", admin) + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 GPG Key Not Found') + end + end + end + + describe 'POST /user/:id/gpg_keys/:key_id/revoke' do + before do + admin + end + + context 'when unauthenticated' do + it 'returns authentication error' do + post api("/users/#{user.id}/gpg_keys/42/revoke") + + expect(response).to have_http_status(401) + end + end + + context 'when authenticated' do + it 'revokes existing key' do + user.gpg_keys << gpg_key + user.save + + expect do + post api("/users/#{user.id}/gpg_keys/#{gpg_key.id}/revoke", admin) + + expect(response).to have_http_status(:accepted) + end.to change { user.gpg_keys.count }.by(-1) + end + + it 'returns 404 error if user not found' do + user.gpg_keys << gpg_key + user.save + + post api("/users/999999/gpg_keys/#{gpg_key.id}/revoke", admin) + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 User Not Found') + end + + it 'returns 404 error if key not foud' do + post api("/users/#{user.id}/gpg_keys/42/revoke", admin) + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 GPG Key Not Found') + end + end + end + describe "POST /users/:id/emails" do before do admin From f4834c8ad5cd09ef4ed2be47eb2123cc06f05f6c Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Tue, 5 Sep 2017 11:32:27 +0200 Subject: [PATCH 15/35] Add documentation --- doc/api/users.md | 211 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) diff --git a/doc/api/users.md b/doc/api/users.md index 57a13eb477d..57b4e117cf3 100644 --- a/doc/api/users.md +++ b/doc/api/users.md @@ -550,6 +550,217 @@ Parameters: Will return `200 OK` on success, or `404 Not found` if either user or key cannot be found. +## List all GPG keys + +Get a list of currently authenticated user's GPG keys. + +``` +GET /user/gpg_keys +``` + +```bash +curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/user/gpg_keys +``` + +Example response: + +```json +[ + { + "id": 1, + "key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFVjnlIBCACibzXOLCiZiL2oyzYUaTOCkYnSUhymg3pdbfKtd4mpBa58xKBj\r\nt1pTHVpw3Sk03wmzhM/Ndlt1AV2YhLv++83WKr+gAHFYFiCV/tnY8bx3HqvVoy8O\r\nCfxWhw4QZK7+oYzVmJj8ZJm3ZjOC4pzuegNWlNLCUdZDx9OKlHVXLCX1iUbjdYWa\r\nqKV6tdV8hZolkbyjedQgrpvoWyeSHHpwHF7yk4gNJWMMI5rpcssL7i6mMXb/sDzO\r\nVaAtU5wiVducsOa01InRFf7QSTxoAm6Xy0PGv/k48M6xCALa9nY+BzlOv47jUT57\r\nvilf4Szy9dKD0v9S0mQ+IHB+gNukWrnwtXx5ABEBAAHNFm5hbWUgKGNvbW1lbnQp\r\nIDxlbUBpbD7CwHUEEwECACkFAlVjnlIJEINgJNgv009/AhsDAhkBBgsJCAcDAgYV\r\nCAIJCgsEFgIDAQAAxqMIAFBHuBA8P1v8DtHonIK8Lx2qU23t8Mh68HBIkSjk2H7/\r\noO2cDWCw50jZ9D91PXOOyMPvBWV2IE3tARzCvnNGtzEFRtpIEtZ0cuctxeIF1id5\r\ncrfzdMDsmZyRHAOoZ9VtuD6mzj0ybQWMACb7eIHjZDCee3Slh3TVrLy06YRdq2I4\r\nbjMOPePtK5xnIpHGpAXkB3IONxyITpSLKsA4hCeP7gVvm7r7TuQg1ygiUBlWbBYn\r\niE5ROzqZjG1s7dQNZK/riiU2umGqGuwAb2IPvNiyuGR3cIgRE4llXH/rLuUlspAp\r\no4nlxaz65VucmNbN1aMbDXLJVSqR1DuE00vEsL1AItI=\r\n=XQoy\r\n-----END PGP PUBLIC KEY BLOCK-----", + "created_at": "2017-09-05T09:17:46.264Z" + } +] +``` + +## Get a specific GPG key + +Get a specific GPG key of currently authenticated user. + +``` +GET /user/gpg_keys/:key_id +``` + +Parameters: + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `key_id` | integer | yes | The ID of the GPG key | + +```bash +curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/user/gpg_keys/1 +``` + +Example response: + +```json + { + "id": 1, + "key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFVjnlIBCACibzXOLCiZiL2oyzYUaTOCkYnSUhymg3pdbfKtd4mpBa58xKBj\r\nt1pTHVpw3Sk03wmzhM/Ndlt1AV2YhLv++83WKr+gAHFYFiCV/tnY8bx3HqvVoy8O\r\nCfxWhw4QZK7+oYzVmJj8ZJm3ZjOC4pzuegNWlNLCUdZDx9OKlHVXLCX1iUbjdYWa\r\nqKV6tdV8hZolkbyjedQgrpvoWyeSHHpwHF7yk4gNJWMMI5rpcssL7i6mMXb/sDzO\r\nVaAtU5wiVducsOa01InRFf7QSTxoAm6Xy0PGv/k48M6xCALa9nY+BzlOv47jUT57\r\nvilf4Szy9dKD0v9S0mQ+IHB+gNukWrnwtXx5ABEBAAHNFm5hbWUgKGNvbW1lbnQp\r\nIDxlbUBpbD7CwHUEEwECACkFAlVjnlIJEINgJNgv009/AhsDAhkBBgsJCAcDAgYV\r\nCAIJCgsEFgIDAQAAxqMIAFBHuBA8P1v8DtHonIK8Lx2qU23t8Mh68HBIkSjk2H7/\r\noO2cDWCw50jZ9D91PXOOyMPvBWV2IE3tARzCvnNGtzEFRtpIEtZ0cuctxeIF1id5\r\ncrfzdMDsmZyRHAOoZ9VtuD6mzj0ybQWMACb7eIHjZDCee3Slh3TVrLy06YRdq2I4\r\nbjMOPePtK5xnIpHGpAXkB3IONxyITpSLKsA4hCeP7gVvm7r7TuQg1ygiUBlWbBYn\r\niE5ROzqZjG1s7dQNZK/riiU2umGqGuwAb2IPvNiyuGR3cIgRE4llXH/rLuUlspAp\r\no4nlxaz65VucmNbN1aMbDXLJVSqR1DuE00vEsL1AItI=\r\n=XQoy\r\n-----END PGP PUBLIC KEY BLOCK-----", + "created_at": "2017-09-05T09:17:46.264Z" + } +``` + +## Add a GPG key + +Creates a new GPG key owned by the currently authenticated user. + +``` +POST /user/gpg_keys +``` + +Parameters: + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| key | string | yes | The new GPG key | + +```bash +curl --data "key=-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFV..." --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/user/gpg_keys +``` + +Example response: + +```json +[ + { + "id": 1, + "key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFVjnlIBCACibzXOLCiZiL2oyzYUaTOCkYnSUhymg3pdbfKtd4mpBa58xKBj\r\nt1pTHVpw3Sk03wmzhM/Ndlt1AV2YhLv++83WKr+gAHFYFiCV/tnY8bx3HqvVoy8O\r\nCfxWhw4QZK7+oYzVmJj8ZJm3ZjOC4pzuegNWlNLCUdZDx9OKlHVXLCX1iUbjdYWa\r\nqKV6tdV8hZolkbyjedQgrpvoWyeSHHpwHF7yk4gNJWMMI5rpcssL7i6mMXb/sDzO\r\nVaAtU5wiVducsOa01InRFf7QSTxoAm6Xy0PGv/k48M6xCALa9nY+BzlOv47jUT57\r\nvilf4Szy9dKD0v9S0mQ+IHB+gNukWrnwtXx5ABEBAAHNFm5hbWUgKGNvbW1lbnQp\r\nIDxlbUBpbD7CwHUEEwECACkFAlVjnlIJEINgJNgv009/AhsDAhkBBgsJCAcDAgYV\r\nCAIJCgsEFgIDAQAAxqMIAFBHuBA8P1v8DtHonIK8Lx2qU23t8Mh68HBIkSjk2H7/\r\noO2cDWCw50jZ9D91PXOOyMPvBWV2IE3tARzCvnNGtzEFRtpIEtZ0cuctxeIF1id5\r\ncrfzdMDsmZyRHAOoZ9VtuD6mzj0ybQWMACb7eIHjZDCee3Slh3TVrLy06YRdq2I4\r\nbjMOPePtK5xnIpHGpAXkB3IONxyITpSLKsA4hCeP7gVvm7r7TuQg1ygiUBlWbBYn\r\niE5ROzqZjG1s7dQNZK/riiU2umGqGuwAb2IPvNiyuGR3cIgRE4llXH/rLuUlspAp\r\no4nlxaz65VucmNbN1aMbDXLJVSqR1DuE00vEsL1AItI=\r\n=XQoy\r\n-----END PGP PUBLIC KEY BLOCK-----", + "created_at": "2017-09-05T09:17:46.264Z" + } +] +``` + +## Delete a GPG key + +Delete a GPG key owned by currently authenticated user. + +``` +DELETE /user/gpg_keys/:key_id +``` + +Parameters: + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `key_id` | integer | yes | The ID of the GPG key | + +```bash +curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/user/gpg_keys/1 +``` + +Returns `204 No Content` on success, or `404 Not found` if the key cannot be found. + +## List all GPG keys for given user + +Get a list of a specified user's GPG keys. Available only for admins. + +``` +GET /users/:id/gpg_keys +``` + +Parameters: + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer | yes | The ID of the user | + +```bash +curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/users/2/gpg_keys +``` + +Example response: + +```json +[ + { + "id": 1, + "key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFVjnlIBCACibzXOLCiZiL2oyzYUaTOCkYnSUhymg3pdbfKtd4mpBa58xKBj\r\nt1pTHVpw3Sk03wmzhM/Ndlt1AV2YhLv++83WKr+gAHFYFiCV/tnY8bx3HqvVoy8O\r\nCfxWhw4QZK7+oYzVmJj8ZJm3ZjOC4pzuegNWlNLCUdZDx9OKlHVXLCX1iUbjdYWa\r\nqKV6tdV8hZolkbyjedQgrpvoWyeSHHpwHF7yk4gNJWMMI5rpcssL7i6mMXb/sDzO\r\nVaAtU5wiVducsOa01InRFf7QSTxoAm6Xy0PGv/k48M6xCALa9nY+BzlOv47jUT57\r\nvilf4Szy9dKD0v9S0mQ+IHB+gNukWrnwtXx5ABEBAAHNFm5hbWUgKGNvbW1lbnQp\r\nIDxlbUBpbD7CwHUEEwECACkFAlVjnlIJEINgJNgv009/AhsDAhkBBgsJCAcDAgYV\r\nCAIJCgsEFgIDAQAAxqMIAFBHuBA8P1v8DtHonIK8Lx2qU23t8Mh68HBIkSjk2H7/\r\noO2cDWCw50jZ9D91PXOOyMPvBWV2IE3tARzCvnNGtzEFRtpIEtZ0cuctxeIF1id5\r\ncrfzdMDsmZyRHAOoZ9VtuD6mzj0ybQWMACb7eIHjZDCee3Slh3TVrLy06YRdq2I4\r\nbjMOPePtK5xnIpHGpAXkB3IONxyITpSLKsA4hCeP7gVvm7r7TuQg1ygiUBlWbBYn\r\niE5ROzqZjG1s7dQNZK/riiU2umGqGuwAb2IPvNiyuGR3cIgRE4llXH/rLuUlspAp\r\no4nlxaz65VucmNbN1aMbDXLJVSqR1DuE00vEsL1AItI=\r\n=XQoy\r\n-----END PGP PUBLIC KEY BLOCK-----", + "created_at": "2017-09-05T09:17:46.264Z" + } +] +``` + +## Get a specific GPG key for a given user + +Get a specific GPG key for a given user. Available only for admins. + +``` +GET /users/:id/gpg_keys/:key_id +``` + +Parameters: + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer | yes | The ID of the user | +| `key_id` | integer | yes | The ID of the GPG key | + +```bash +curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/users/2/gpg_keys/1 +``` + +Example response: + +```json + { + "id": 1, + "key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFVjnlIBCACibzXOLCiZiL2oyzYUaTOCkYnSUhymg3pdbfKtd4mpBa58xKBj\r\nt1pTHVpw3Sk03wmzhM/Ndlt1AV2YhLv++83WKr+gAHFYFiCV/tnY8bx3HqvVoy8O\r\nCfxWhw4QZK7+oYzVmJj8ZJm3ZjOC4pzuegNWlNLCUdZDx9OKlHVXLCX1iUbjdYWa\r\nqKV6tdV8hZolkbyjedQgrpvoWyeSHHpwHF7yk4gNJWMMI5rpcssL7i6mMXb/sDzO\r\nVaAtU5wiVducsOa01InRFf7QSTxoAm6Xy0PGv/k48M6xCALa9nY+BzlOv47jUT57\r\nvilf4Szy9dKD0v9S0mQ+IHB+gNukWrnwtXx5ABEBAAHNFm5hbWUgKGNvbW1lbnQp\r\nIDxlbUBpbD7CwHUEEwECACkFAlVjnlIJEINgJNgv009/AhsDAhkBBgsJCAcDAgYV\r\nCAIJCgsEFgIDAQAAxqMIAFBHuBA8P1v8DtHonIK8Lx2qU23t8Mh68HBIkSjk2H7/\r\noO2cDWCw50jZ9D91PXOOyMPvBWV2IE3tARzCvnNGtzEFRtpIEtZ0cuctxeIF1id5\r\ncrfzdMDsmZyRHAOoZ9VtuD6mzj0ybQWMACb7eIHjZDCee3Slh3TVrLy06YRdq2I4\r\nbjMOPePtK5xnIpHGpAXkB3IONxyITpSLKsA4hCeP7gVvm7r7TuQg1ygiUBlWbBYn\r\niE5ROzqZjG1s7dQNZK/riiU2umGqGuwAb2IPvNiyuGR3cIgRE4llXH/rLuUlspAp\r\no4nlxaz65VucmNbN1aMbDXLJVSqR1DuE00vEsL1AItI=\r\n=XQoy\r\n-----END PGP PUBLIC KEY BLOCK-----", + "created_at": "2017-09-05T09:17:46.264Z" + } +``` + +## Add a GPG key for a given user + +Create new GPG key owned by the specified user. Available only for admins. + +``` +POST /users/:id/gpg_keys +``` + +Parameters: + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer | yes | The ID of the user | +| `key_id` | integer | yes | The ID of the GPG key | + +```bash +curl --data "key=-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFV..." --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/users/2/gpg_keys +``` + +Example response: + +```json +[ + { + "id": 1, + "key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFVjnlIBCACibzXOLCiZiL2oyzYUaTOCkYnSUhymg3pdbfKtd4mpBa58xKBj\r\nt1pTHVpw3Sk03wmzhM/Ndlt1AV2YhLv++83WKr+gAHFYFiCV/tnY8bx3HqvVoy8O\r\nCfxWhw4QZK7+oYzVmJj8ZJm3ZjOC4pzuegNWlNLCUdZDx9OKlHVXLCX1iUbjdYWa\r\nqKV6tdV8hZolkbyjedQgrpvoWyeSHHpwHF7yk4gNJWMMI5rpcssL7i6mMXb/sDzO\r\nVaAtU5wiVducsOa01InRFf7QSTxoAm6Xy0PGv/k48M6xCALa9nY+BzlOv47jUT57\r\nvilf4Szy9dKD0v9S0mQ+IHB+gNukWrnwtXx5ABEBAAHNFm5hbWUgKGNvbW1lbnQp\r\nIDxlbUBpbD7CwHUEEwECACkFAlVjnlIJEINgJNgv009/AhsDAhkBBgsJCAcDAgYV\r\nCAIJCgsEFgIDAQAAxqMIAFBHuBA8P1v8DtHonIK8Lx2qU23t8Mh68HBIkSjk2H7/\r\noO2cDWCw50jZ9D91PXOOyMPvBWV2IE3tARzCvnNGtzEFRtpIEtZ0cuctxeIF1id5\r\ncrfzdMDsmZyRHAOoZ9VtuD6mzj0ybQWMACb7eIHjZDCee3Slh3TVrLy06YRdq2I4\r\nbjMOPePtK5xnIpHGpAXkB3IONxyITpSLKsA4hCeP7gVvm7r7TuQg1ygiUBlWbBYn\r\niE5ROzqZjG1s7dQNZK/riiU2umGqGuwAb2IPvNiyuGR3cIgRE4llXH/rLuUlspAp\r\no4nlxaz65VucmNbN1aMbDXLJVSqR1DuE00vEsL1AItI=\r\n=XQoy\r\n-----END PGP PUBLIC KEY BLOCK-----", + "created_at": "2017-09-05T09:17:46.264Z" + } +] +``` + +## Delete a GPG key for a given user + +Delete a GPG key owned by a specified user. Available only for admins. + +``` +DELETE /users/:id/gpg_keys/:key_id +``` + +Parameters: + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer | yes | The ID of the user | +| `key_id` | integer | yes | The ID of the GPG key | + +```bash +curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/users/2/gpg_keys/1 +``` + ## List emails Get a list of currently authenticated user's emails. From c0303b81feda982d2640ffd594f6c01e9b6502ea Mon Sep 17 00:00:00 2001 From: Hiroyuki Sato Date: Tue, 5 Sep 2017 22:22:16 +0900 Subject: [PATCH 16/35] Update search document --- doc/user/search/img/issue_search_by_term.png | Bin 0 -> 65826 bytes doc/user/search/index.md | 10 ++++++---- 2 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 doc/user/search/img/issue_search_by_term.png diff --git a/doc/user/search/img/issue_search_by_term.png b/doc/user/search/img/issue_search_by_term.png new file mode 100644 index 0000000000000000000000000000000000000000..66e612c4ea6168ff77d5578e8a312f59e5181103 GIT binary patch literal 65826 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 IyRQHL0ev1q7XSbN literal 0 HcmV?d00001 diff --git a/doc/user/search/index.md b/doc/user/search/index.md index 609d66d1dcb..21e96d8b11c 100644 --- a/doc/user/search/index.md +++ b/doc/user/search/index.md @@ -42,15 +42,17 @@ milestone, and label. ### Searching for specific terms -You can filter issues by specific terms included in titles or descriptions. +You can filter issues and merge requests by specific terms included in titles or descriptions. * Syntax - * Searches look for all the words in a query, in any order - e.g.: searching + * Searches look for all the words in a query, in any order. E.g.: searching issues for `display bug` will return all issues matching both those words, in any order. * To find the exact term, use double quotes: `"display bug"` * Limitation - * For a performance reason, the terms shorter than 3 chars are ignored - e.g.: searching - issues for `included in titles` is same with `included titles` + * For performance reasons, terms shorter than 3 chars are ignored. E.g.: searching + issues for `included in titles` is same as `included titles` + +![filter issues by specific terms](img/issue_search_by_term.png) ### Issues and merge requests per group From 8bafe5d1eed5b6430afd565d8c0fbdedac17c1b8 Mon Sep 17 00:00:00 2001 From: Hiroyuki Sato Date: Tue, 5 Sep 2017 22:23:02 +0900 Subject: [PATCH 17/35] Fix typo --- spec/lib/gitlab/sql/pattern_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/gitlab/sql/pattern_spec.rb b/spec/lib/gitlab/sql/pattern_spec.rb index a780776d48e..48d56628ed5 100644 --- a/spec/lib/gitlab/sql/pattern_spec.rb +++ b/spec/lib/gitlab/sql/pattern_spec.rb @@ -80,7 +80,7 @@ describe Gitlab::SQL::Pattern do end end - context 'with two words divided by two speces both equal to 3 chars' do + context 'with two words divided by two spaces both equal to 3 chars' do let(:query) { 'foo baz' } it 'returns array containing two words' do From b0e30189a0cb82a03d6b6b25c04fa1498da85b0b Mon Sep 17 00:00:00 2001 From: Jarka Kadlecova Date: Fri, 25 Aug 2017 13:37:21 +0200 Subject: [PATCH 18/35] Migrate issues authored by deleted user to the Ghost user --- .../36860-migrate-issues-author.yml | 5 ++ ...0825104051_migrate_issues_to_ghost_user.rb | 36 +++++++++++++ ...1071411_add_foreign_key_to_issue_author.rb | 14 +++++ db/schema.rb | 3 +- .../migrate_issues_to_ghost_user_spec.rb | 51 +++++++++++++++++++ 5 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/36860-migrate-issues-author.yml create mode 100644 db/migrate/20170825104051_migrate_issues_to_ghost_user.rb create mode 100644 db/migrate/20170901071411_add_foreign_key_to_issue_author.rb create mode 100644 spec/migrations/migrate_issues_to_ghost_user_spec.rb diff --git a/changelogs/unreleased/36860-migrate-issues-author.yml b/changelogs/unreleased/36860-migrate-issues-author.yml new file mode 100644 index 00000000000..3e9fcc55836 --- /dev/null +++ b/changelogs/unreleased/36860-migrate-issues-author.yml @@ -0,0 +1,5 @@ +--- +title: Migrate issues authored by deleted user to the Ghost user +merge_request: +author: +type: fixed diff --git a/db/migrate/20170825104051_migrate_issues_to_ghost_user.rb b/db/migrate/20170825104051_migrate_issues_to_ghost_user.rb new file mode 100644 index 00000000000..294141e4fdb --- /dev/null +++ b/db/migrate/20170825104051_migrate_issues_to_ghost_user.rb @@ -0,0 +1,36 @@ +class MigrateIssuesToGhostUser < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + DOWNTIME = false + + disable_ddl_transaction! + + class User < ActiveRecord::Base + self.table_name = 'users' + end + + class Issue < ActiveRecord::Base + self.table_name = 'issues' + + include ::EachBatch + end + + def reset_column_in_migration_models + ActiveRecord::Base.clear_cache! + + ::User.reset_column_information + end + + def up + reset_column_in_migration_models + + # we use the model method because rewriting it is too complicated and would require copying multiple methods + ghost_id = ::User.ghost.id + + Issue.where('NOT EXISTS (?)', User.unscoped.select(1).where('issues.author_id = users.id')).each_batch do |relation| + relation.update_all(author_id: ghost_id) + end + end + + def down + end +end diff --git a/db/migrate/20170901071411_add_foreign_key_to_issue_author.rb b/db/migrate/20170901071411_add_foreign_key_to_issue_author.rb new file mode 100644 index 00000000000..ab6e9fb565a --- /dev/null +++ b/db/migrate/20170901071411_add_foreign_key_to_issue_author.rb @@ -0,0 +1,14 @@ +class AddForeignKeyToIssueAuthor < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + disable_ddl_transaction! + + def up + add_concurrent_foreign_key(:issues, :users, column: :author_id, on_delete: :nullify) + end + + def down + remove_foreign_key(:issues, column: :author_id) + end +end diff --git a/db/schema.rb b/db/schema.rb index a5f867df9ae..9b45861cde7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170824162758) do +ActiveRecord::Schema.define(version: 20170901071411) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1707,6 +1707,7 @@ ActiveRecord::Schema.define(version: 20170824162758) do add_foreign_key "issue_assignees", "users", name: "fk_5e0c8d9154", on_delete: :cascade add_foreign_key "issue_metrics", "issues", on_delete: :cascade add_foreign_key "issues", "projects", name: "fk_899c8f3231", on_delete: :cascade + add_foreign_key "issues", "users", column: "author_id", name: "fk_05f1e72feb", on_delete: :cascade add_foreign_key "label_priorities", "labels", on_delete: :cascade add_foreign_key "label_priorities", "projects", on_delete: :cascade add_foreign_key "labels", "namespaces", column: "group_id", on_delete: :cascade diff --git a/spec/migrations/migrate_issues_to_ghost_user_spec.rb b/spec/migrations/migrate_issues_to_ghost_user_spec.rb new file mode 100644 index 00000000000..cfd4021fbac --- /dev/null +++ b/spec/migrations/migrate_issues_to_ghost_user_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' +require Rails.root.join('db', 'migrate', '20170825104051_migrate_issues_to_ghost_user.rb') + +describe MigrateIssuesToGhostUser, :migration do + describe '#up' do + let(:projects) { table(:projects) } + let(:issues) { table(:issues) } + let(:users) { table(:users) } + + before do + projects.create!(name: 'gitlab') + user = users.create(email: 'test@example.com') + issues.create(title: 'Issue 1', author_id: nil, project_id: 1) + issues.create(title: 'Issue 2', author_id: user.id, project_id: 1) + end + + context 'when ghost user exists' do + let!(:ghost) { users.create(ghost: true, email: 'ghost@example.com') } + + it 'does not create a new user' do + expect { schema_migrate_up! }.not_to change { User.count } + end + + it 'migrates issues where author = nil to the ghost user' do + schema_migrate_up! + + expect(issues.first.reload.author_id).to eq(ghost.id) + end + + it 'does not change issues authored by an existing user' do + expect { schema_migrate_up! }.not_to change { issues.second.reload.author_id} + end + end + + context 'when ghost user does not exist' do + it 'creates a new user' do + expect { schema_migrate_up! }.to change { User.count }.by(1) + end + + it 'migrates issues where author = nil to the ghost user' do + schema_migrate_up! + + expect(issues.first.reload.author_id).to eq(User.ghost.id) + end + + it 'does not change issues authored by an existing user' do + expect { schema_migrate_up! }.not_to change { issues.second.reload.author_id} + end + end + end +end From ae9b771797cceee76c18376910519e9e71628acc Mon Sep 17 00:00:00 2001 From: Jarka Kadlecova Date: Tue, 5 Sep 2017 16:25:40 +0200 Subject: [PATCH 19/35] Remove checks if issue.author is present --- app/views/projects/issues/show.html.haml | 3 +-- .../issuable/_close_reopen_button.html.haml | 3 +-- .../_close_reopen_report_toggle.html.haml | 22 +++++++++---------- spec/features/issues/issue_detail_spec.rb | 14 ------------ 4 files changed, 12 insertions(+), 30 deletions(-) diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index fd7ff176c5e..04b4ed95a2d 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -37,8 +37,7 @@ %ul - if can_update_issue %li= link_to 'Edit', edit_project_issue_path(@project, @issue) - / TODO: simplify condition back #36860 - - if @issue.author && current_user != @issue.author + - unless current_user == @issue.author %li= link_to 'Report abuse', new_abuse_report_path(user_id: @issue.author.id, ref_url: issue_url(@issue)) - if can_update_issue %li= link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), class: "btn-close js-btn-issue-action #{issue_button_visibility(@issue, true)}", title: 'Close issue' diff --git a/app/views/shared/issuable/_close_reopen_button.html.haml b/app/views/shared/issuable/_close_reopen_button.html.haml index cb706d80f23..f16bc8dd430 100644 --- a/app/views/shared/issuable/_close_reopen_button.html.haml +++ b/app/views/shared/issuable/_close_reopen_button.html.haml @@ -9,7 +9,6 @@ class: "hidden-xs hidden-sm btn btn-grouped btn-reopen js-btn-issue-action #{issuable_button_visibility(issuable, false)}", title: "Reopen #{display_issuable_type}" - elsif can_update && !is_current_user = render 'shared/issuable/close_reopen_report_toggle', issuable: issuable -- elsif issuable.author - / TODO: change back to else #36860 +- else = link_to 'Report abuse', new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)), class: 'hidden-xs hidden-sm btn btn-grouped btn-close-color', title: 'Report abuse' diff --git a/app/views/shared/issuable/_close_reopen_report_toggle.html.haml b/app/views/shared/issuable/_close_reopen_report_toggle.html.haml index d8144a39b23..a38cd319e3c 100644 --- a/app/views/shared/issuable/_close_reopen_report_toggle.html.haml +++ b/app/views/shared/issuable/_close_reopen_report_toggle.html.haml @@ -37,15 +37,13 @@ %li.divider.droplab-item-ignore - / TODO: remove condition #36860 - - if issuable.author - %li.report-item{ data: { text: 'Report abuse', url: new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)), - button_class: "#{button_class} btn-close-color", toggle_class: "#{toggle_class} btn-close-color", method: '' } } - %button.btn.btn-transparent - = icon('check', class: 'icon') - .description - %strong.title Report abuse - %p.text - Report - = display_issuable_type.pluralize - that are abusive, inappropriate or spam. + %li.report-item{ data: { text: 'Report abuse', url: new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)), + button_class: "#{button_class} btn-close-color", toggle_class: "#{toggle_class} btn-close-color", method: '' } } + %button.btn.btn-transparent + = icon('check', class: 'icon') + .description + %strong.title Report abuse + %p.text + Report + = display_issuable_type.pluralize + that are abusive, inappropriate or spam. diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb index c470cb7c716..28b636f9359 100644 --- a/spec/features/issues/issue_detail_spec.rb +++ b/spec/features/issues/issue_detail_spec.rb @@ -40,18 +40,4 @@ feature 'Issue Detail', :js do end end end - - context 'when authored by a user who is later deleted' do - before do - issue.update_attribute(:author_id, nil) - sign_in(user) - visit project_issue_path(project, issue) - end - - it 'shows the issue' do - page.within('.issuable-details') do - expect(find('h2')).to have_content(issue.title) - end - end - end end From b4248270f8d6893633330dd7ceaf520c1c44083f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Tue, 5 Sep 2017 17:52:30 +0200 Subject: [PATCH 20/35] Cleanup rspec_flaky report files in the update-tests-metadata job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index aa7659d1b41..7ba6f09ab24 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -208,7 +208,7 @@ update-tests-metadata: - '[[ -z ${TESTS_METADATA_S3_BUCKET} ]] || scripts/sync-reports put $TESTS_METADATA_S3_BUCKET $KNAPSACK_RSPEC_SUITE_REPORT_PATH $KNAPSACK_SPINACH_SUITE_REPORT_PATH' - '[[ -z ${TESTS_METADATA_S3_BUCKET} ]] || scripts/sync-reports put $TESTS_METADATA_S3_BUCKET $FLAKY_RSPEC_SUITE_REPORT_PATH' - rm -f knapsack/${CI_PROJECT_NAME}/*_node_*.json - - rm -f rspec_flaky/${CI_PROJECT_NAME}/all_node_*.json + - rm -f rspec_flaky/${CI_PROJECT_NAME}/*_node_*.json flaky-examples-check: <<: *dedicated-runner From 7f012213ad60581fd319aaa0f3c0b5eb0cc4ae61 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 16 Aug 2017 15:05:32 -0700 Subject: [PATCH 21/35] Bump jira-ruby gem to 1.4.1 to fix issues with HTTP proxies Previous versions of jira-ruby gem would generate erroneous URLs when an HTTP proxy were confused via the `http_proxy` environment variables: https://github.com/sumoheavy/jira-ruby/issues/250 Closes gitlab-org/gitlab-ee#3125 --- Gemfile | 2 +- Gemfile.lock | 5 +++-- changelogs/unreleased/sh-bump-jira-gem.yml | 5 +++++ 3 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 changelogs/unreleased/sh-bump-jira-gem.yml diff --git a/Gemfile b/Gemfile index 61c941ae449..5b551005c6e 100644 --- a/Gemfile +++ b/Gemfile @@ -181,7 +181,7 @@ gem 'connection_pool', '~> 2.0' gem 'hipchat', '~> 1.5.0' # JIRA integration -gem 'jira-ruby', '~> 1.1.2' +gem 'jira-ruby', '~> 1.4' # Flowdock integration gem 'gitlab-flowdock-git-hook', '~> 1.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index cba30e856ed..55653e72c24 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -404,8 +404,9 @@ GEM cause json ipaddress (0.8.3) - jira-ruby (1.1.2) + jira-ruby (1.4.1) activesupport + multipart-post oauth (~> 0.5, >= 0.5.0) jquery-atwho-rails (1.3.2) jquery-rails (4.1.1) @@ -1042,7 +1043,7 @@ DEPENDENCIES html2text httparty (~> 0.13.3) influxdb (~> 0.2) - jira-ruby (~> 1.1.2) + jira-ruby (~> 1.4) jquery-atwho-rails (~> 1.3.2) jquery-rails (~> 4.1.0) json-schema (~> 2.6.2) diff --git a/changelogs/unreleased/sh-bump-jira-gem.yml b/changelogs/unreleased/sh-bump-jira-gem.yml new file mode 100644 index 00000000000..d76b688caac --- /dev/null +++ b/changelogs/unreleased/sh-bump-jira-gem.yml @@ -0,0 +1,5 @@ +--- +title: Bump jira-ruby gem to 1.4.1 to fix issues with HTTP proxies +merge_request: +author: +type: fixed From bed08ddacc4db8412dee20b7f4807e4feac75313 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Tue, 5 Sep 2017 17:52:48 +0100 Subject: [PATCH 22/35] Update issue search example to lorem ipsum --- doc/user/search/img/issue_search_by_term.png | Bin 65826 -> 127492 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/user/search/img/issue_search_by_term.png b/doc/user/search/img/issue_search_by_term.png index 66e612c4ea6168ff77d5578e8a312f59e5181103..3cefa3adb8b0df98a46d59d8c3844c1654df1ba2 100644 GIT binary patch literal 127492 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%0D|di;&8Byx(p77 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

6M0*sFD3?)Mb5A6vXC~p9?P@U(*98 zONi4#t}~~EV}-CqV65nym*yJ_@_DCeQAb*yj8Z0@vC>p+NYey(bU$UaMa?B*)7^x| zMVgs|o>rtz0JVs(K#j^(z67fL9t^?LuLq;=rlUeRo0Y2PYr}uYN#_^mA+val6!%;u z?4=tkKed=E?YwWmYwlq!b*I$LZEw)Ba@85F&e@MrJEfb^(`Z&|P=zDhII?Lo`b8Uh zg9ra4EmaR2XS#jnDDWm-qtKXmX32cqwqfzjh!fYr6g4@?HOMf7B>$P>ksw z+cV#($EJ~NXHN_+xoMYM|Ij_(GJ4BT6)OL&fQB^HfS|_H*)r|3A_XrL?+Z?E|2&z5 zUUjfLjjf$3Ylx44*rABS;m&XewJ-tY`i|rl&K<| zAbef{k+yJ`16f^jo7jr^=pmbzBWthR4DH9EG)L^RE)K89Y}r?i*6Bz(N96<)2DYj3 z*BU0i@CUAF07~)MnQ&D}4N>G95#11uqu-efOFW%QCHf4=rS6YP*n2fx=;~vVP5yT> zihmmR$z}Q?@UI1~5BiDS=C5n<*gpty#&))9`cZDr2UYJf#Y?q}ZP#0;lMW(|9DFOV zwk@;vt(xLjGvI{M`!z9@Ag07)V;IL|86Vo7n6W#L;oSGqBn~xYzgJ60NmFqe#!~eF zqso0qO|nhg3NwE})?O%`OxzmT(kQiwd-ZMVc~Iu8cL!0>)Zdu9%3J~~M2#cqJ=(R~ z2mPvvb*LfEFhzwKk+&iamSck1#l$tP&LCgecJfZooR*Gg*a9ES(7mnjN8sf1aYxQ% z!vr+L-f1&r@mA8xR<^S)ntEJE$V?0G`IE!Co(2kTX;-nP9SZV@b1a1b+2p*5vXY>K z2a5vL^22Gv8TyY2QbTAdc1-5aQ*p#QVqs)*i;CB^UfxMnDf0nW;Db1@i))zhXa(d4 zY=mr;|6%6ZK{A=!S~4(^0xKAOxNny4sHFrsNIt4R9MRY;8DI{>Lfa#3&gn?j^gHBe7obL_Ld(|R$pQ)_S9K3-Xv=f z9lFeTewQFy8qGlL&*)pjDiA(qw3Nw_XRTt*3+TSTI;e8kkuTM(p@cPuw7%%@eFJrg zi;MeSX8{{cJD+WQER8*!H|w#R6%>uOt!yc^B6?2REam<>6l3YMG%8no@*!B}S(Of8 zjUzJe{e?PCTJW7(YP12SA zR?i^=mW^4>ir<#~dV5+gGOL`Gab>2#kbWfP0cuyDZNkCjB#~25c z*HUVpThB8DQSWaeSS(H2i_YfpQA7CVOd7{OFP+S+C|NwyupRlxu>7ubcFckjKeGLF zw+NU+_wY~Uy4sza_?k4H8kI1xmWrr8)K^s6;z8%54OXz2Z=?aP$|-50Cp$Z5oA_4g zY9(>^I;*e#Vpn10y7E_h3bV#wen@rs;d-Jf6;O%f?{(EPDBTNAjLfJCgEJ(E&dPeO z!(c0S>T~j`T?3QVWglp|{8{|&3$M}?Q0P^U6@IW$pk`h1l?9{5Q43dK}2ICg%s!+=WqsuurmKdMC zua}Voir1GPUf!ns3;_Q5@~)!foqaH+A}78%8s-3n-*}L#c9<=yE-Jodqgtaff*xiS z_Iv8JyVsv}JG7O>glWx#eP$K?tJVhYKZ}P^(tqJtd^cSuj`gkH2vGfJ#bxyPuEE2( z<}T=UdyvK)w}VL=>qUA}4OPQ*h9+1v@NYiX3Xhtx{+I5S*)iVR? zcH*s9wc9pC_x;p^x4xW-P%rxtaG5FU6g!lwP-e{ye(9AxIlvoDJlJo8oz06Y+wE~4 z5o>KX^jB7)e|<{MQ=n5nPd^E4vR288_;|pk~qW>b4b-p2e-a#ToCh6vwf_? zu%N+Dv!vf2Z^>|bDc8EH;+%8S;J|XGKO;A!Xw&45_4I{w=B94tCdKHRYhMm?Yctbs zOK3ASp28$Qw~(VkdX@8pCvBqj$Aj#hg07{@r6$iT9ko5yOb}F9$e_$`q~}W}z~I&^ zMeOG4JbA`lxW%B=CW8~FCRr%5FLX?Nx{z2k;Uv0c#A4Xp|E%bHtA`-z^UD2++Y1$y zm-qF?jhGO^%rD!0Sf!BYcPw4|lA+M5;azSanuz0u_GPie%( z$Q9zfK2xDj7Bwd;Av*pERMEjB<=xGSl|naiIo=i+2b$vEQ-e6ZaNln#$+&KPkdP?AdYRJw z$vD~`K1Fgeb*HiWm@f*>e^U6>)OKtYRjsax0#ulnc5gL zGcz+YGcz;e^_i(#^?kQyGIP)GuC1-DrIwbYM^e6&^WB_^&Bxor&ZoB@@P|c1#=;63 z92C{`xSPY~_2kOF^V;qIHNoXKE=_EH@*X2@cDH>o7HB3J+N4jXcJY?dqV!RqN8Xo* z-sroUi6iz8LmmslU~}^X+vekR#9>MH);nk&ro$AXwC9cM(mjmXseyCKHSpLd#P>yj zY&-D5nyDqty4IbaB^#OioPa_-F0#S7X9M`+s$GjWE~9Y;*#w2nzjhZ8%X5^kM=ZTj z*CVF)NEe}ta9_`TOoPgDj}ZiKxolX4VKjuH7pKn)H&weir?UT2T#;I~3t|jimcb^e zIQFxVy2*?0SBx8qs7a?%-D$Rw`DTb1y@a_F^orGa(+Qa^=T~r=eKo-~Y5hD+Wg*!%8#6Wq z*cZZl?gJkD8#ddVqTx@*&*exboYGvpbzv`T7%XhnGU-U4g_suM*&Y{6xvI66iiejQ zLxzDcP2QuH_m##52R%v6xLhXBUb|m(q~4CtOc8vm%(w1SJ>71<90f3z02AJpxF@$# zf*-wp7~BsyFpC0nCqV6!hKri8B^dg!zbM}ipD^LfoE-3N5tuR(66mfq7u>P(#K~P( z!WrOucvQ!F*gZUAc=%{`-8vpJGZmtr`wFA>V}HcNc;b$i=7cz5Q>oksjmyLFAy-&O z9j~7Ppu-;}M&SnwkUG%aj(~)OBsU{$zEK-}c6~ikMcW0Eq5YBM{r#asBH{gP%$yktfC1EVgNns=5$5@*R#&N+Y-Qh81rFp{t@hKY) zU|A4a8xAb1o)n!BN&oz}i+}#(m(6S9%ew`D#CidgkS5>F(*}sojFM}E&Bkq&@%a@x zq{VUj*Mml7(mT!v`jcSq?^T4GO|#ABODBBZhmWo;&j<*Bg7waWvX}-7+)w)J)w$Vr zw1p&FlsR@dKd7(W(ZquE?8aF1nw_7+!zf?3ki7Wx^hp1e0@l4foJ!Q>q<0KxYu})E zEYc+WJEQ-Nsc1xi2`+2Krdaki!53V{A7GFAmB-Xu;tQm=zO&mha&S|8!UHj;9Rm|d zio5)vC02fhmf<|XWOQa;#@dSiFNFGE@mdSv|4>?3NG0ZsG3P>nO8SmA)W?xlKtI`MDgSeFk>A4zOsZ)}N>?vG3tEO>l#V{k9olC{l^7G-Ff{2B>b#eQ}K)$Vi$WXb0RNNv4^^=V=iAVJGhtGEje@D(F31pFTi{?+LJU+zG&7=nX?pOkv2_gPn{(Zg(e2M@(m$VW0-zD++ z0aw^MVE^Xh2*_Y`hq&Jey5{~jBS2CzcB;rnE`LW}LP z*?wKmm;0Ro;nL{kY4d=q4yreg(rkSp)L&0nMmvlJ@E58QtB#v+i*W1R7QS5whoSF( z(DQ>G99QaUR5{^iK~Zuh0G~$vB`S$E_eNqq4}^X|dynOg+vg%0)ON9@r5|QV+2-(V zxb<~|qj6BbhcBgEP&DhdX_;WH29VR@5OnSJF7`&*xD3H#_xJOka@aNzbu#DQr7jY( zZ!?oPSNR0b(u{4|vQxvwG+=LzhH5TO~AU?T}tE@38cdrn}YpcH+(6 za%j=ROvZ#3AnmnLeh!$PUNY3R&H8s~ z`Y~9!CLU;{j?%l4_<-&YPi(a!phh!QE zq*o>Oy_Z$M3VJ}}7I*IIh*RQI>L1?Pt~ zC%MmEhhCrE9@7qqBLN2)UW6lw3?laS_I&B@p~f7I7)`XT>F>|g;lp3yWyvPMf2MZ0 z5G6=T#f2J|krFSw&haofk!ik7a2I-du9LeO9ZHy*|1C(r1$no8jgb0&$Oo~F7K@Cx zJ8@P1iB_&IBR~<O1REyGd?s0+ZSt+>_g{U$iZmDw&0!(8(> zqOd~%nVVEbAZixeraEr!9w9a!^U6tb@)nEiP%m$1`>hAE0D{O$t~U0B*e~YhdX7*| zjtG67_6AgschXq6QEfr} z`X`cz|*6ZkzaBB44H_ch^P6ucF%J7u_`h zVTQOJ1ZPajA4jgLZkuJpcP^xNtaB%&lX}jF8_24$@-a4gzQPq*=s3dO$6niHg@1yB zJG76{CjJ;I5|rir?Dee**(YDh$ZXhfEJkD=Xxq_1xOhCV7|dk{&gOjY&6c|54%~jO zQr5zC(0;)VyOMt(jGW=-ua&N~Vj5cuN8f3p-5=jj54P!z|59HUk$C*AabTLeo0Zk| z*Trw%)*EdC^;D+xqHj?{zUV7s!>dyXYiHIB2jMevLB+VZUQE9wnJRLQ+Kp3mZX%_| z-tIY?H$wL`c5;mD`WNRrBbae3z#Hn<%9f1AjBobDn%_B?AK0OBCtPH9KG^vqu(J3u z7xVQ`b`Zw7?)s<_cBH72Z1mUwY_?GEuj9yv=KWcu*HjSZPG!H-g-Z=W#kx-crGmE# zQJJ@KkKJF6k(Rc^GV)%sAIC4@mL_4oqAlN^Ubnjikac0X@q2Uaw_au?cWgR2j^b53 zLF!qfm+sWaUb-{OtK{ZvX0lpL)w9NYxSw~T3LD?QhlNk47LMUv5DcL17H8h%;&QbovN}(3z3^%Nr$8j?0-dcd6yjSk9_oM4;>7CG1#o{-!gkB=^+EWObcL-_6$1R5DJ0wzQtP zj#aB9s zo~33rTjVsST~=s7ia&tCD%{vu4Ff7YMB){LbRJgHC;lKy;bkV$n~D9Fu&Y68!4VTX z#wt0uh!`fri~X4otu+&v2)IThiDBQ1TykXqa91v-(527h@_7_sB2t=E7Kw1D6X*UQ z2+|qxAVKJUN1py!0c8rP18%3z1^n?`%e(J;%Ilm6irr#?YEMti~T6pAEo|HcCnN{mX z3XkSVae8!}QMqk3^cpQVjrC>36^(eYN9IkI| zL`NUABOZ?9!A`59v>uIbDl9?McE8N~h~oM%vQB!?h4a{WJq1j-ecfv@VYaOU(rfX{ z4Z37TLuf&+FFp{!?1PW2E&DGwL$S5nE2y)+g$V;~Y2*hq{9rl<;TOfASFr{QlvCr+ ztH|oVF(}qu%x8z(AN0Fa>*4TQdFqo~CG!yn-sDiY^OG~o^D~< zTEp#q7?7 z_w(N}hlm!mN8}{tARyt|Nwv4fsfp=5Y2l72dNp7ZU4@8_eY_o%W{wJaVh$DyG>9129~eGHRIoV9KV@~ z6BEt{H|-t^MT`keZF3K9>|;covCn$13Kd-&yzBq%Vw*_`A$cq@M==IJ^qwz?VjI4J z%9R$%TLZ_gC}Kyg%)KQ$U%ZDuT!3uO-418xRR@K`C|=5HosVcnv{6*f{j7yKoiE5) z57BE%s(DAQ`jM)Ihk?zb5S1ol-V1(`NJ<^P2fpN8KbNi$RC!z^Uo>{@@G()Z*Smc+ zQMq09^u_FKyaQct&hFT?)k`}yhr?2FK@6-s2*u_#{%%oC>|~D^@t{hOto@`j5CG-W zFL(F)Sx3SNPI7l#i6rdI@%n%}Ntl2`c3>u4jXX2(+$QUIW|L9Wd8;{}i+{i+XR3f577YWGxdHdn=jlJ1T$uiLUh zGOJM3MJF8Z3dQGYEhDc(mXRVpkEJw0&WlaU{>XR@`<5Wc#q1YRxk@)lKA^|%i+xFW zN8WZq=C0?!P*cwm7_)V`5vJyid&lv@d4`DSaxaDmnxJxn9W#x}oivst6JXQ$;4lwX zs7i%EQDas}j-V3KidPL>9r^{1G;z0R#P4?9kMDs zg2&>147l>vMBgwR@4Newm_HrLV)H`7qvCAtPpuB9Gq((ZE4hp80+uS-Hwvk-9&lc` ztoF04=H)rX{KBP~bFD~5<_`WLXxogTx>nH)uHO~^P`lJ~MBZ)ZTFGpqS<*9gh zoU_$GDK3~waaDFy5;y|uh)?zDz+X zqd6gy&>~WTPhIk;##1Ob1XN6>7JO65eT%M*N*OZj5<*)S^~3`JrulX6pbOP+7N1=# z+1N4^iX;aI8u6OTe8&@TRcBrJQcISnEeu#G>a|7Q)67qq4|2JrmRIy~FR*N>w-Rz) z9axlHrd;~v(VFD6uF0+!PUUj!v)Jg|nqlDc$&P_7Tu+7gB_1p4 zp|t^K`zFgcbPbSpL>hroAMIk|lh4ZFsbq&BBbyl_EK(<_GJA_5OU`SHYm5qRRu^Np z>nV2wPN@(1Z9{s&sbWY`beXX=HuaE;+=ffXMTa zxc#x4b`)*tGec!gwU4^c%MzBBmS${ag;g+2%;gH}vk>?dZ}T4Z;ndMh)t7!igY5n_ z&#HdZ9kuSHfZEaFixV2=2NjmKsSQXVERO~;cANy|C`6Vk}8nzY9E@rmh; zai)HSj|TxA4IlKGN(-W7PhnsmvX}m}{@%C0ro-PPJ7;LZnv4k^%Ab;wIiL(x@QT-$ z{XoNpfFo)24;5H>qLeZ9T!`Zn8N^Q%Q_ z(D}@n8;8A`KrKriTlrW~?1jjFQgZ%z+BS-w=MPB??b+Zax}6$ED?^I%s1{Hz#CPWc za|T3wllx@T&*95x4SM&gu~{ZjGNT5e5&&;=SxaPNpeP2>e5XXE#^6>69UJj0O>rnR?1BHoSfB%GJE$fwCZQqg z+D&dC(acSBGXtEG*5bGoKd$%@)!gP5$IN-H?mfzW6V1Kls%dh}Co#jxbdH$0)KIS` zrx~~+2(#Nw{nJqZ@!HUUB#_@A8$^rQLHv7BF5GhP||cH`j{JUo#q zfK{>eHBknXN~rQ86~H)7#F7s_LQlpJUwOONnr5L(!5@w#Sjvzl`)%wfR_R{OIykjw zTibM-uDR*R%i73Wp@$%jyv;bT7aLWQALN1n$km9&_d#_%#zgr*Gz^B)frN!fT1MN> z5{SF>__qaILB_zG!R?y6fotwY1A?KQl)0rWWDOFz((|oHNC=p)=?gHhdB~AQk*rRLV zgX+1b_j+QmX`>DaC*1>IvMcsDa6NG86*((gCPhcd@sK@QpfEB<4vvlHtTKLJ+EI&f z6)wqyx;zV<&u=Ld;5FkaA-K#PLAxVKi`T-WmS?kKg!gLN(qPdzmiC2->^|xI0J*wc zL`%ROD741t>}o5I)3(L%S&Fqq1+Opqm#)l0zt7XmLOxA95|qdjAp{w1C&X0GS-MX< z>bD5o>!NR$6I-clQ%W-+fQ3{iNT%QkjFKPANstsvE?jv8 zExX&K*p*&}3%YDX-{0b?LYjft=)@~9-FhP#O_TSg=*aTco*Rm=Ma2z3wF`keecA() z)Yw6zC}t*U&_7m~$Pcph4Q=|Jkd2Y;3@3WO3>tQE0;{U3 zYTQfEh@&fzPLth35auNqAny`Ze`ZnCL;l7aSu*buQB_yd9sCdMJ5-MrGI+#<}qjn@# zI|ES$j~FGgpC(adOB|B3yAw`euv|wnkYOWwW3(K{nV|Qywp7`#szYeV4+g8LTs|h^ z+ch0+j+$00E$zjC&d}Q(=MU{!2lIzoIZ23Mu)mSo?yAJ?SKO|}-N4-4y>3--L3O{X zUi^unI&TP(^cCsOk;3=Jy|aa>!d&rhG633`Up|iNIEI00wRe;fRY2)bP`8>|sPNbZ zBSCFmb~Bh!SLq(!;E?avsveEfD2Y6B;3v6k*dQ6U3gCY zpWpzOMvNuJfmSh7jgu4UXSKGBHf;b54(kOcOVoPoGVConE~IEojHm9nje z3O!>w2qRaSdqnp9ow-WwM`0>4f~hva1j0Ks!w6>LED4yqMaiM_!mm;@8-WypztxRb z`r_dWW)RtcToCv1gUL1w77?x~UongQ*eSlS!xfrOi-3ww0rhd2q(QIe*+I4WhsFYB#ES$IV0}GRm}VwE`?b#OvNIJy30r_3 zKLDh)0j5X(Vr#2QbIp*)0Cs1lUSzTX%`p@<3tueygIGi3A{~QLaR|s&>SoSvc=YU} zI0V8I%n~2(!CfwJTB}F^K0{bYv=!@H3`Md!fqrTbSW}omT_?_{F4cZ9gS(DlRDT1Z zl5|)=r_?RoZJpmUdoa?I20RV}_DF@E(wV1v{^^r@4fTyry14i{aeD9^>FKRT4S z+^l;hzB?vMgd8AKyYL~qC2{t`W-(AQFdGAkW=1>*+4jez{uLz}<&OuR#VEy`=4RYHa*Y@_KlK&g zu{~`DfT~2ZCpIn~rKj}_Tq)Vk9 zP|R+XCMdBjeJtfE94~uqnPp66Gf;16Yc)B;4VsuyE@~%zXCVs|_{oM?ld;LDS$?}$dObm3U?oOq#k1%@v?mZ+_ zOrvR!p^1^-7#<-X$Va}D>s{EvWA?6YW4UOnTHP z8~Yz{C9l{IM2V*j%LIl_4hNpBBP$L2zoh2jx8)$#n}y4-l4|)Cm33-v<6k zX4Gv6Qng|&}# zs9!RCz$OLIRfY0&&rxflfc{w^73at1#-iv&GXw@^Vs~&@ZyJZDFWDi4*uCWbQ)itD z%MJT*a{pJVQ|DD^LtLG~$nWMv<6eL9`(Wp2ZxzWI8s_5IRgki)QVWwM_Y(GUt4aX8?1Tu zH&SvCeEm3+yo?7%CJ0E{Q0R@LQ3jNsazmt@moCZTt`s5 z;);IF?a^l_2>RJ(=eGCDwE*^{uEBi$N$kNn^T36nfcVBNJEfOV@hQ3^(Pl4sQ;w z6e)RAVajd49~0nkEbQ*~(&92aclS8REeOadn)zZymK1%*aGdD;7V`jhp|xw;Anr0q z-cW|t)8zF+!?qYo-l3IUVsWxXLiZ;lZ1h%9vZcTqf_=~Uv5?sxW+X!SYFoJVQHm5N z;3aIZM1h1(Fb5d}1M*~%uGF&~Tg{d_h;|F+Dxd#)B6M(Onu`n|2u40^g%cl1K9NYu ztIaYAH;`EDQ@CYAW*yR#G*z9!pfgHE+jfN#)X3JHZ!@XXWR_+Q(P)A*Jfci$RvJH? zRRLceMb}_VNeU=@XOY_Ey#8pd52+uZBA@vBqz~a76GJNAltUuGv$2C{M zDU5;2f;ZaAbitwQ7kK45b#sKBCU0lL3{;P1Gaz()lit&CY2^P^?y5iu?Z}-Q8X{k0 z)r&2Tt{1$l7b4Nys?--Jj1xfh3HKCqAsqR*uthyI=n@AP#T}@}Kc(3yM#-J)S+eZR zjLPZ73|&4$6Nw^RD?t^G#1Hu_JyEeNFV{M`lP@zM2b3-ydjL=P!5Lg?*S6b1%7Avd z-Q18D{tv>bYM0}K@^{IsNF7w2^tcaX61+{BzoM_&nZar?*+{t`0gsmB$_t{YfLbau zGQu&}I4M%XE32TVew@kxb=vER$)l{b3S*Iy84Kg5R>-k|WD^C!yTeFoEBfjJ!-2Wl zxGhvpFXIE8%%=wu;)h@X=DT2xgB-7Q4Xyrl5EAsBz<%9wAPjx+m3H=AfGg zecSJhJTtQRlyk(xfh$bwDa!^G2qm054AK}9G05`dSt%YrMKZh;Eh`}Kc2*^br9;ne!j2bq35^+#|bWA4X2ZkzO+R~sQ zbW2ioPl)1XQCnS-W_dm(?I^etKL;g9tk+PCyq{{aK=xT%bn33O~z(Q%B7p9bWjl|I<;cIE;Ig&ZN0< zVu8dtv*KMKKp#fwr%PB&By#bt{D$YOx>9w?dO6&9w6|MbIX5##O^or+qeEf9vY{fO z9dQ@mTR7ouT|PG8vemj=C^W8L$kJL99`joFo({}`ljd-%TSDT8BhF{daa?#bhINLg+5Z;FG^nl1mvd=vEZnshTcvE{yjxQ9kZ@C_dk)9x@XRKA+f8y@FPLFk> zi22;{?*F`PSo^yFxj-xj<&C>J(*|`jqx1~oO!;QuCqD1qtO?oc%-!MZsu=!EoK~|< z{KG}57PeVw!S}CLwO`^o6R2=RF}eWyd!Yg29Rl7uAP zjmP-yYx5J@??_b8+J1jmSw6K0azFks!Lg~Ub)`-a)*6e5V<0ux^64mh=X!A04g#r+ z$gW79l#t;cCkm3T9%H=_M+B;8%r`u2hgsh~1n<9TTn@fRN5s%`$jr{XRy~yk1Pw3L zu7;kbV3(T`**?c8HCLclx5a=97+0U)1GZg=)&TJwX*yNXd5J!}OC>8eDV z%Q?ray1t-#4+foWc$OB^?G66m9a|uul4=lslm9W`s0WIU6w1-AdmH)QB|-4Vr&c$w zFsA*Mi%sHWVX`v%7scC2_$I4IwXTABla|!$f#wKeC)j+&C(8v0Q?0pdJXKgSZ6^z7rEM`^X$vx76^UYM@EhN z=)^m_J3P3Fg-3K4yLYC?JZIlWUW`rgmpDF#^KFc<{tW&f=N)VlB3p7T0E9nBTMuN{ z@vBR+0zt0q15r=A?RdJsNiGa!CZo_NeH;23G>CfPmvC0xMP6w`W=R?8M@sA6P#f)X(Z{1fg+#=&_6 zRm|T0w2wEYMg##(N%CMc#PkqwIoWas+(uFqZ$863D8zHT=O6L_c9;F>_W(vm{1x0j z$qM0H3QpZ0)K^H72eT2#I4p$n&4?lgY+=J*Odxd;pc()|LZ_Asj>CEYRp(?G{z2?1 z?{V<)nm$hnb>OIc35h6VRHr>Pgk2!l#B+>PkRk#{>p$X{2YvhPP8`WbTb?^&ArBIb zFbhR?p})>cXmHYdTTc$tq`_J+1N&gBFja2;IiJEV`0(@TN06e)a1jCz^F!c>?l^Ys z`?{HD?cHyb$9QcdUy@AX6E)k|k2E^ zUUZ$L^^P%b?Z9Bi0}YX4!D=uCwbXri@q7TgUn-fp%xb+$rr>Aek2s`F-CYyg;Zc*} ziFY5Ev*}9J6oaL^9r3=LAXA^xvGTs*ujr&SMSr4tUV>L82~j@;N>IZQ-iD6)V^x(d zH4Xkr_cN*8(|_#IzulucPonG3XzNS%CkgHsEQHOv0k-l&g*3630Lkbj}@M)Bzj+^I1 zrHNv%+=Z@wVD5w9ro7|(Q8=`o$nO=Ux#c>G%QDJWbzYJ*AK39G>mc)n0!xr__Y6Q= zq2K?|NoH-bZ0U1f?yr5(qfl(p(uTh~G>T^bIs9mW>6eS&_ctHOhXp|*m9;S3Jcx*0 zzGZCdF<*LqJDU~yJ&>x8LvH0ak3+cQ(C6kII1b*$GAz44rGrTvC^;V?T)ILru?V(r zRyK3GXDluRorB_7HoYQ`8&~C+$SKR?#=#*f6U)y)(EL_xvYw z;i;XHT)UfIuF{qiO*SZQe5$32^-{N;GzoeVPXR>2q;DB_w+iNzIO2=^u@2}*4l;Ev z@Yv>><1SI9ioeQw8AEK6t@SV*92#++InuI*Yn{aJ&y}Z?y#6r*C}RwN=3y#n z23Z2v>ehIV<^ndS#1;bRNO*|T%iRu!`5K$B;Zp=y_?weFHaNoF?O3(l*AAwYhXk_w z74F!`Jnz*RU$8p(_75*LmhBuk;Q5BOo&5W>l{cjf*c` z`)ABs3fC;BxMH~a9fu7L(br?6JZ>e42^g@lwzBBRUhMJ8 zL>zUOCs<8tkXkE+^+3t<0h=_A2>z!7v=yO>UTWEmrO;tj7cZY>>PZS1fY9+&=rD-n z2)dSCYs#!7hDThXFnRKaJz+6?)GYv1g+M9W^udHg#)!*jX487ch6tw=Uzi zL!t~D;iLdht+z)9*u+|b!hb#5RaW;>#jiemG$osQ$P-LeqH|R`qJY4TxA?j4O193$ zJOFuLOsl>|5XEBKl`ds^ZdI`2>E~0uag!wXCpy&jv6(~x-B^u)rQOt$HHy_?sb*{@ zDIz<|b)E0!9DrJ-vm5ptW*+aJHUb>*0u%0b-I+1QF5GH@NY;m9(RfAj zVLl}l$GpybZpo9mFGQnX^o+@y9zjnumB2P-73kzs%kW{J=SpZA1!gZ5{1%NGUbB@~p&Jgak7rQ8=6eh&>0B{CDbRl@u|%@RPGy|%~^@LS|fsmuBlQCWz$ zE{~|wL&jD%2J|wc4&WTB^m)kWErOTTZ24zgCPj9GPkZ#VR?0vuuOCl|`r2!^x1CfY z#yEPTusPuoJ@g(f3-=yWCR7AU{P9sMC-|2Be1rvZ-E+darkzit{IeCJTG@^bugpG0 z#+B5j5pf;rQRoi1t5j}cCmNx9sdRA6_EG{HPjhIw1(rYJqqgsTo8kbo5$vl6O$9qH zklaKDfnU?0a2Lf2d5n78Xnh8_Dnc5eT7XVDg>vDiEJX%{QduC7VDK^;aJb>dECl>a*e`xt$WvNi40;{Wgo| zOzJz<*{9Jo&A2o!byxfI4`X3(N zV16;tR#I_J2MWbTXp7EAg@|4g8oHg8P1KQ9m&=B z+N&A2Z^yX~Z{`U>z4J4~(kv@+=_`cR__C8L`-QQ~M0R9hbKA>S>W>XoCWmpKWouN#-LQCDH>LS1Jldvm0!lK(Cb~eNau1+V>cC2851}kU{L!{ znLcV|gtN!ZMb4Y+T)Pb8BKg@9KS^)O-MK2MGPa32PeYEu3eWDjsClBUS9!V)_YX@1 zjegy?ua_zgvK%0a#h3opy!957*BR+cx0F+^+oKvY3X^%G%cc_*V`}drdI@{h$s9U` zuiuKrR3ilTW0yo_$!MKP?JB6uDBFwaeGZNYB6Wu?_2&;)F`xll7E7Wv)A8!&j`C#y zNd{Df2&O0d+MLf+=V%je!en1-2&_FAS)1>2WN)d0vU+}{c}$& zNQCHV_G9KL=D3Q6+0A$Arai7tfMup&9|&s!P}SCm@c7XBM@js*Zz9^(7_{zaGK0D|>^8xT!m;HEFR0nIYwRKb6&uLC^bU7kXftQzaX{0vla=n#+Fgp1se#cfXAN_lw~_f4KJv|I!^ zSKGkp3I1U(@Y|J}O*ER$T`lAWax}e>N-r}ijB6@2Cs$IX3=uy`AsmZh*cd4t?~Wo* zsy-%$%|i4h9OC@>;M;bIm{nnu+^6B(DiP__qyj6vgG)Qnk~YM`trK$G>MI!L94ke9 z3DhCyY#U{)87w7xZg+V1=IkZ{>7a>619woTMB$si4lVmCGX`SRMnlF(#K~JCN{F*u!fAp!&@31{85$Ipav-tsVSq{^jzXF-;>rC zqYW1THPof5M-fbAXC)jYtU?($xU3wA4sx}+=L3Fw@TF=9ZSu>B*@RYVsX|CD27JKo=D z96=rLt)$_hVns{Mb(C-(v_Zht$?E;)T{c?O@M!M6Z_ru8>0lX;(1`h7pz=borVW~S zB(Pk3>B$o+cIl5IYLtTqkH5{TQ)GzsB!JvMHrBir)P>zih(VJAgXp!!eayQ=7rF~v z%qrbsIi=~Zir{Fs`}>2DtaNvB_`?cxK`+GAuiHd6)+FMl`3F6YD$KyUV?2v*6NRvw zju4&9%32j;>8yU~-OW0piA%O&3Ku#wdO-^K1cd@FW|Ke4Z{kOLk!&;;98}+&zU=Jhk4wH;q_Dz?i6nQ1*5h{OK_1u7FuU4^sO1EPVI=4}881~gh1atlY z3bU^1Ky=?DHB@(HM`%OBTC+3lirw)QJ|R0hd(U_kHAz;u8TBCp)@2~h!N|L>GJZQu zgKUS+H1_03(?z=~q~X+Mw_L|P@oBPn)oD73#M_<9yHfLha_mxhg*#ZkjbhcuWm$JX z#Tjgst4&P&!mcP7xQScq$Zi|t(QwUkD0%R_S6yGbVzCuF>Ueqtvi?dp4%i1n;ZMhB zePx@?^>biw626);Pp}(%8V{6ghp38rpYKr(#9jBGQHy&iJsjy4A8ZsruB=NKc!iM* z$ga;FSJFKNL#ESpN08ix*XPyijiaX+aHf}jqz^2|#+esfIS!^B;uEL!kBhox0vp24 z(i4{XIQj8ecNOxIhfAlDIr)%y)3=FEqj(2jYXrY1kLj<0dgQ--!CuqHWm}|tx&yL= z2)WAFjL0BSvrq{|6G3a0C4H(JvU)XUL2v8wDsz!81f%Exci8!{q3@T^S$Xao`R>yC zgBy|;oj>m-b0^q=P_4J!Ku?B)#g@tXV905ysaR2uYl+1LtUo6szb=&X-#37$cexTQ zKXt4z)K9u@JR#H8jyT-so+09hDshJvze@kg6sn{Z1fZJajaj(A#E9a<&{x~7X%(Z-j*OzxZcES4>=+hm{@wg3R#hY6XS&aTEz_!@^2->O zZ?hV;z$Ib}C!#+3Qv94rp5#sRqPZ%|Onv7PRw?}~vdm&kLEGZFL)+Eosv;5*$4 z@5e>G>U~}*<&QSAn89UArAPddn7}c*H7%?wjj+Ok7Ty`!ON=PT9wW>(smaA0q^UzZ z!^r1I7bEu~Fm2?P#GgQ|*sMGN*L(fAAbmu8eW?bi(fZvuy~Ot+wBO%9Y~&w^De3A} zj@$Cudf_$*eM3P1E|9Cm)W} zrpA#z1IDs^lE-lRyelJoDX7axJMG=j4G-C)i}%->gAPkAXvKalBO=JV~i z{sYEQ!nW3(bJY{c@jUN~Tm|L4!W<y5p!Mw`O8NhCb)`S)MzDJR}FqA|_>hb#-;I*OAN;6u`E2049#I zVAIem1#!EO9cHxtv{rnGKm(?;s%o5!@C#;5B%34)=@I4j_BhSfK1EH$1^XK+&o^pc ziXBsBpK%ENHehs*CO`x^m0QxF>SW1ENGBjZMb<$I+d0h`pE8FD6PKam)3_=polkqB z@0kgc7JIb~#n%sa7|W|MZ**I|z79OSh0ttS?)tyq$#p%6g!R)e!Bl^_v|@PZKpZU| zo{}uk|7w&jNZW{y&E~n91o;0_?@!OcP4^t<=!R>&SS*?LfUp^BbUEb@LEa~-*PVYy z-NFwWp8ncwB<>4$=}gvPX?z3v=yE`DpwrU$y3Y&qoe9(F0!O~Z@FYWD31QHen&UJ@ znli~{R{jbx(hozvbH0aH)MJ%`Ryq%{uHNB_#p2z3I7fJ$N(@n`wmvF$hT+<#_x+M; zILWU@=Xswv#x6j=`yQuGhBq_dnwti9aRKL-cP!>HOU!rEl|>A)Kk|QKO-XaBJfYVH zBhY`HtfT7p%tgeXEkatus5XtA?;f<-GPAS*EEzG=7dX=Fgg(aa*HHG!D0l*#u%w{r zQOVYdqlDYYX6&<^6&2a8bvs5E9=6NCVo%7ED6@3;npA5o1`{zi6`s>*uAuuVW)|I6 ze$uE=F%EmT4y8a8U}}UxpkZQB#`C3y*TG(bpQWg(e^m=m?=QW}*L!a~f?!fWDhtQo z58~alcghAq9MI2(L)3+rPEYd{ONcfTk z1v}?OtvNQd`r#v;aF~lI-{fP*^}a#fLsn2T21+k&oaIVi8ABExT}unw9p+OX6)$14 zq!)pLRo2zOk*W0i$=j+U;I?mwRt|2oNF_i;MjE1e{3i_7LD6lQ&1y|o6uwf=G}v%;9V&;wV159JLm324H;)$Z@| zF1Uzcp!{-Tq4-M1wX8d(rW!4uarpsuB-^)BX_zfA`>{`#20Py6zNca^O*vu?bE?6n zhtYvcb?yA7ZRz67YypS)3y}e~GIZyK*2yB<=&diwM*mE*pK04B8_bYgVmw_2#8UC} zg?oOU6DzWpU0DA$>Sx%FUzLVna$J46IwqC&ViqGxiTmhtjN`b{)o+aC&KZLv;7&y` zN|<|QabM+mnerlKV|W7=`ldWOZ~YlzO0a&$F2yc|Jz=gOW&-`r?BYnQFgxjd8RgWC z_;V{vXxBVWyOGt}j%faS*SW{Q0>UH|D`am*5qM%VwVQ5WCWnbfSHRM=zSe#D`{*I< zSh9I%(UnxZnu7|>p4#hFH%jsm^CD3mUS|>}iJv2-WBxMdr3%Wa7fKZ8@&Vw(Q1L-v zUCdG)T8XB%1AGMWP^(rQ-&whIj^3H6l)J?L!i}AhmzR*;d{n7H7muvb_wfwoW)G%t z@8iW6DAhi>53omu!_8Iqb#ZNNLO3kOk1mCg0F{7AFH9r|@txx;a<8;#Ddlzt#Wt{= z}pwRCcbBge1mZ+rPNCfIHkzAueu zqdK6sGJz6T@Uo_-6oK})TqAE@23!qAd}C|Dn>ggl*QWjTmJ406`|$SF&x6aXTt>`3 zBHI&S!UqLx6yKzPn%!_EN4druk!v}rG(Pf6_#nYYf77mVL!0lZL60=;Y38kLhCtJS z&r}Z`+79gvabGAmwk;n3sjRmt5F;NmTABCv?Qhd!SzvAqE&RA~V=qY30zf<<2dmaVVj0>-H59yA4UQ zolbzth6|m4LK@FlPcC^>Pk}TYZZJA= z5Ia919wUKxD3_m{%yDnP0P@6J1~H46maPL;S?JAIPss-{8hqKEs~Ec?{3a{&05jSWMaJ;^Q*7mixR2)gqcI<5)Ua!*0SPNl zUq?$Xxmy;CANYx^e~ZE+&#`Rn5T?SiFL14A&qdJrF+~yXZ}wVT3NiyfmDbh99pgGS zaAYYq-SL57`8XhrEq`yu;^)G>zTExMPD_4nM@5uVPaoQo>8^G?8cfgn_WX%khZ?p+ z6;70Fssp|G*szGGJ6Pw@5*IV}*m@ZC@XeAk1>dg%>M|rvERdp_%PPf}wroB{Mu~48 zug4MF-Yr6SO>Nw=`wd{|q|fV}1WQuNvJhVLw*@}#CP7&E`wlssm!c&>ba5YPrQOTF zKUWQ0J@YPTv5aWLFV&=3?&ciK_@V#iSi1d2C*`KM z@^G)S#5SG*{-~=47%%4j?1#D`aJrV1>SJp2gJuaAaEVK-?ELm5UMOUC&N{_3Q(~$D zNFF)uu=!B@?-vyU|T3A#h-TYO44fv{G*gF4+!dENeRXyw}c+#kZQFd&uF zVS>rv&T@bas)pZk=JsGlxw5fpccslpgXksa;x+1+z4#>c?z6hK=m*~?l3TNp9 z)2g^54k+lZ?kygvO?HCXFN6kJeDgYPqb}<8d0%e4$*jrKXFKIAk4KA;_G_i<#3T>I z`W9RjYw$GSGfT>p0Zo0aN*z+?9}$<}jze|c?XSfX3^2mo2$cErwqEYfM5+9mR#(bR zYTU=6qaATuuKr%wE=-@&g2of3I6lGcnx>%eZOamenb3pG%ER;N&P{`#-UWYY%nl>< z)bal8u|65MGDx5bipzbmk`Uc}`HuEnlk+@fcreNbv(U7D1N+@1U?tIW@FudM4bNcm z?xuCu^;h!D%|oMmXO1iIlJvXZEI7GBA)LM>F0?xrAtPVc%HDFfxvMZI>pADsiTqLI z0tiVax0}|ZXCbJ<{E32<$NGDnHU)7GGJ^+0D%)TLYb#^qtVa&Dr!p~{Xm=rl4mEFW z7^$n(!fB>gm5VElEMKzS+eOgxi}uTvU4dO*(CI+@#HGMQry%+A#E){UDQ42BmNx@Je$tQVv?WE4-Av}QGiOBC3M&j~3n_%} z&%3Nzpt#I+@H#WRzDf?N}Y(?Y}PqRR^C-3~b3K#YZ)xM1aSaDKApS(<--W zcTl`{+}8^H7Y9F}6=jPG2}YQ1piG=vdYNEPr0ukVU%gDT<+D~&8!e3 zik^I$FMp$7zn`kpu#2QOgc+2Db~#5+Z%`(E(e6H$=`taG5fpPABfKXsjD|mBGqkJ| z*Pk-$rQ$QxzgXL;`098)Rlw~tb4Eu+L41T0JGJlW9pF80Co@Q9T(-b_c*nkXCiJ4e zf5auUxzOI!v795c`BzOuZPiSnudkx_ZAZn-g{xWL*0}v~F=+jrh~P*az$9+Rr{%3% zVG%LeRo*Q7EZXkJ${Hydzsr3U=Q_2t9^np6Re|<~A}vFjZ=!^nCflCJC+NZmD}wSk*W^$gc1CRGn?q+B7=br_hzWPV4~o)s4IU) zvRp)C-*^x0W^c7vH8gn#QBBys^>~U0Rtv7;8BMa@znup4LWKF_0FCJ_jAPa-E)zK> z`s~5YPK(iNLqAqaw^n$z@3X*;dmTf@bi|!8x($7K!UEV;ipb9DvM!ZnuFkV-46_8S zF~F~%G1r$_Tt2nWXD!@MUT$ui`jKUT=XN-u$H8^)zze6hL(nZ4huqGnU8C=Lmj`?+ z&C<9sm$U5cgX=-&{#7X_uZBE)V`)lguFfD|y~=a2Z>4s=QoptEyz+d_>lk08O0`I# zkG`r+rv>o^LEZrnA*%=A!c3+>e=9~&@t zEooSA`w{RJ1)zdyl+eB{|ER$>@Y>mmtGJ;W)lPXqXu;-DB#S0{#KgbZt$$fE0{QIC zn~pu%o`v)C^KsIhblVD$%;Q~Svz*5)nw9K~%Na|P84{TL?H!*|%d|RF7}kN$EZcdn zoP$dONN%(ff`n_C48I=D&cnMI>YL?K=^M{yNQ2$$D-s?)13PsROBlhRK*>dur^b~l z$udNI%w7by^^c!1uOweu`b~wHtQ+L03UNjFq(d0^3+}a~p-s~)ng;qp!hqJA02VL@ ze92Q+PxzPTviGv((lhpn)OF943vo@pW4m&LDgvi0MQibW=N*;1tCHhhF--M`HkS)F zAiB?q#GNVQXwoUmsxvSKRq%76?ZR}14~bBD1h=DppK5Ee`CZWA#_)4;j-`ILbUE8vVS0+t)n#Tk|TW~Zt>t$LRmC|6e<)x z2d;>Yfz!4ZZrY9)VG?+4PA5FyOi|hCjQ1&L*hKdxBeB zZfx3Pk1d40;j+`VMG(7ANLlJ zYnw>)cJe9s;@+}@>RAPFJ%E#s1IsjN+=5uqI6gY-0Yr=L3j~}ELljkYml>c60Vz2@ zXO}g+P)_ya6y58JD2R5Ofz3zNQ&X>rBGHM(3Js9*H+s z9&ZY*ew>zzXG070TQa!n&GvbuFzd#A$-pU6V!c^jg2Mi>S-(p4!U7^}9U+DCryXu{ zWiXllHu?Uc#2+GFFoDH1BQ(nZkMlAEegFvmgCDl(SLH4q&smQWq99#@=de*R#lDPsb34IU0Ggig zBI<&QeftIWn{Q3e#KgoLZ_f7r;8ZmI^oe>LBy9Kv)Y94-@$;2^E3{#u$noS0~q{Ntnl0)=tM1)nr@x`_@AB>ujBQv9W{9M}r zq&7BQj>oNz66g0oq^vM~h-{=4S9^GwNp$OmW}jUhHo{B2^JlhT@hM(qY(28D&!EQ} z-3}KC4cnR&-rkA|{CnGd_;$=^50V>t(acM0$1q-Dmrk?fc7}V;~Qh3NY;7H_VKBAZfz_wgVk0+8f+gu|T)o&}vx! z(RM8b=!5L}&i=05d0_j1{>VaKmYQ_cOx-|#NuxUek<_SWvAc$!MteNXa03ef19 zcg-u+zSb)bMVB8RoY0&(?OkBaR1LnT{w&}~E_0l}k@R1_rIF`Lm$Q4fLn%KwXVkqM zYdb2M$Hso^Md&yEaaaaBSmZYS?Or+yUrhkofP5d z*v4+x!irAc+|Fn4eH zvWWBlpc!GLF8e2(-zEZT9T86{lDgIgCZxjEk@_(m} n|98awugd>FEzkewDt|{l9}$(Q%};CidY83b%T}S?@ literal 65826 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 IyRQHL0ev1q7XSbN From e10437de407a0782cd49cf5f341517c5b17fdd5e Mon Sep 17 00:00:00 2001 From: Ahmad Sherif Date: Tue, 5 Sep 2017 17:29:45 +0000 Subject: [PATCH 23/35] Migrate Gitlab::Git::Repository#find_branch to Gitaly --- GITALY_SERVER_VERSION | 2 +- Gemfile | 2 +- Gemfile.lock | 4 +-- lib/gitlab/git/repository.rb | 18 +++++++----- lib/gitlab/gitaly_client/ref_service.rb | 14 +++++++++ spec/lib/gitlab/git/repository_spec.rb | 38 ++++++++++++++++--------- 6 files changed, 53 insertions(+), 25 deletions(-) diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 93d4c1ef06f..0f1a7dfc7c4 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -0.36.0 +0.37.0 diff --git a/Gemfile b/Gemfile index 61c941ae449..be3f75df7da 100644 --- a/Gemfile +++ b/Gemfile @@ -397,7 +397,7 @@ group :ed25519 do end # Gitaly GRPC client -gem 'gitaly-proto', '~> 0.31.0', require: 'gitaly' +gem 'gitaly-proto', '~> 0.32.0', require: 'gitaly' gem 'toml-rb', '~> 0.3.15', require: false diff --git a/Gemfile.lock b/Gemfile.lock index cba30e856ed..5761495dddc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -275,7 +275,7 @@ GEM po_to_json (>= 1.0.0) rails (>= 3.2.0) gherkin-ruby (0.3.2) - gitaly-proto (0.31.0) + gitaly-proto (0.32.0) google-protobuf (~> 3.1) grpc (~> 1.0) github-linguist (4.7.6) @@ -1020,7 +1020,7 @@ DEPENDENCIES gettext (~> 3.2.2) gettext_i18n_rails (~> 1.8.0) gettext_i18n_rails_js (~> 1.2.0) - gitaly-proto (~> 0.31.0) + gitaly-proto (~> 0.32.0) github-linguist (~> 4.7.0) gitlab-flowdock-git-hook (~> 1.0.1) gitlab-markup (~> 1.5.1) diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index f7577b02d5d..75d4efc0bc5 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -134,15 +134,19 @@ module Gitlab # This is to work around a bug in libgit2 that causes in-memory refs to # be stale/invalid when packed-refs is changed. # See https://gitlab.com/gitlab-org/gitlab-ce/issues/15392#note_14538333 - # - # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/474 def find_branch(name, force_reload = false) - reload_rugged if force_reload + gitaly_migrate(:find_branch) do |is_enabled| + if is_enabled + gitaly_ref_client.find_branch(name) + else + reload_rugged if force_reload - rugged_ref = rugged.branches[name] - if rugged_ref - target_commit = Gitlab::Git::Commit.find(self, rugged_ref.target) - Gitlab::Git::Branch.new(self, rugged_ref.name, rugged_ref.target, target_commit) + rugged_ref = rugged.branches[name] + if rugged_ref + target_commit = Gitlab::Git::Commit.find(self, rugged_ref.target) + Gitlab::Git::Branch.new(self, rugged_ref.name, rugged_ref.target, target_commit) + end + end end end diff --git a/lib/gitlab/gitaly_client/ref_service.rb b/lib/gitlab/gitaly_client/ref_service.rb index 8c0008c6971..a1a25cf2079 100644 --- a/lib/gitlab/gitaly_client/ref_service.rb +++ b/lib/gitlab/gitaly_client/ref_service.rb @@ -78,6 +78,20 @@ module Gitlab raise ArgumentError, e.message end + def find_branch(branch_name) + request = Gitaly::DeleteBranchRequest.new( + repository: @gitaly_repo, + name: GitalyClient.encode(branch_name) + ) + + response = GitalyClient.call(@repository.storage, :ref_service, :find_branch, request) + branch = response.branch + return unless branch + + target_commit = Gitlab::Git::Commit.decorate(@repository, branch.target_commit) + Gitlab::Git::Branch.new(@repository, encode!(branch.name.dup), branch.target_commit.id, target_commit) + end + private def consume_refs_response(response) diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 4cfb4b7d357..08959e7bc16 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -916,27 +916,37 @@ describe Gitlab::Git::Repository, seed_helper: true do end describe '#find_branch' do - it 'should return a Branch for master' do - branch = repository.find_branch('master') + shared_examples 'finding a branch' do + it 'should return a Branch for master' do + branch = repository.find_branch('master') - expect(branch).to be_a_kind_of(Gitlab::Git::Branch) - expect(branch.name).to eq('master') + expect(branch).to be_a_kind_of(Gitlab::Git::Branch) + expect(branch.name).to eq('master') + end + + it 'should handle non-existent branch' do + branch = repository.find_branch('this-is-garbage') + + expect(branch).to eq(nil) + end end - it 'should handle non-existent branch' do - branch = repository.find_branch('this-is-garbage') - - expect(branch).to eq(nil) + context 'when Gitaly find_branch feature is enabled' do + it_behaves_like 'finding a branch' end - it 'should reload Rugged::Repository and return master' do - expect(Rugged::Repository).to receive(:new).twice.and_call_original + context 'when Gitaly find_branch feature is disabled', skip_gitaly_mock: true do + it_behaves_like 'finding a branch' - repository.find_branch('master') - branch = repository.find_branch('master', force_reload: true) + it 'should reload Rugged::Repository and return master' do + expect(Rugged::Repository).to receive(:new).twice.and_call_original - expect(branch).to be_a_kind_of(Gitlab::Git::Branch) - expect(branch.name).to eq('master') + repository.find_branch('master') + branch = repository.find_branch('master', force_reload: true) + + expect(branch).to be_a_kind_of(Gitlab::Git::Branch) + expect(branch.name).to eq('master') + end end end From abeae9f4e61c4c9da8001fa858441cf64ea0e0d5 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Tue, 5 Sep 2017 15:35:58 -0400 Subject: [PATCH 24/35] Remove GraphQL from future plans. --- doc/api/README.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/doc/api/README.md b/doc/api/README.md index c2a08dcff07..d3b7c9e6ef1 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -59,19 +59,6 @@ following locations: - [V3 to V4](v3_to_v4.md) - [Version](version.md) -## Road to GraphQL - -Going forward, we will start on moving to -[GraphQL](http://graphql.org/learn/best-practices/) and deprecate the use of -controller-specific endpoints. GraphQL has a number of benefits: - -1. We avoid having to maintain two different APIs. -2. Callers of the API can request only what they need. -3. It is versioned by default. - -It will co-exist with the current v4 REST API. If we have a v5 API, this should -be a compatibility layer on top of GraphQL. - ## Basic usage API requests should be prefixed with `api` and the API version. The API version From 9ccc516adee396bd2263558d1a3d8f0f3acda6e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Mon, 4 Sep 2017 19:12:47 -0300 Subject: [PATCH 25/35] Enable all gitaly features in spinach tests --- features/support/gitaly.rb | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 features/support/gitaly.rb diff --git a/features/support/gitaly.rb b/features/support/gitaly.rb new file mode 100644 index 00000000000..3cd5f4ce497 --- /dev/null +++ b/features/support/gitaly.rb @@ -0,0 +1,3 @@ +Spinach.hooks.before_scenario do + allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(true) +end From f58a1bdb0e6a9b308509c7576431cade7d9d65b4 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Tue, 5 Sep 2017 15:49:17 -0400 Subject: [PATCH 26/35] Provide context for people wondering what happened. --- doc/api/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/api/README.md b/doc/api/README.md index d3b7c9e6ef1..357248cdaf1 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -59,6 +59,10 @@ following locations: - [V3 to V4](v3_to_v4.md) - [Version](version.md) +## Road to GraphQL + +After reviewing the GraphQL license, we have changed our plans to move our API to GraphQL. Anything related to the Facebook BSD plus patent license will not be allowed at GitLab. + ## Basic usage API requests should be prefixed with `api` and the API version. The API version From a728e4d7c031e89addea094fdc1b68ce10edd64b Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Tue, 5 Sep 2017 15:51:04 -0400 Subject: [PATCH 27/35] Update wording on change plans. --- doc/api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/README.md b/doc/api/README.md index 357248cdaf1..a947eed2db8 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -61,7 +61,7 @@ following locations: ## Road to GraphQL -After reviewing the GraphQL license, we have changed our plans to move our API to GraphQL. Anything related to the Facebook BSD plus patent license will not be allowed at GitLab. +We have changed our plans to move to GraphQL. After reviewing the GraphQL license, anything related to the Facebook BSD plus patent license will not be allowed at GitLab. ## Basic usage From f76e8c6536a3af4c9051ff056b95c2d7f2dd7b7e Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Thu, 10 Aug 2017 15:13:38 -0500 Subject: [PATCH 28/35] Top navigation updates --- app/assets/stylesheets/framework/header.scss | 13 +- .../stylesheets/framework/variables.scss | 3 +- app/assets/stylesheets/new_nav.scss | 278 +++++++++++++----- app/assets/stylesheets/new_sidebar.scss | 10 +- app/helpers/nav_helper.rb | 10 +- app/views/layouts/header/_default.html.haml | 8 +- app/views/layouts/header/_new.html.haml | 39 ++- app/views/layouts/header/_new_dropdown.haml | 6 +- .../layouts/nav/_new_dashboard.html.haml | 41 ++- app/views/layouts/nav/_new_explore.html.haml | 17 +- app/views/shared/_logo.svg | 2 +- app/views/shared/icons/_caret_down.svg | 1 + app/views/shared/icons/_mr_bold.svg | 3 +- app/views/shared/icons/_plus_square.svg | 1 + app/views/shared/icons/_todo_done.svg | 1 + 15 files changed, 292 insertions(+), 141 deletions(-) create mode 100644 app/views/shared/icons/_caret_down.svg create mode 100644 app/views/shared/icons/_plus_square.svg create mode 100644 app/views/shared/icons/_todo_done.svg diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index 35bd97980e2..b00a2d053e2 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -105,12 +105,11 @@ header { top: -3px; font-size: 10px; } + } + .user-counter { svg { - position: relative; - top: 2px; - height: 17px; - // hack to get SVG to line up with FA icons + height: 16px; width: 23px; fill: currentColor; } @@ -325,12 +324,12 @@ header { li { .badge { position: inherit; - top: -8px; font-weight: $gl-font-weight-normal; - margin-left: -11px; + margin-left: -6px; font-size: 11px; color: $white-light; - padding: 1px 5px 2px; + padding: 0 5px; + line-height: 12px; border-radius: 7px; box-shadow: 0 1px 0 rgba($gl-header-color, .2); diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 01fffa717e9..88b08998dfd 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -177,13 +177,14 @@ $row-hover: $blue-25; $row-hover-border: $blue-100; $progress-color: #c0392b; $header-height: 50px; +$new-navbar-height: 40px; $fixed-layout-width: 1280px; $limited-layout-width: 990px; $limited-layout-width-sm: 790px; $container-text-max-width: 540px; $gl-avatar-size: 40px; $error-exclamation-point: $red-500; -$border-radius-default: 3px; +$border-radius-default: 4px; $settings-icon-size: 18px; $provider-btn-not-active-color: $blue-500; $link-underline-blue: $blue-500; diff --git a/app/assets/stylesheets/new_nav.scss b/app/assets/stylesheets/new_nav.scss index b711bd12c73..4deb7431284 100644 --- a/app/assets/stylesheets/new_nav.scss +++ b/app/assets/stylesheets/new_nav.scss @@ -2,15 +2,21 @@ @import 'framework/tw_bootstrap_variables'; @import "bootstrap/variables"; +.content-wrapper.page-with-new-nav { + margin-top: $new-navbar-height; +} + header.navbar-gitlab-new { color: $white-light; background: linear-gradient(to right, $indigo-900, $indigo-800); border-bottom: 0; + min-height: $new-navbar-height; .header-content { display: -webkit-flex; display: flex; padding-left: 0; + min-height: $new-navbar-height; .title-container { display: -webkit-flex; @@ -38,20 +44,13 @@ header.navbar-gitlab-new { display: -webkit-flex; display: flex; align-items: center; - padding-right: $gl-padding; - padding-left: $gl-padding; - margin-left: -$gl-padding; - - @media (min-width: $screen-sm-min) { - padding-right: $gl-padding; - padding-left: $gl-padding; - } + padding: 2px 8px; + margin: 5px 2px 5px -8px; + border-radius: $border-radius-default; svg { - margin-top: -3px; - @media (min-width: $screen-sm-min) { - margin-right: 10px; + margin-right: 8px; } } @@ -60,7 +59,7 @@ header.navbar-gitlab-new { svg { width: 55px; - height: 15px; + height: 14px; margin: 0; fill: $white-light; } @@ -68,9 +67,7 @@ header.navbar-gitlab-new { &:hover, &:focus { - .logo-text svg { - fill: $tanuki-yellow; - } + background-color: rgba($indigo-200, .2); } } } @@ -90,6 +87,20 @@ header.navbar-gitlab-new { right: 0; } } + + &.menu-expanded { + @media (max-width: $screen-xs-max) { + .title-container, + .header-logo, { + display: none; + } + } + } + } + + .dropdown-bold-header { + color: $gl-text-color-secondary; + font-size: 12px; } .navbar-collapse { @@ -98,14 +109,10 @@ header.navbar-gitlab-new { box-shadow: 0; @media (max-width: $screen-xs-max) { - margin-left: -$gl-padding; + margin-left: -8px; margin-right: -10px; } - .dropdown-bold-header { - color: initial; - } - .nav { > li:not(.hidden-xs) a { @media (max-width: $screen-xs-max) { @@ -119,7 +126,7 @@ header.navbar-gitlab-new { .container-fluid { .navbar-toggle { min-width: 45px; - padding: 6px $gl-padding; + padding: 4px $gl-padding; margin-right: -7px; font-size: 14px; text-align: center; @@ -156,29 +163,88 @@ header.navbar-gitlab-new { } > a { - background: none; will-change: color; + margin: 4px 2px; + padding: 6px 8px; + color: $indigo-200; + height: 32px; + + @media (max-width: $screen-xs-max) { + padding: 0; + } + + svg { + fill: $indigo-200; + } + + &.header-user-dropdown-toggle { + margin-left: 2px; + + .header-user-avatar { + border-color: $indigo-200; + margin-right: 0; + } + } + } + + .header-new-dropdown-toggle { + margin-right: 0; + } + + > a:hover, + > a:focus { + text-decoration: none; + outline: 0; + opacity: 1; + color: $white-light; + + @media (min-width: $screen-sm-min) { + background-color: rgba($indigo-200, .2); + } + + svg { + fill: currentColor; + } &.header-user-dropdown-toggle { .header-user-avatar { - border-color: $indigo-200; + border-color: $white-light; } } + } - &:hover, - &:focus { - color: $white-light; - opacity: 1; + .impersonated-user, + .impersonated-user:hover { + margin-right: 1px; + background-color: $white-light; + border-top-right-radius: 0; + border-bottom-right-radius: 0; - > svg { - fill: $white-light; - } + svg { + fill: $indigo-900; + } + } - &.header-user-dropdown-toggle { - .header-user-avatar { - border-color: $white-light; - } - } + .impersonation-btn, + .impersonation-btn:hover { + background-color: $white-light; + margin-left: 0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + + i { + color: $orange-500; + font-size: 20px; + } + } + + &.active > a, + &.dropdown.open > a { + color: $indigo-900; + background-color: $white-light; + + svg { + fill: currentColor; } } } @@ -188,40 +254,9 @@ header.navbar-gitlab-new { .navbar-sub-nav { display: -webkit-flex; display: flex; - margin-bottom: 0; + margin: 0 0 0 6px; color: $indigo-200; - > li { - > a:hover, - > a:focus { - box-shadow: inset 0 -3px 0 rgba($indigo-200, .4); - text-decoration: none; - outline: 0; - color: $white-light; - } - - &.active > a { - box-shadow: inset 0 -3px 0 $indigo-500; - color: $white-light; - font-weight: $gl-font-weight-bold; - } - - > a { - display: block; - padding: 16px 10px; - font-size: 13px; - color: currentColor; - box-shadow: inset 0 0 0 transparent; - will-change: box-shadow; - transition: box-shadow 0.15s; - - @media (min-width: $screen-sm-min) { - padding: 15px $gl-padding; - font-size: 14px; - } - } - } - .dropdown-chevron { position: relative; top: -1px; @@ -229,16 +264,82 @@ header.navbar-gitlab-new { } } +.navbar-gitlab-new { + .navbar-sub-nav, + .navbar-nav { + > li { + > a:hover, + > a:focus { + text-decoration: none; + outline: 0; + color: $white-light; + background-color: rgba($indigo-200, .2); + + svg { + fill: currentColor; + } + } + + &.active > a, + &.dropdown.open > a { + color: $indigo-900; + background-color: $white-light; + + svg { + fill: currentColor; + } + } + + > a { + display: flex; + align-items: center; + justify-content: center; + padding: 6px 8px; + margin: 4px 2px; + font-size: 12px; + color: currentColor; + border-radius: $border-radius-default; + height: 32px; + font-weight: $gl-font-weight-bold; + + svg { + fill: currentColor; + } + } + + &.line-separator { + border-left: 1px solid rgba($indigo-200, .2); + margin: 8px; + } + } + } +} + +.admin-icon i { + font-size: 18px; +} + +.caret-down { + height: 11px; + width: 11px; + margin-left: 4px; + fill: currentColor; +} + .header-user .dropdown-menu-nav, .header-new .dropdown-menu-nav { margin-top: 4px; } .search { + margin: 4px 8px 0; + form { + height: 32px; border: 0; + border-radius: $border-radius-default; background-color: rgba($indigo-200, .2); - transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s, background-color ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, background-color ease-in-out 0.15s; &:hover { background-color: rgba($indigo-200, .3); @@ -247,31 +348,50 @@ header.navbar-gitlab-new { } &.search-active form { - background-color: rgba($indigo-200, .3); + background-color: $white-light; box-shadow: none; + + .search-input { + color: $gl-text-color; + transition: color ease-in-out 0.15s; + } + + .search-input::placeholder { + color: $gl-text-color-tertiary; + } + + .search-input-wrap { + .search-icon, + .clear-icon { + color: $gl-text-color-tertiary; + transition: color ease-in-out 0.15s; + } + } } .search-input { color: $white-light; background: none; + transition: color ease-in-out 0.15s; } .search-input::placeholder { color: rgba($indigo-200, .8); + transition: color ease-in-out 0.15s; } .location-badge { font-size: 12px; color: $indigo-100; background-color: rgba($indigo-200, .1); - transition: color 0.15s; will-change: color; margin: -4px 4px -4px -4px; line-height: 25px; padding: 4px 8px; border-radius: 2px 0 0 2px; border-right: 1px solid $indigo-800; - height: 34px; + height: 32px; + transition: border-color ease-in-out 0.15s; } .search-input-wrap { @@ -283,8 +403,9 @@ header.navbar-gitlab-new { &.search-active { .location-badge { - color: $white-light; - background-color: rgba($indigo-200, .2); + color: $gl-text-color; + background-color: $nav-badge-bg; + border-color: $border-color; } .search-input-wrap { @@ -458,3 +579,14 @@ header.navbar-gitlab-new { } } } + +.btn-sign-in { + margin-top: 3px; + background-color: $indigo-100; + color: $indigo-900; + font-weight: $gl-font-weight-bold; + + &:hover { + background-color: $white-light; + } +} diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss index f624b130e19..90b0a543c5c 100644 --- a/app/assets/stylesheets/new_sidebar.scss +++ b/app/assets/stylesheets/new_sidebar.scss @@ -26,7 +26,7 @@ $new-sidebar-collapsed-width: 50px; // Override position: absolute .right-sidebar { position: fixed; - height: calc(100% - #{$header-height}); + height: calc(100% - #{$new-navbar-height}); } .issues-bulk-update.right-sidebar.right-sidebar-expanded .issuable-sidebar-header { @@ -93,7 +93,7 @@ $new-sidebar-collapsed-width: 50px; z-index: 400; width: $new-sidebar-width; transition: left $sidebar-transition-duration; - top: $header-height; + top: $new-navbar-height; bottom: 0; left: 0; background-color: $gray-normal; @@ -189,7 +189,7 @@ $new-sidebar-collapsed-width: 50px; } .with-performance-bar .nav-sidebar { - top: $header-height + $performance-bar-height; + top: $new-navbar-height + $performance-bar-height; } .sidebar-sub-level-items { @@ -453,7 +453,7 @@ $new-sidebar-collapsed-width: 50px; // Make issue boards full-height now that sub-nav is gone .boards-list { - height: calc(100vh - #{$header-height}); + height: calc(100vh - #{$new-navbar-height}); @media (min-width: $screen-sm-min) { height: 475px; // Needed for PhantomJS @@ -464,7 +464,7 @@ $new-sidebar-collapsed-width: 50px; } .with-performance-bar .boards-list { - height: calc(100vh - #{$header-height} - #{$performance-bar-height}); + height: calc(100vh - #{$new-navbar-height} - #{$performance-bar-height}); } diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb index b63b3b70903..73b3386fe9c 100644 --- a/app/helpers/nav_helper.rb +++ b/app/helpers/nav_helper.rb @@ -38,7 +38,7 @@ module NavHelper end def layout_nav_class - return [] if show_new_nav? + return 'page-with-new-nav' if show_new_nav? class_names = [] class_names << 'page-with-layout-nav' if defined?(nav) && nav @@ -50,4 +50,12 @@ module NavHelper def nav_control_class "nav-control" if current_user end + + def user_dropdown_class + class_names = [] + class_names << 'header-user-dropdown-toggle' + class_names << 'impersonated-user' if session[:impersonator_id] + + class_names + end end diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 1d875f81041..0d6760e7b8f 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -42,21 +42,21 @@ = link_to sherlock_transactions_path, title: 'Sherlock Transactions', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = icon('tachometer fw') - %li + %li.user-counter = link_to assigned_issues_dashboard_path, title: 'Issues', aria: { label: "Issues" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = custom_icon('issues') - issues_count = assigned_issuables_count(:issues) %span.badge.issues-count{ class: ('hidden' if issues_count.zero?) } = number_with_delimiter(issues_count) - %li + %li.user-counter = link_to assigned_mrs_dashboard_path, title: 'Merge requests', aria: { label: "Merge requests" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = custom_icon('mr_bold') - merge_requests_count = assigned_issuables_count(:merge_requests) %span.badge.merge-requests-count{ class: ('hidden' if merge_requests_count.zero?) } = number_with_delimiter(merge_requests_count) - %li + %li.user-counter = link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, class: 'shortcuts-todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do - = icon('check-circle fw') + = custom_icon('todo_done') %span.badge.todos-count{ class: ('hidden' if todos_pending_count.zero?) } = todos_count_format(todos_pending_count) %li.header-user.dropdown diff --git a/app/views/layouts/header/_new.html.haml b/app/views/layouts/header/_new.html.haml index c84d7053cd6..61b71c091be 100644 --- a/app/views/layouts/header/_new.html.haml +++ b/app/views/layouts/header/_new.html.haml @@ -16,47 +16,35 @@ .navbar-collapse.collapse %ul.nav.navbar-nav + - if current_user + = render 'layouts/header/new_dropdown' %li.hidden-sm.hidden-xs = render 'layouts/search' unless current_controller?(:search) %li.visible-sm-inline-block.visible-xs-inline-block = link_to search_path, title: 'Search', aria: { label: "Search" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = icon('search') - if current_user - - if session[:impersonator_id] - %li.impersonation - = link_to admin_impersonation_path, method: :delete, title: "Stop impersonation", aria: { label: 'Stop impersonation' }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do - = icon('user-secret fw') - - if current_user.admin? - %li - = link_to admin_root_path, title: 'Admin area', aria: { label: "Admin area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do - = icon('wrench fw') - = render 'layouts/header/new_dropdown' - - if Gitlab::Sherlock.enabled? - %li - = link_to sherlock_transactions_path, title: 'Sherlock Transactions', - data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do - = icon('tachometer fw') - %li + %li.user-counter = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'dashboard-shortcuts-issues', aria: { label: "Issues" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = custom_icon('issues') - issues_count = assigned_issuables_count(:issues) %span.badge.issues-count{ class: ('hidden' if issues_count.zero?) } = number_with_delimiter(issues_count) - %li + %li.user-counter = link_to assigned_mrs_dashboard_path, title: 'Merge requests', class: 'dashboard-shortcuts-merge_requests', aria: { label: "Merge requests" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = custom_icon('mr_bold') - merge_requests_count = assigned_issuables_count(:merge_requests) %span.badge.merge-requests-count{ class: ('hidden' if merge_requests_count.zero?) } = number_with_delimiter(merge_requests_count) - %li + %li.user-counter = link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, class: 'shortcuts-todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do - = icon('check-circle fw') + = custom_icon('todo_done') %span.badge.todos-count{ class: ('hidden' if todos_pending_count.zero?) } = todos_count_format(todos_pending_count) %li.header-user.dropdown - = link_to current_user, class: "header-user-dropdown-toggle", data: { toggle: "dropdown" } do - = image_tag avatar_icon(current_user, 26), width: 26, height: 26, class: "header-user-avatar" - = icon('chevron-down') + = link_to current_user, class: user_dropdown_class, data: { toggle: "dropdown" } do + = image_tag avatar_icon(current_user, 23), width: 23, height: 23, class: "header-user-avatar" + = custom_icon('caret_down') .dropdown-menu-nav.dropdown-menu-align-right %ul %li.current-user @@ -68,13 +56,20 @@ = link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username } %li = link_to "Settings", profile_path + - if current_user + %li + = link_to "Help", help_path %li.divider %li = link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link" + - if session[:impersonator_id] + %li.impersonation + = link_to admin_impersonation_path, class: 'impersonation-btn', method: :delete, title: "Stop impersonation", aria: { label: 'Stop impersonation' }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do + = icon('user-secret') - else %li %div - = link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in btn-success' + = link_to "Sign in / Register", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in' %button.navbar-toggle.hidden-sm.hidden-md.hidden-lg{ type: 'button' } %span.sr-only Toggle navigation diff --git a/app/views/layouts/header/_new_dropdown.haml b/app/views/layouts/header/_new_dropdown.haml index 9da739b0974..9cf2739b368 100644 --- a/app/views/layouts/header/_new_dropdown.haml +++ b/app/views/layouts/header/_new_dropdown.haml @@ -1,11 +1,11 @@ %li.header-new.dropdown = link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip", title: "New...", ref: 'tooltip', aria: { label: "New..." }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body' } do - if show_new_nav? - = icon('plus') - = icon('chevron-down') + = custom_icon('plus_square') + = custom_icon('caret_down') - else = icon('plus fw') - = icon('caret-down') + = custom_icon('caret_down') .dropdown-menu-nav.dropdown-menu-align-right %ul - if @group&.persisted? diff --git a/app/views/layouts/nav/_new_dashboard.html.haml b/app/views/layouts/nav/_new_dashboard.html.haml index e670e04928c..8a39c4d775f 100644 --- a/app/views/layouts/nav/_new_dashboard.html.haml +++ b/app/views/layouts/nav/_new_dashboard.html.haml @@ -1,26 +1,38 @@ %ul.list-unstyled.navbar-sub-nav = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown" }) do - %a{ href: '#', title: 'Projects', data: { toggle: 'dropdown' } } + %a{ href: "#", data: { toggle: "dropdown" } } Projects - = icon("chevron-down", class: "dropdown-chevron") + = custom_icon('caret_down') .dropdown-menu.projects-dropdown-menu = render "layouts/nav/projects_dropdown/show" - = nav_link(controller: ['dashboard/groups', 'explore/groups']) do + = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { class: "hidden-xs" }) do = link_to dashboard_groups_path, class: 'dashboard-shortcuts-groups', title: 'Groups' do Groups - = nav_link(path: 'dashboard#activity', html_options: { class: "hidden-xs hidden-sm hidden-md" }) do + = nav_link(path: 'dashboard#activity', html_options: { class: "visible-lg" }) do = link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', title: 'Activity' do Activity - %li.dropdown + = nav_link(controller: 'dashboard/milestones', html_options: { class: "visible-lg" }) do + = link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones', title: 'Milestones' do + Milestones + + = nav_link(controller: 'dashboard/snippets', html_options: { class: "visible-lg" }) do + = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', title: 'Snippets' do + Snippets + + %li.dropdown.hidden-lg %a{ href: "#", data: { toggle: "dropdown" } } More - = icon("chevron-down", class: "dropdown-chevron") + = custom_icon('caret_down') .dropdown-menu %ul - = nav_link(path: 'dashboard#activity', html_options: { class: "visible-xs visible-sm visible-md" }) do + = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { class: "visible-xs" }) do + = link_to dashboard_groups_path, class: 'dashboard-shortcuts-groups', title: 'Groups' do + Groups + + = nav_link(path: 'dashboard#activity') do = link_to activity_dashboard_path, title: 'Activity' do Activity @@ -31,11 +43,20 @@ = nav_link(controller: 'dashboard/snippets') do = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', title: 'Snippets' do Snippets - %li.divider - %li - = link_to "Help", help_path, title: 'About GitLab CE' -# Shortcut to Dashboard > Projects %li.hidden = link_to dashboard_projects_path, title: 'Projects', class: 'dashboard-shortcuts-projects' do Projects + + - if current_user.admin? || Gitlab::Sherlock.enabled? + %li.line-separator.hidden-xs + - if current_user.admin? + = nav_link(controller: 'admin/dashboard') do + = link_to admin_root_path, class: 'admin-icon', title: 'Admin area', aria: { label: "Admin area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = icon('wrench fw') + - if Gitlab::Sherlock.enabled? + %li + = link_to sherlock_transactions_path, class: 'admin-icon', title: 'Sherlock Transactions', + data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = icon('tachometer fw') diff --git a/app/views/layouts/nav/_new_explore.html.haml b/app/views/layouts/nav/_new_explore.html.haml index 40385f251e3..cd1c39f3226 100644 --- a/app/views/layouts/nav/_new_explore.html.haml +++ b/app/views/layouts/nav/_new_explore.html.haml @@ -5,15 +5,8 @@ = nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do = link_to explore_groups_path, title: 'Groups', class: 'dashboard-shortcuts-groups' do Groups - %li.dropdown - %a{ href: "#", data: { toggle: "dropdown" } } - More - = icon("chevron-down", class: "dropdown-chevron") - .dropdown-menu - %ul - = nav_link(controller: :snippets) do - = link_to explore_snippets_path, title: 'Snippets', class: 'dashboard-shortcuts-snippets' do - Snippets - %li.divider - %li - = link_to "Help", help_path, title: 'About GitLab CE' + = nav_link(controller: :snippets) do + = link_to explore_snippets_path, title: 'Snippets', class: 'dashboard-shortcuts-snippets' do + Snippets + %li + = link_to "Help", help_path, title: 'About GitLab CE' diff --git a/app/views/shared/_logo.svg b/app/views/shared/_logo.svg index 10e6c49ae9f..0ef9de5fed6 100644 --- a/app/views/shared/_logo.svg +++ b/app/views/shared/_logo.svg @@ -1,4 +1,4 @@ -7&QX3G%cfsF6!5js~jME%0-t4z0(o)r#)qws~ji(-? z;~()b@dvB&UgYU^5mRU_Sm*k_i>S2ZYPhM-N8o7Qr)T3Lvj5B8Q^FQc>aT7ig!ub1 zJ_GFn0_cw{Y$W_)47-(fl=Z}={5HHZ%me2L>A#_|) z%R*v!2OX1zQ0}prpxjX@nmbN%?$^gpz|d#kbfDc~G=XwyaM@Dk7q{M(m$e|f?2xNa zUmf-PU0*6PfMGCP@g!=ctO%5Gb_(Si&1P|#^hyFkGA@>-r)$HY%vdYlnr40xr2PUa zI7_fCykw)xyyl2&9O!re@20>3CyK(^&~UZy3W5h82GXNU8O0Pc-Bu@*i7+s0xd!fzaJ21zVs1p+H!woi+ zAh_xYF9JJ_7ymr0hVnti+W4e;GR@fS>3X?xHJ7G_m<*o+j)mU4)&0O@(bmC7PPgEa zss8k8#@PuJj3KfVa;QGW63r>IP-!+&q{dL7+=4BCXa3~bhwPHXx+lFxOU{k7J43;CC z@#pKR82jyV<`uqylPsdSHDU1P-D73cDRYJ7rK5Xd2Vo$LcLVV3G)Z;Mq1UQj*?Gf~ z8MToXwWHR0d2+s8ikp%0kg+p$W;-OPe#}{CR;4V-;DQpz&o;j8bw<3fi~HA(8DA>2DOhPhSM+m|N0U}!Z)7FHEQI?tSC~NF z8Rya6+%XJx|KixB82^7SC`NZ_>^1ov#+w=CDDwVTEw|XTDQ@#=bBXir!tDKM`6a$D z#0i(JW!u?*jh4j+pMFaJ_B(n+!y)Y)Kkxj{7JKKjM^z>`jqKgW+>nXKNALY18lZ*| zKI0cpw-z>oSr-{F&RMAhKIbp`y5o<+roy}Uxn`AGcDK;geXH@_QEwG|k{ VN5|Y;tbp${|7mhZ2$lO From 8769961679e320e7ee8016fbd8b9134863c40888 Mon Sep 17 00:00:00 2001 From: Winnie Hellmann Date: Tue, 5 Sep 2017 22:29:54 +0000 Subject: [PATCH 31/35] Make search dropdowns consistent --- app/assets/javascripts/gl_dropdown.js | 14 +- .../stylesheets/framework/dropdowns.scss | 1 + app/assets/stylesheets/pages/search.scss | 2 + spec/javascripts/gl_dropdown_spec.js | 379 ++++++++++-------- 4 files changed, 218 insertions(+), 178 deletions(-) diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js index d65bbc0d808..6f7671aa6fe 100644 --- a/app/assets/javascripts/gl_dropdown.js +++ b/app/assets/javascripts/gl_dropdown.js @@ -637,11 +637,15 @@ GitLabDropdown = (function() { value = this.options.id ? this.options.id(data) : data.id; fieldName = this.options.fieldName; - if (value) { value = value.toString().replace(/'/g, '\\\''); } - - field = this.dropdown.parent().find("input[name='" + fieldName + "'][value='" + value + "']"); - if (field.length) { - selected = true; + if (value) { + value = value.toString().replace(/'/g, '\\\''); + field = this.dropdown.parent().find(`input[name='${fieldName}'][value='${value}']`); + if (field.length) { + selected = true; + } + } else { + field = this.dropdown.parent().find(`input[name='${fieldName}']`); + selected = !field.length; } } // Set URL diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index e65a78b8dc3..6b21def33a6 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -766,6 +766,7 @@ box-shadow: none; padding: 8px 16px; text-align: left; + white-space: normal; width: 100%; // make sure the text color is not overriden diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index 8d73246223d..615020ca856 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -190,6 +190,8 @@ input[type="checkbox"]:hover { } .search-holder { + @include new-style-dropdown; + @media (min-width: $screen-sm-min) { display: -webkit-flex; display: flex; diff --git a/spec/javascripts/gl_dropdown_spec.js b/spec/javascripts/gl_dropdown_spec.js index 10fcc590c89..dcb8dbce178 100644 --- a/spec/javascripts/gl_dropdown_spec.js +++ b/spec/javascripts/gl_dropdown_spec.js @@ -4,7 +4,10 @@ import '~/gl_dropdown'; import '~/lib/utils/common_utils'; import '~/lib/utils/url_utility'; -(() => { +describe('glDropdown', function describeDropdown() { + preloadFixtures('static/gl_dropdown.html.raw'); + loadJSONFixtures('projects.json'); + const NON_SELECTABLE_CLASSES = '.divider, .separator, .dropdown-header, .dropdown-menu-empty-link'; const SEARCH_INPUT_SELECTOR = '.dropdown-input-field'; const ITEM_SELECTOR = `.dropdown-content li:not(${NON_SELECTABLE_CLASSES})`; @@ -39,187 +42,217 @@ import '~/lib/utils/url_utility'; remoteCallback = callback.bind({}, data); }; - describe('Dropdown', function describeDropdown() { - preloadFixtures('static/gl_dropdown.html.raw'); - loadJSONFixtures('projects.json'); + function initDropDown(hasRemote, isFilterable, extraOpts = {}) { + const options = Object.assign({ + selectable: true, + filterable: isFilterable, + data: hasRemote ? remoteMock.bind({}, this.projectsData) : this.projectsData, + search: { + fields: ['name'] + }, + text: project => (project.name_with_namespace || project.name), + id: project => project.id, + }, extraOpts); + this.dropdownButtonElement = $('#js-project-dropdown', this.dropdownContainerElement).glDropdown(options); + } - function initDropDown(hasRemote, isFilterable, extraOpts = {}) { - const options = Object.assign({ - selectable: true, - filterable: isFilterable, - data: hasRemote ? remoteMock.bind({}, this.projectsData) : this.projectsData, - search: { - fields: ['name'] - }, - text: project => (project.name_with_namespace || project.name), - id: project => project.id, - }, extraOpts); - this.dropdownButtonElement = $('#js-project-dropdown', this.dropdownContainerElement).glDropdown(options); - } + beforeEach(() => { + loadFixtures('static/gl_dropdown.html.raw'); + this.dropdownContainerElement = $('.dropdown.inline'); + this.$dropdownMenuElement = $('.dropdown-menu', this.dropdownContainerElement); + this.projectsData = getJSONFixture('projects.json'); + }); + afterEach(() => { + $('body').unbind('keydown'); + this.dropdownContainerElement.unbind('keyup'); + }); + + it('should open on click', () => { + initDropDown.call(this, false); + expect(this.dropdownContainerElement).not.toHaveClass('open'); + this.dropdownButtonElement.click(); + expect(this.dropdownContainerElement).toHaveClass('open'); + }); + + it('escapes HTML as text', () => { + this.projectsData[0].name_with_namespace = ''; + + initDropDown.call(this, false); + + this.dropdownButtonElement.click(); + + expect( + $('.dropdown-content li:first-child').text(), + ).toBe(''); + }); + + it('should output HTML when highlighting', () => { + this.projectsData[0].name_with_namespace = 'testing'; + $('.dropdown-input .dropdown-input-field').val('test'); + + initDropDown.call(this, false, true, { + highlight: true, + }); + + this.dropdownButtonElement.click(); + + expect( + $('.dropdown-content li:first-child').text(), + ).toBe('testing'); + + expect( + $('.dropdown-content li:first-child a').html(), + ).toBe('testing'); + }); + + describe('that is open', () => { beforeEach(() => { - loadFixtures('static/gl_dropdown.html.raw'); - this.dropdownContainerElement = $('.dropdown.inline'); - this.$dropdownMenuElement = $('.dropdown-menu', this.dropdownContainerElement); - this.projectsData = getJSONFixture('projects.json'); - }); - - afterEach(() => { - $('body').unbind('keydown'); - this.dropdownContainerElement.unbind('keyup'); - }); - - it('should open on click', () => { - initDropDown.call(this, false); - expect(this.dropdownContainerElement).not.toHaveClass('open'); + initDropDown.call(this, false, false); this.dropdownButtonElement.click(); + }); + + it('should select a following item on DOWN keypress', () => { + expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(0); + const randomIndex = (Math.floor(Math.random() * (this.projectsData.length - 1)) + 0); + navigateWithKeys('down', randomIndex, () => { + expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(1); + expect($(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, this.$dropdownMenuElement)).toHaveClass('is-focused'); + }); + }); + + it('should select a previous item on UP keypress', () => { + expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(0); + navigateWithKeys('down', (this.projectsData.length - 1), () => { + expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(1); + const randomIndex = (Math.floor(Math.random() * (this.projectsData.length - 2)) + 0); + navigateWithKeys('up', randomIndex, () => { + expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(1); + expect($(`${ITEM_SELECTOR}:eq(${((this.projectsData.length - 2) - randomIndex)}) a`, this.$dropdownMenuElement)).toHaveClass('is-focused'); + }); + }); + }); + + it('should click the selected item on ENTER keypress', () => { expect(this.dropdownContainerElement).toHaveClass('open'); - }); - - it('escapes HTML as text', () => { - this.projectsData[0].name_with_namespace = ''; - - initDropDown.call(this, false); - - this.dropdownButtonElement.click(); - - expect( - $('.dropdown-content li:first-child').text(), - ).toBe(''); - }); - - it('should output HTML when highlighting', () => { - this.projectsData[0].name_with_namespace = 'testing'; - $('.dropdown-input .dropdown-input-field').val('test'); - - initDropDown.call(this, false, true, { - highlight: true, - }); - - this.dropdownButtonElement.click(); - - expect( - $('.dropdown-content li:first-child').text(), - ).toBe('testing'); - - expect( - $('.dropdown-content li:first-child a').html(), - ).toBe('testing'); - }); - - describe('that is open', () => { - beforeEach(() => { - initDropDown.call(this, false, false); - this.dropdownButtonElement.click(); - }); - - it('should select a following item on DOWN keypress', () => { - expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(0); - const randomIndex = (Math.floor(Math.random() * (this.projectsData.length - 1)) + 0); - navigateWithKeys('down', randomIndex, () => { - expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(1); - expect($(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, this.$dropdownMenuElement)).toHaveClass('is-focused'); + const randomIndex = Math.floor(Math.random() * (this.projectsData.length - 1)) + 0; + navigateWithKeys('down', randomIndex, () => { + spyOn(gl.utils, 'visitUrl').and.stub(); + navigateWithKeys('enter', null, () => { + expect(this.dropdownContainerElement).not.toHaveClass('open'); + const link = $(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, this.$dropdownMenuElement); + expect(link).toHaveClass('is-active'); + const linkedLocation = link.attr('href'); + if (linkedLocation && linkedLocation !== '#') expect(gl.utils.visitUrl).toHaveBeenCalledWith(linkedLocation); }); }); - - it('should select a previous item on UP keypress', () => { - expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(0); - navigateWithKeys('down', (this.projectsData.length - 1), () => { - expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(1); - const randomIndex = (Math.floor(Math.random() * (this.projectsData.length - 2)) + 0); - navigateWithKeys('up', randomIndex, () => { - expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(1); - expect($(`${ITEM_SELECTOR}:eq(${((this.projectsData.length - 2) - randomIndex)}) a`, this.$dropdownMenuElement)).toHaveClass('is-focused'); - }); - }); - }); - - it('should click the selected item on ENTER keypress', () => { - expect(this.dropdownContainerElement).toHaveClass('open'); - const randomIndex = Math.floor(Math.random() * (this.projectsData.length - 1)) + 0; - navigateWithKeys('down', randomIndex, () => { - spyOn(gl.utils, 'visitUrl').and.stub(); - navigateWithKeys('enter', null, () => { - expect(this.dropdownContainerElement).not.toHaveClass('open'); - const link = $(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, this.$dropdownMenuElement); - expect(link).toHaveClass('is-active'); - const linkedLocation = link.attr('href'); - if (linkedLocation && linkedLocation !== '#') expect(gl.utils.visitUrl).toHaveBeenCalledWith(linkedLocation); - }); - }); - }); - - it('should close on ESC keypress', () => { - expect(this.dropdownContainerElement).toHaveClass('open'); - this.dropdownContainerElement.trigger({ - type: 'keyup', - which: ARROW_KEYS.ESC, - keyCode: ARROW_KEYS.ESC - }); - expect(this.dropdownContainerElement).not.toHaveClass('open'); - }); }); - describe('opened and waiting for a remote callback', () => { - beforeEach(() => { - initDropDown.call(this, true, true); - this.dropdownButtonElement.click(); + it('should close on ESC keypress', () => { + expect(this.dropdownContainerElement).toHaveClass('open'); + this.dropdownContainerElement.trigger({ + type: 'keyup', + which: ARROW_KEYS.ESC, + keyCode: ARROW_KEYS.ESC }); - - it('should show loading indicator while search results are being fetched by backend', () => { - const dropdownMenu = document.querySelector('.dropdown-menu'); - - expect(dropdownMenu.className.indexOf('is-loading') !== -1).toEqual(true); - remoteCallback(); - expect(dropdownMenu.className.indexOf('is-loading') !== -1).toEqual(false); - }); - - it('should not focus search input while remote task is not complete', () => { - expect($(document.activeElement)).not.toEqual($(SEARCH_INPUT_SELECTOR)); - remoteCallback(); - expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR)); - }); - - it('should focus search input after remote task is complete', () => { - remoteCallback(); - expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR)); - }); - - it('should focus on input when opening for the second time after transition', () => { - remoteCallback(); - this.dropdownContainerElement.trigger({ - type: 'keyup', - which: ARROW_KEYS.ESC, - keyCode: ARROW_KEYS.ESC - }); - this.dropdownButtonElement.click(); - this.dropdownContainerElement.trigger('transitionend'); - expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR)); - }); - }); - - describe('input focus with array data', () => { - it('should focus input when passing array data to drop down', () => { - initDropDown.call(this, false, true); - this.dropdownButtonElement.click(); - this.dropdownContainerElement.trigger('transitionend'); - expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR)); - }); - }); - - it('should still have input value on close and restore', () => { - const $searchInput = $(SEARCH_INPUT_SELECTOR); - initDropDown.call(this, false, true); - $searchInput - .trigger('focus') - .val('g') - .trigger('input'); - expect($searchInput.val()).toEqual('g'); - this.dropdownButtonElement.trigger('hidden.bs.dropdown'); - $searchInput - .trigger('blur') - .trigger('focus'); - expect($searchInput.val()).toEqual('g'); + expect(this.dropdownContainerElement).not.toHaveClass('open'); }); }); -})(); + + describe('opened and waiting for a remote callback', () => { + beforeEach(() => { + initDropDown.call(this, true, true); + this.dropdownButtonElement.click(); + }); + + it('should show loading indicator while search results are being fetched by backend', () => { + const dropdownMenu = document.querySelector('.dropdown-menu'); + + expect(dropdownMenu.className.indexOf('is-loading') !== -1).toEqual(true); + remoteCallback(); + expect(dropdownMenu.className.indexOf('is-loading') !== -1).toEqual(false); + }); + + it('should not focus search input while remote task is not complete', () => { + expect($(document.activeElement)).not.toEqual($(SEARCH_INPUT_SELECTOR)); + remoteCallback(); + expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR)); + }); + + it('should focus search input after remote task is complete', () => { + remoteCallback(); + expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR)); + }); + + it('should focus on input when opening for the second time after transition', () => { + remoteCallback(); + this.dropdownContainerElement.trigger({ + type: 'keyup', + which: ARROW_KEYS.ESC, + keyCode: ARROW_KEYS.ESC + }); + this.dropdownButtonElement.click(); + this.dropdownContainerElement.trigger('transitionend'); + expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR)); + }); + }); + + describe('input focus with array data', () => { + it('should focus input when passing array data to drop down', () => { + initDropDown.call(this, false, true); + this.dropdownButtonElement.click(); + this.dropdownContainerElement.trigger('transitionend'); + expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR)); + }); + }); + + it('should still have input value on close and restore', () => { + const $searchInput = $(SEARCH_INPUT_SELECTOR); + initDropDown.call(this, false, true); + $searchInput + .trigger('focus') + .val('g') + .trigger('input'); + expect($searchInput.val()).toEqual('g'); + this.dropdownButtonElement.trigger('hidden.bs.dropdown'); + $searchInput + .trigger('blur') + .trigger('focus'); + expect($searchInput.val()).toEqual('g'); + }); + + describe('renderItem', () => { + describe('without selected value', () => { + let dropdown; + + beforeEach(() => { + const dropdownOptions = { + + }; + const $dropdownDiv = $('
'); + $dropdownDiv.glDropdown(dropdownOptions); + dropdown = $dropdownDiv.data('glDropdown'); + }); + + it('marks items without ID as active', () => { + const dummyData = { }; + + const html = dropdown.renderItem(dummyData, null, null); + + const link = html.querySelector('a'); + expect(link).toHaveClass('is-active'); + }); + + it('does not mark items with ID as active', () => { + const dummyData = { + id: 'ea' + }; + + const html = dropdown.renderItem(dummyData, null, null); + + const link = html.querySelector('a'); + expect(link).not.toHaveClass('is-active'); + }); + }); + }); +}); From 4dff341af11d651d1ec199d35eebaf4adb92fdd0 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Wed, 6 Sep 2017 09:15:34 +0200 Subject: [PATCH 32/35] Fix wrong API status codes --- doc/api/README.md | 4 ++-- doc/api/environments.md | 2 +- doc/api/project_snippets.md | 3 +-- doc/api/users.md | 15 +++------------ 4 files changed, 7 insertions(+), 17 deletions(-) diff --git a/doc/api/README.md b/doc/api/README.md index a947eed2db8..db61497db53 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -237,8 +237,8 @@ The following table gives an overview of how the API functions generally behave. | ------------ | ----------- | | `GET` | Access one or more resources and return the result as JSON. | | `POST` | Return `201 Created` if the resource is successfully created and return the newly created resource as JSON. | -| `GET` / `PUT` / `DELETE` | Return `200 OK` if the resource is accessed, modified or deleted successfully. The (modified) result is returned as JSON. | -| `DELETE` | Designed to be idempotent, meaning a request to a resource still returns `200 OK` even it was deleted before or is not available. The reasoning behind this, is that the user is not really interested if the resource existed before or not. | +| `GET` / `PUT` | Return `200 OK` if the resource is accessed or modified successfully. The (modified) result is returned as JSON. | +| `DELETE` | Returns `204 No Content` if the resuource was deleted successfully. | The following table shows the possible return codes for API requests. diff --git a/doc/api/environments.md b/doc/api/environments.md index 5ca766bf87d..e8deb3e07e9 100644 --- a/doc/api/environments.md +++ b/doc/api/environments.md @@ -94,7 +94,7 @@ Example response: ## Delete an environment -It returns `200` if the environment was successfully deleted, and `404` if the environment does not exist. +It returns `204` if the environment was successfully deleted, and `404` if the environment does not exist. ``` DELETE /projects/:id/environments/:environment_id diff --git a/doc/api/project_snippets.md b/doc/api/project_snippets.md index 24c8ff5fa7a..ad2521230e6 100644 --- a/doc/api/project_snippets.md +++ b/doc/api/project_snippets.md @@ -95,8 +95,7 @@ Parameters: ## Delete snippet -Deletes an existing project snippet. This is an idempotent function and deleting a non-existent -snippet still returns a `200 OK` status code. +Deletes an existing project snippet. This returns a `204 No Content` status code if the operation was successfully or `404` if the resource was not found. ``` DELETE /projects/:id/snippets/:snippet_id diff --git a/doc/api/users.md b/doc/api/users.md index 57b4e117cf3..9f3e4caf2f4 100644 --- a/doc/api/users.md +++ b/doc/api/users.md @@ -299,10 +299,7 @@ e.g. when renaming the email address to some existing one. ## User deletion Deletes a user. Available only for administrators. -This is an idempotent function, calling this function for a non-existent user id -still returns a status code `200 OK`. -The JSON response differs if the user was actually deleted or not. -In the former the user is returned and in the latter not. +This returns a `204 No Content` status code if the operation was successfully or `404` if the resource was not found. ``` DELETE /users/:id @@ -524,8 +521,7 @@ Parameters: ## Delete SSH key for current user Deletes key owned by currently authenticated user. -This is an idempotent function and calling it on a key that is already deleted -or not available results in `200 OK`. +This returns a `204 No Content` status code if the operation was successfully or `404` if the resource was not found. ``` DELETE /user/keys/:key_id @@ -548,8 +544,6 @@ Parameters: - `id` (required) - id of specified user - `key_id` (required) - SSH key ID -Will return `200 OK` on success, or `404 Not found` if either user or key cannot be found. - ## List all GPG keys Get a list of currently authenticated user's GPG keys. @@ -865,8 +859,7 @@ Parameters: ## Delete email for current user Deletes email owned by currently authenticated user. -This is an idempotent function and calling it on a email that is already deleted -or not available results in `200 OK`. +This returns a `204 No Content` status code if the operation was successfully or `404` if the resource was not found. ``` DELETE /user/emails/:email_id @@ -889,8 +882,6 @@ Parameters: - `id` (required) - id of specified user - `email_id` (required) - email ID -Will return `200 OK` on success, or `404 Not found` if either user or email cannot be found. - ## Block user Blocks the specified user. Available only for admin. From 70bff97c2760cbe554f7b82047bc9186ccf3dfaf Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Wed, 6 Sep 2017 07:42:47 +0000 Subject: [PATCH 33/35] Use flexbox for prometheus graph row grouping instead of bootstrap classes --- .../monitoring/components/dashboard.vue | 10 +-- .../monitoring/components/graph.vue | 15 ++--- .../monitoring/components/graph_group.vue | 2 +- .../monitoring/components/graph_row.vue | 41 ------------ .../monitoring/stores/monitoring_store.js | 26 +------- .../stylesheets/pages/environments.scss | 26 ++++++-- spec/javascripts/monitoring/graph_row_spec.js | 62 ------------------- .../monitoring/monitoring_store_spec.js | 4 +- 8 files changed, 35 insertions(+), 151 deletions(-) delete mode 100644 app/assets/javascripts/monitoring/components/graph_row.vue delete mode 100644 spec/javascripts/monitoring/graph_row_spec.js diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index 74244faa5d9..b596c4f383f 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -4,7 +4,7 @@ import statusCodes from '../../lib/utils/http_status'; import MonitoringService from '../services/monitoring_service'; import GraphGroup from './graph_group.vue'; - import GraphRow from './graph_row.vue'; + import Graph from './graph.vue'; import EmptyState from './empty_state.vue'; import MonitoringStore from '../stores/monitoring_store'; import eventHub from '../event_hub'; @@ -32,8 +32,8 @@ }, components: { + Graph, GraphGroup, - GraphRow, EmptyState, }, @@ -127,10 +127,10 @@ :key="index" :name="groupData.group" > - diff --git a/app/assets/javascripts/monitoring/components/graph.vue b/app/assets/javascripts/monitoring/components/graph.vue index 9c785f4ada8..cde2ff7ca2a 100644 --- a/app/assets/javascripts/monitoring/components/graph.vue +++ b/app/assets/javascripts/monitoring/components/graph.vue @@ -19,10 +19,6 @@ type: Object, required: true, }, - classType: { - type: String, - required: true, - }, updateAspectRatio: { type: Boolean, required: true, @@ -207,12 +203,11 @@ }, }; +