diff options
14 files changed, 145 insertions, 24 deletions
diff --git a/.gitlab/merge_request_templates/Security Release.md b/.gitlab/merge_request_templates/Security Release.md index 246f2dae009..42314f9b2dd 100644 --- a/.gitlab/merge_request_templates/Security Release.md +++ b/.gitlab/merge_request_templates/Security Release.md @@ -7,6 +7,10 @@ See [the general developer security release guidelines](https://gitlab.com/gitla This merge request _must not_ close the corresponding security issue _unless_ it targets master. +When submitting a merge request for CE, a corresponding EE merge request is +always required. This makes it easier to merge security merge requests, as +manually merging CE into EE is no longer required. + --> ## Related issues @@ -20,8 +24,8 @@ targets master. - [ ] Title of this MR is the same as for all backports - [ ] A [CHANGELOG entry](https://docs.gitlab.com/ee/development/changelog.html) is added without a `merge_request` value, with `type` set to `security` - [ ] Add a link to this MR in the `links` section of related issue -- [ ] Add a link to an EE MR if required -- [ ] Assign to a reviewer +- [ ] Set up an EE MR (always required for CE merge requests): EE_MR_LINK_HERE +- [ ] Assign to a reviewer (that is not a release manager) ## Reviewer checklist diff --git a/app/assets/javascripts/pipelines/stores/pipeline_store.js b/app/assets/javascripts/pipelines/stores/pipeline_store.js index 052e34a8aef..259278b6410 100644 --- a/app/assets/javascripts/pipelines/stores/pipeline_store.js +++ b/app/assets/javascripts/pipelines/stores/pipeline_store.js @@ -1,7 +1,6 @@ export default class PipelineStore { constructor() { this.state = {}; - this.state.pipeline = {}; } diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index 61ecf133b02..0eb854ecf98 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -346,7 +346,9 @@ } > .popover-title, - > .popover-content { + > .popover-content, + > .popover-header, + > .popover-body { padding: 8px; font-size: 12px; white-space: nowrap; diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 9e2375b84d0..6415d902ca6 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -256,6 +256,10 @@ .selectbox { display: none; + + &.show { + display: block; + } } .btn-clipboard:hover { @@ -309,6 +313,7 @@ } .no-value, + .btn-default-hover-link, .btn-secondary-hover-link { color: $gl-text-color-secondary; } @@ -592,7 +597,6 @@ margin: -7px; } - .user-list { display: flex; flex-wrap: wrap; @@ -716,6 +720,7 @@ .issuable-main-info { flex: 1 auto; margin-right: 10px; + min-width: 0; .issue-weight-icon { vertical-align: sub; @@ -777,6 +782,7 @@ @media(max-width: map-get($grid-breakpoints, lg)-1) { .task-status, .issuable-due-date, + .issuable-weight, .project-ref-path { display: none; } diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index 93d3c991846..0319e95d439 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -81,7 +81,7 @@ class ProjectsFinder < UnionFinder if private_only? current_user.authorized_projects else - Project.public_or_visible_to_user(current_user) + Project.public_or_visible_to_user(current_user, params[:visibility_level]) end end end diff --git a/app/models/project.rb b/app/models/project.rb index 97a17d120c6..06010409574 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -459,14 +459,41 @@ class Project < ActiveRecord::Base # Returns a collection of projects that is either public or visible to the # logged in user. - def self.public_or_visible_to_user(user = nil) - if user - where('EXISTS (?) OR projects.visibility_level IN (?)', - user.authorizations_for_projects, - Gitlab::VisibilityLevel.levels_for_user(user)) - else - public_to_user - end + # + # requested_visiblity_levels: Normally all projects that are visible + # to the user (e.g. internal and public) are queried, but this + # parameter allows the caller to narrow the search space to optimize + # database queries. For instance, a caller may only want to see + # internal projects. Instead of querying for internal and public + # projects and throwing away public projects, this parameter allows + # the query to be targeted for only internal projects. + def self.public_or_visible_to_user(user = nil, requested_visibility_levels = []) + return public_to_user unless user + + visible_levels = Gitlab::VisibilityLevel.levels_for_user(user) + include_private = true + requested_visibility_levels = Array(requested_visibility_levels) + + if requested_visibility_levels.present? + visible_levels &= requested_visibility_levels + include_private = requested_visibility_levels.include?(Gitlab::VisibilityLevel::PRIVATE) + end + + public_or_internal_rel = + if visible_levels.present? + where('projects.visibility_level IN (?)', visible_levels) + else + Project.none + end + + private_rel = + if include_private + where('EXISTS (?)', user.authorizations_for_projects) + else + Project.none + end + + public_or_internal_rel.or(private_rel) end # project features may be "disabled", "internal", "enabled" or "public". If "internal", diff --git a/app/views/projects/artifacts/browse.html.haml b/app/views/projects/artifacts/browse.html.haml index 09295940529..6a7cb1499c5 100644 --- a/app/views/projects/artifacts/browse.html.haml +++ b/app/views/projects/artifacts/browse.html.haml @@ -4,7 +4,7 @@ = render "projects/jobs/header" - add_to_breadcrumbs(s_('CICD|Jobs'), project_jobs_path(@project)) -- add_to_breadcrumbs("##{@build.id}", project_jobs_path(@project)) +- add_to_breadcrumbs("##{@build.id}", project_job_path(@project, @build)) .tree-holder .nav-block diff --git a/changelogs/unreleased/59502-fix-breadcrumb-artifacts.yml b/changelogs/unreleased/59502-fix-breadcrumb-artifacts.yml new file mode 100644 index 00000000000..da65c3bc870 --- /dev/null +++ b/changelogs/unreleased/59502-fix-breadcrumb-artifacts.yml @@ -0,0 +1,5 @@ +--- +title: Fixes job link in artifacts page breadcrumb +merge_request: 26592 +author: +type: fixed diff --git a/changelogs/unreleased/sh-optimize-projects-api.yml b/changelogs/unreleased/sh-optimize-projects-api.yml new file mode 100644 index 00000000000..2f2459be77f --- /dev/null +++ b/changelogs/unreleased/sh-optimize-projects-api.yml @@ -0,0 +1,5 @@ +--- +title: Optimize /api/v4/projects endpoint for visibility level +merge_request: 26481 +author: +type: performance diff --git a/db/fixtures/development/25_api_personal_access_token.rb b/db/fixtures/development/25_api_personal_access_token.rb new file mode 100644 index 00000000000..a2e6c674c1f --- /dev/null +++ b/db/fixtures/development/25_api_personal_access_token.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require './spec/support/sidekiq' + +# Create an api access token for root user with the value: ypCa3Dzb23o5nvsixwPA +Gitlab::Seeder.quiet do + PersonalAccessToken.create!( + user_id: User.find_by(username: 'root').id, + name: "seeded-api-token", + scopes: ["api"], + token_digest: "/O0jfLERYT/L5gG8nfByQxqTj43TeLlRzOtJGTzRsbQ=" + ) + + print '.' +end diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb index 0b92ea29ca4..ceb888bb4ef 100644 --- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb +++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb @@ -106,8 +106,7 @@ module QA end end - # Failure issue: https://gitlab.com/gitlab-org/quality/nightly/issues/87 - describe 'Auto DevOps', :smoke, :quarantine do + describe 'Auto DevOps', :smoke do it 'enables AutoDevOps by default' do login diff --git a/spec/features/projects/artifacts/user_browses_artifacts_spec.rb b/spec/features/projects/artifacts/user_browses_artifacts_spec.rb index 5f630c9ffa4..a1fcd4024c0 100644 --- a/spec/features/projects/artifacts/user_browses_artifacts_spec.rb +++ b/spec/features/projects/artifacts/user_browses_artifacts_spec.rb @@ -19,6 +19,12 @@ describe "User browses artifacts" do visit(browse_project_job_artifacts_path(project, job)) end + it "renders a link to the job in the breadcrumbs" do + page.within('.js-breadcrumbs-list') do + expect(page).to have_link("##{job.id}", href: project_job_path(project, job)) + end + end + it "shows artifacts" do expect(page).not_to have_selector(".build-sidebar") diff --git a/spec/javascripts/notes/components/note_form_spec.js b/spec/javascripts/notes/components/note_form_spec.js index c48f8188105..b632ee6736d 100644 --- a/spec/javascripts/notes/components/note_form_spec.js +++ b/spec/javascripts/notes/components/note_form_spec.js @@ -41,8 +41,6 @@ describe('issue_note_form component', () => { noteBody: 'Magni suscipit eius consectetur enim et ex et commodi.', noteId: '545', }; - - wrapper = createComponentWrapper(); }); afterEach(() => { @@ -50,6 +48,10 @@ describe('issue_note_form component', () => { }); describe('noteHash', () => { + beforeEach(() => { + wrapper = createComponentWrapper(); + }); + it('returns note hash string based on `noteId`', () => { expect(wrapper.vm.noteHash).toBe(`#note_${props.noteId}`); }); @@ -71,6 +73,10 @@ describe('issue_note_form component', () => { }); describe('conflicts editing', () => { + beforeEach(() => { + wrapper = createComponentWrapper(); + }); + it('should show conflict message if note changes outside the component', done => { wrapper.setProps({ ...props, @@ -100,6 +106,10 @@ describe('issue_note_form component', () => { }); describe('form', () => { + beforeEach(() => { + wrapper = createComponentWrapper(); + }); + it('should render text area with placeholder', () => { const textarea = wrapper.find('textarea'); @@ -198,10 +208,6 @@ describe('issue_note_form component', () => { }); describe('with autosaveKey', () => { - beforeEach(() => { - wrapper.destroy(); - }); - describe('with draft', () => { beforeEach(done => { Object.assign(props, { diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index fc9d9a28b9a..90dcf861849 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -2710,7 +2710,7 @@ describe Project do end describe '#any_lfs_file_locks?', :request_store do - set(:project) { create(:project) } + let!(:project) { create(:project) } it 'returns false when there are no LFS file locks' do expect(project.any_lfs_file_locks?).to be_falsey @@ -3148,6 +3148,53 @@ describe Project do expect(projects).to eq([public_project]) end end + + context 'with requested visibility levels' do + set(:internal_project) { create(:project, :internal, :repository) } + set(:private_project_2) { create(:project, :private) } + + context 'with admin user' do + set(:admin) { create(:admin) } + + it 'returns all projects' do + projects = described_class.all.public_or_visible_to_user(admin, []) + + expect(projects).to match_array([public_project, private_project, private_project_2, internal_project]) + end + + it 'returns all public and private projects' do + projects = described_class.all.public_or_visible_to_user(admin, [Gitlab::VisibilityLevel::PUBLIC, Gitlab::VisibilityLevel::PRIVATE]) + + expect(projects).to match_array([public_project, private_project, private_project_2]) + end + + it 'returns all private projects' do + projects = described_class.all.public_or_visible_to_user(admin, [Gitlab::VisibilityLevel::PRIVATE]) + + expect(projects).to match_array([private_project, private_project_2]) + end + end + + context 'with regular user' do + it 'returns authorized projects' do + projects = described_class.all.public_or_visible_to_user(user, []) + + expect(projects).to match_array([public_project, private_project, internal_project]) + end + + it "returns user's public and private projects" do + projects = described_class.all.public_or_visible_to_user(user, [Gitlab::VisibilityLevel::PUBLIC, Gitlab::VisibilityLevel::PRIVATE]) + + expect(projects).to match_array([public_project, private_project]) + end + + it 'returns one private project' do + projects = described_class.all.public_or_visible_to_user(user, [Gitlab::VisibilityLevel::PRIVATE]) + + expect(projects).to eq([private_project]) + end + end + end end describe '.with_feature_available_for_user' do |