Commit e4fbd94c authored by Victor Zagorodny's avatar Victor Zagorodny Committed by Kamil Trzciński

Update CE files for GSD projects filter

A new param with_security_reports was added to
GET /groups/:id/projects API and the code to
support this logic in GroupProjectsFinder and
Project model. Also, a DB index was added to
ci_job_artifacts table to speed up the search
of security reports artifacts for projects
parent 8c262bf7
......@@ -23,8 +23,12 @@ class GroupProjectsFinder < ProjectsFinder
attr_reader :group, :options
def initialize(group:, params: {}, options: {}, current_user: nil, project_ids_relation: nil)
super(params: params, current_user: current_user, project_ids_relation: project_ids_relation)
@group = group
super(
params: params,
current_user: current_user,
project_ids_relation: project_ids_relation
)
@group = group
@options = options
end
......@@ -84,15 +88,13 @@ class GroupProjectsFinder < ProjectsFinder
options.fetch(:include_subgroups, false)
end
# rubocop: disable CodeReuse/ActiveRecord
def owned_projects
if include_subgroups?
Project.where(namespace_id: group.self_and_descendants.select(:id))
Project.for_group_and_its_subgroups(group)
else
group.projects
end
end
# rubocop: enable CodeReuse/ActiveRecord
def shared_projects
group.shared_projects
......
......@@ -87,6 +87,8 @@ module Ci
scope :expired, -> (limit) { where('expire_at < ?', Time.now).limit(limit) }
scope :scoped_project, -> { where('ci_job_artifacts.project_id = projects.id') }
delegate :filename, :exists?, :open, to: :file
enum file_type: {
......
......@@ -497,6 +497,7 @@ class Project < ApplicationRecord
# We require an alias to the project_mirror_data_table in order to use import_state in our queries
scope :joins_import_state, -> { joins("INNER JOIN project_mirror_data import_state ON import_state.project_id = projects.id") }
scope :for_group, -> (group) { where(group: group) }
scope :for_group_and_its_subgroups, ->(group) { where(namespace_id: group.self_and_descendants.select(:id)) }
class << self
# Searches for a list of projects based on the query given in `query`.
......
# frozen_string_literal: true
class AddIndexToCiJobArtifactsOnProjectIdForSecurityReports < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_index :ci_job_artifacts,
:project_id,
name: "index_ci_job_artifacts_on_project_id_for_security_reports",
where: "file_type IN (5, 6, 7, 8)"
end
def down
remove_concurrent_index :ci_job_artifacts,
:project_id,
name: "index_ci_job_artifacts_on_project_id_for_security_reports"
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_08_20_163320) do
ActiveRecord::Schema.define(version: 2019_08_28_083843) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
......@@ -658,6 +658,7 @@ ActiveRecord::Schema.define(version: 2019_08_20_163320) do
t.index ["file_store"], name: "index_ci_job_artifacts_on_file_store"
t.index ["job_id", "file_type"], name: "index_ci_job_artifacts_on_job_id_and_file_type", unique: true
t.index ["project_id"], name: "index_ci_job_artifacts_on_project_id"
t.index ["project_id"], name: "index_ci_job_artifacts_on_project_id_for_security_reports", where: "(file_type = ANY (ARRAY[5, 6, 7, 8]))"
end
create_table "ci_job_variables", force: :cascade do |t|
......
......@@ -158,6 +158,7 @@ Parameters:
| `with_shared` | boolean | no | Include projects shared to this group. Default is `true` |
| `include_subgroups` | boolean | no | Include projects in subgroups of this group. Default is `false` |
| `with_custom_attributes` | boolean | no | Include [custom attributes](custom_attributes.md) in response (admins only) |
| `with_security_reports` | boolean | no | **(ULTIMATE)** Return only projects that have security reports artifacts present in any of their builds. This means "projects with security reports enabled". Default is `false` |
Example response:
......
......@@ -62,6 +62,9 @@ Once you're on the dashboard, at the top you should see a series of filters for:
- Report type
- Project
NOTE: **Note:**
The dashboard only shows projects with [security reports](#supported-reports) enabled in a group.
![dashboard with action buttons and metrics](img/group_security_dashboard.png)
Selecting one or more filters will filter the results in this page.
......
......@@ -216,6 +216,7 @@ module API
use :pagination
use :with_custom_attributes
use :optional_projects_params
end
get ":id/projects" do
projects = find_group_projects(params)
......
......@@ -416,17 +416,7 @@ module API
# rubocop: enable CodeReuse/ActiveRecord
def project_finder_params
finder_params = { without_deleted: true }
finder_params[:owned] = true if params[:owned].present?
finder_params[:non_public] = true if params[:membership].present?
finder_params[:starred] = true if params[:starred].present?
finder_params[:visibility_level] = Gitlab::VisibilityLevel.level_value(params[:visibility]) if params[:visibility]
finder_params[:archived] = archived_param unless params[:archived].nil?
finder_params[:search] = params[:search] if params[:search]
finder_params[:user] = params.delete(:user) if params[:user]
finder_params[:custom_attributes] = params[:custom_attributes] if params[:custom_attributes]
finder_params[:min_access_level] = params[:min_access_level] if params[:min_access_level]
finder_params
project_finder_params_ce.merge(project_finder_params_ee)
end
# file helpers
......@@ -461,6 +451,27 @@ module API
end
end
protected
def project_finder_params_ce
finder_params = { without_deleted: true }
finder_params[:owned] = true if params[:owned].present?
finder_params[:non_public] = true if params[:membership].present?
finder_params[:starred] = true if params[:starred].present?
finder_params[:visibility_level] = Gitlab::VisibilityLevel.level_value(params[:visibility]) if params[:visibility]
finder_params[:archived] = archived_param unless params[:archived].nil?
finder_params[:search] = params[:search] if params[:search]
finder_params[:user] = params.delete(:user) if params[:user]
finder_params[:custom_attributes] = params[:custom_attributes] if params[:custom_attributes]
finder_params[:min_access_level] = params[:min_access_level] if params[:min_access_level]
finder_params
end
# Overridden in EE
def project_finder_params_ee
{}
end
private
# rubocop:disable Gitlab/ModuleWithInstanceVariables
......
......@@ -28,6 +28,13 @@ module API
use :optional_params_ce
use :optional_params_ee
end
params :optional_projects_params_ee do
end
params :optional_projects_params do
use :optional_projects_params_ee
end
end
end
end
......@@ -6,9 +6,10 @@ RSpec.shared_context 'GroupProjectsFinder context' do
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
let(:current_user) { create(:user) }
let(:params) { {} }
let(:options) { {} }
let(:finder) { described_class.new(group: group, current_user: current_user, options: options) }
let(:finder) { described_class.new(group: group, current_user: current_user, params: params, options: options) }
let!(:public_project) { create(:project, :public, group: group, path: '1') }
let!(:private_project) { create(:project, :private, group: group, path: '2') }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment