Commit 2b637999 authored by Philip Cunningham's avatar Philip Cunningham

Create DastSiteProfile and DastSite models

Adds models, specs and migrations feature related to on-demand scans.
parent 5a3dd927
---
title: Add new models for DAST site profiles as part of DAST on-demand scans
merge_request: 36659
author:
type: changed
# frozen_string_literal: true
class CreateDastSites < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
with_lock_retries do
create_table :dast_sites do |t|
t.references :project, foreign_key: { on_delete: :cascade }, null: false, index: false
t.timestamps_with_timezone null: false
t.text :url, null: false
end
end
add_concurrent_index :dast_sites, [:project_id, :url], unique: true
add_text_limit :dast_sites, :url, 255
end
def down
drop_table :dast_sites
end
end
# frozen_string_literal: true
class CreateDastSiteProfiles < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
with_lock_retries do
create_table :dast_site_profiles do |t|
t.references :project, foreign_key: { on_delete: :cascade }, null: false, index: false
t.references :dast_site, foreign_key: { on_delete: :cascade }, null: false
t.timestamps_with_timezone null: false
t.text :name, null: false
end
end
add_concurrent_index :dast_site_profiles, [:project_id, :name], unique: true
add_text_limit :dast_site_profiles, :name, 255
end
def down
drop_table :dast_site_profiles
end
end
...@@ -10885,6 +10885,43 @@ CREATE SEQUENCE public.custom_emoji_id_seq ...@@ -10885,6 +10885,43 @@ CREATE SEQUENCE public.custom_emoji_id_seq
ALTER SEQUENCE public.custom_emoji_id_seq OWNED BY public.custom_emoji.id; ALTER SEQUENCE public.custom_emoji_id_seq OWNED BY public.custom_emoji.id;
CREATE TABLE public.dast_site_profiles (
id bigint NOT NULL,
project_id bigint NOT NULL,
dast_site_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
name text NOT NULL,
CONSTRAINT check_6cfab17b48 CHECK ((char_length(name) <= 255))
);
CREATE SEQUENCE public.dast_site_profiles_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE public.dast_site_profiles_id_seq OWNED BY public.dast_site_profiles.id;
CREATE TABLE public.dast_sites (
id bigint NOT NULL,
project_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
url text NOT NULL,
CONSTRAINT check_46df8b449c CHECK ((char_length(url) <= 255))
);
CREATE SEQUENCE public.dast_sites_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE public.dast_sites_id_seq OWNED BY public.dast_sites.id;
CREATE TABLE public.dependency_proxy_blobs ( CREATE TABLE public.dependency_proxy_blobs (
id integer NOT NULL, id integer NOT NULL,
group_id integer NOT NULL, group_id integer NOT NULL,
...@@ -16564,6 +16601,10 @@ ALTER TABLE ONLY public.conversational_development_index_metrics ALTER COLUMN id ...@@ -16564,6 +16601,10 @@ ALTER TABLE ONLY public.conversational_development_index_metrics ALTER COLUMN id
ALTER TABLE ONLY public.custom_emoji ALTER COLUMN id SET DEFAULT nextval('public.custom_emoji_id_seq'::regclass); ALTER TABLE ONLY public.custom_emoji ALTER COLUMN id SET DEFAULT nextval('public.custom_emoji_id_seq'::regclass);
ALTER TABLE ONLY public.dast_site_profiles ALTER COLUMN id SET DEFAULT nextval('public.dast_site_profiles_id_seq'::regclass);
ALTER TABLE ONLY public.dast_sites ALTER COLUMN id SET DEFAULT nextval('public.dast_sites_id_seq'::regclass);
ALTER TABLE ONLY public.dependency_proxy_blobs ALTER COLUMN id SET DEFAULT nextval('public.dependency_proxy_blobs_id_seq'::regclass); ALTER TABLE ONLY public.dependency_proxy_blobs ALTER COLUMN id SET DEFAULT nextval('public.dependency_proxy_blobs_id_seq'::regclass);
ALTER TABLE ONLY public.dependency_proxy_group_settings ALTER COLUMN id SET DEFAULT nextval('public.dependency_proxy_group_settings_id_seq'::regclass); ALTER TABLE ONLY public.dependency_proxy_group_settings ALTER COLUMN id SET DEFAULT nextval('public.dependency_proxy_group_settings_id_seq'::regclass);
...@@ -17532,6 +17573,12 @@ ALTER TABLE ONLY public.conversational_development_index_metrics ...@@ -17532,6 +17573,12 @@ ALTER TABLE ONLY public.conversational_development_index_metrics
ALTER TABLE ONLY public.custom_emoji ALTER TABLE ONLY public.custom_emoji
ADD CONSTRAINT custom_emoji_pkey PRIMARY KEY (id); ADD CONSTRAINT custom_emoji_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.dast_site_profiles
ADD CONSTRAINT dast_site_profiles_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.dast_sites
ADD CONSTRAINT dast_sites_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.dependency_proxy_blobs ALTER TABLE ONLY public.dependency_proxy_blobs
ADD CONSTRAINT dependency_proxy_blobs_pkey PRIMARY KEY (id); ADD CONSTRAINT dependency_proxy_blobs_pkey PRIMARY KEY (id);
...@@ -19032,6 +19079,12 @@ CREATE UNIQUE INDEX index_custom_emoji_on_namespace_id_and_name ON public.custom ...@@ -19032,6 +19079,12 @@ CREATE UNIQUE INDEX index_custom_emoji_on_namespace_id_and_name ON public.custom
CREATE UNIQUE INDEX index_daily_build_group_report_results_unique_columns ON public.ci_daily_build_group_report_results USING btree (project_id, ref_path, date, group_name); CREATE UNIQUE INDEX index_daily_build_group_report_results_unique_columns ON public.ci_daily_build_group_report_results USING btree (project_id, ref_path, date, group_name);
CREATE INDEX index_dast_site_profiles_on_dast_site_id ON public.dast_site_profiles USING btree (dast_site_id);
CREATE UNIQUE INDEX index_dast_site_profiles_on_project_id_and_name ON public.dast_site_profiles USING btree (project_id, name);
CREATE UNIQUE INDEX index_dast_sites_on_project_id_and_url ON public.dast_sites USING btree (project_id, url);
CREATE INDEX index_dependency_proxy_blobs_on_group_id_and_file_name ON public.dependency_proxy_blobs USING btree (group_id, file_name); CREATE INDEX index_dependency_proxy_blobs_on_group_id_and_file_name ON public.dependency_proxy_blobs USING btree (group_id, file_name);
CREATE INDEX index_dependency_proxy_group_settings_on_group_id ON public.dependency_proxy_group_settings USING btree (group_id); CREATE INDEX index_dependency_proxy_group_settings_on_group_id ON public.dependency_proxy_group_settings USING btree (group_id);
...@@ -22012,6 +22065,9 @@ ALTER TABLE ONLY public.project_compliance_framework_settings ...@@ -22012,6 +22065,9 @@ ALTER TABLE ONLY public.project_compliance_framework_settings
ALTER TABLE ONLY public.users_security_dashboard_projects ALTER TABLE ONLY public.users_security_dashboard_projects
ADD CONSTRAINT fk_rails_6f6cf8e66e FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_6f6cf8e66e FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.dast_sites
ADD CONSTRAINT fk_rails_6febb6ea9c FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.ci_builds_runner_session ALTER TABLE ONLY public.ci_builds_runner_session
ADD CONSTRAINT fk_rails_70707857d3 FOREIGN KEY (build_id) REFERENCES public.ci_builds(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_70707857d3 FOREIGN KEY (build_id) REFERENCES public.ci_builds(id) ON DELETE CASCADE;
...@@ -22027,6 +22083,9 @@ ALTER TABLE ONLY public.slack_integrations ...@@ -22027,6 +22083,9 @@ ALTER TABLE ONLY public.slack_integrations
ALTER TABLE ONLY public.custom_emoji ALTER TABLE ONLY public.custom_emoji
ADD CONSTRAINT fk_rails_745925b412 FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_745925b412 FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.dast_site_profiles
ADD CONSTRAINT fk_rails_747dc64abc FOREIGN KEY (dast_site_id) REFERENCES public.dast_sites(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.merge_request_context_commit_diff_files ALTER TABLE ONLY public.merge_request_context_commit_diff_files
ADD CONSTRAINT fk_rails_74a00a1787 FOREIGN KEY (merge_request_context_commit_id) REFERENCES public.merge_request_context_commits(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_74a00a1787 FOREIGN KEY (merge_request_context_commit_id) REFERENCES public.merge_request_context_commits(id) ON DELETE CASCADE;
...@@ -22081,6 +22140,9 @@ ALTER TABLE ONLY public.clusters_kubernetes_namespaces ...@@ -22081,6 +22140,9 @@ ALTER TABLE ONLY public.clusters_kubernetes_namespaces
ALTER TABLE ONLY public.approval_merge_request_rules_users ALTER TABLE ONLY public.approval_merge_request_rules_users
ADD CONSTRAINT fk_rails_80e6801803 FOREIGN KEY (approval_merge_request_rule_id) REFERENCES public.approval_merge_request_rules(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_80e6801803 FOREIGN KEY (approval_merge_request_rule_id) REFERENCES public.approval_merge_request_rules(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.dast_site_profiles
ADD CONSTRAINT fk_rails_83e309d69e FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.deployment_merge_requests ALTER TABLE ONLY public.deployment_merge_requests
ADD CONSTRAINT fk_rails_86a6d8bf12 FOREIGN KEY (merge_request_id) REFERENCES public.merge_requests(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_86a6d8bf12 FOREIGN KEY (merge_request_id) REFERENCES public.merge_requests(id) ON DELETE CASCADE;
...@@ -23772,6 +23834,8 @@ COPY "schema_migrations" (version) FROM STDIN; ...@@ -23772,6 +23834,8 @@ COPY "schema_migrations" (version) FROM STDIN;
20200710102846 20200710102846
20200710105332 20200710105332
20200710130234 20200710130234
20200712084655
20200712235622
20200713071042 20200713071042
\. \.
# frozen_string_literal: true
class DastSite < ApplicationRecord
belongs_to :project
has_many :dast_site_profiles
validates :url, length: { maximum: 255 }, uniqueness: { scope: :project_id }, public_url: true
validates :project_id, presence: true
end
# frozen_string_literal: true
class DastSiteProfile < ApplicationRecord
belongs_to :project
belongs_to :dast_site
validates :name, length: { maximum: 255 }, uniqueness: { scope: :project_id }
validates :project_id, :dast_site_id, presence: true
validate :dast_site_project_id_fk
private
def dast_site_project_id_fk
unless project_id == dast_site&.project_id
errors.add(:project_id, 'does not match dast_site.project')
end
end
end
...@@ -70,6 +70,9 @@ module EE ...@@ -70,6 +70,9 @@ module EE
has_many :vulnerability_scanners, class_name: 'Vulnerabilities::Scanner' has_many :vulnerability_scanners, class_name: 'Vulnerabilities::Scanner'
has_many :vulnerability_exports, class_name: 'Vulnerabilities::Export' has_many :vulnerability_exports, class_name: 'Vulnerabilities::Export'
has_many :dast_site_profiles
has_many :dast_sites
has_many :protected_environments has_many :protected_environments
has_many :software_license_policies, inverse_of: :project, class_name: 'SoftwareLicensePolicy' has_many :software_license_policies, inverse_of: :project, class_name: 'SoftwareLicensePolicy'
has_many :software_licenses, through: :software_license_policies has_many :software_licenses, through: :software_license_policies
......
# frozen_string_literal: true
FactoryBot.define do
factory :dast_site_profile do
name { FFaker::Product.product_name }
before(:create) do |dast_site_profile|
project = FactoryBot.create(:project)
dast_site = FactoryBot.create(:dast_site, project: project)
dast_site_profile.project = project
dast_site_profile.dast_site = dast_site
end
end
end
# frozen_string_literal: true
FactoryBot.define do
factory :dast_site do
project
url { FFaker::Internet.uri(:https) }
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe DastSiteProfile, type: :model do
subject { create(:dast_site_profile) }
describe 'associations' do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:dast_site) }
end
describe 'validations' do
it { is_expected.to be_valid }
it { is_expected.to validate_length_of(:name).is_at_most(255) }
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:project_id) }
it { is_expected.to validate_presence_of(:project_id) }
it { is_expected.to validate_presence_of(:dast_site_id) }
context 'when the project_id and dast_site.project_id do not match' do
let(:project) { create(:project) }
let(:dast_site) { create(:dast_site) }
subject { build(:dast_site_profile, project: project, dast_site: dast_site) }
it 'is not valid' do
expect(subject.valid?).to be_falsey
expect(subject.errors.full_messages).to include('Project does not match dast_site.project')
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe DastSite, type: :model do
subject { create(:dast_site) }
describe 'associations' do
it { is_expected.to belong_to(:project) }
it { is_expected.to have_many(:dast_site_profiles) }
end
describe 'validations' do
it { is_expected.to be_valid }
it { is_expected.to validate_length_of(:url).is_at_most(255) }
it { is_expected.to validate_uniqueness_of(:url).scoped_to(:project_id) }
it { is_expected.to validate_presence_of(:project_id) }
context 'when the url is not public' do
subject { build(:dast_site, url: 'http://127.0.0.1') }
it 'is not valid' do
expect(subject.valid?).to be_falsey
expect(subject.errors.full_messages).to include('Url is blocked: Requests to localhost are not allowed')
end
end
end
end
...@@ -34,6 +34,8 @@ RSpec.describe Project do ...@@ -34,6 +34,8 @@ RSpec.describe Project do
it { is_expected.to have_many(:vulnerability_feedback) } it { is_expected.to have_many(:vulnerability_feedback) }
it { is_expected.to have_many(:vulnerability_exports) } it { is_expected.to have_many(:vulnerability_exports) }
it { is_expected.to have_many(:vulnerability_scanners) } it { is_expected.to have_many(:vulnerability_scanners) }
it { is_expected.to have_many(:dast_site_profiles) }
it { is_expected.to have_many(:dast_sites) }
it { is_expected.to have_many(:audit_events).dependent(false) } it { is_expected.to have_many(:audit_events).dependent(false) }
it { is_expected.to have_many(:protected_environments) } it { is_expected.to have_many(:protected_environments) }
it { is_expected.to have_many(:approvers).dependent(:destroy) } it { is_expected.to have_many(:approvers).dependent(:destroy) }
......
...@@ -464,6 +464,8 @@ project: ...@@ -464,6 +464,8 @@ project:
- vulnerability_feedback - vulnerability_feedback
- vulnerability_identifiers - vulnerability_identifiers
- vulnerability_scanners - vulnerability_scanners
- dast_site_profiles
- dast_sites
- operations_feature_flags - operations_feature_flags
- operations_feature_flags_client - operations_feature_flags_client
- operations_feature_flags_user_lists - operations_feature_flags_user_lists
......
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