Commit e106199e authored by Igor Drozdov's avatar Igor Drozdov

Merge branch 'add_unimplemented_create_scanner_profile_mutation_229729' into 'master'

Add unimplemented CreateDastScannerProfile mutation

See merge request gitlab-org/gitlab!37382
parents b86fc7a5 7a189e7b
...@@ -2159,6 +2159,56 @@ enum DastScanTypeEnum { ...@@ -2159,6 +2159,56 @@ enum DastScanTypeEnum {
PASSIVE PASSIVE
} }
"""
Autogenerated input type of DastScannerProfileCreate
"""
input DastScannerProfileCreateInput {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
The project the scanner profile belongs to.
"""
fullPath: ID!
"""
The name of the scanner profile.
"""
profileName: String!
"""
The maximum number of seconds allowed for the spider to traverse the site.
"""
spiderTimeout: Int
"""
The maximum number of seconds allowed for the site under test to respond to a request.
"""
targetTimeout: Int
}
"""
Autogenerated return type of DastScannerProfileCreate
"""
type DastScannerProfileCreatePayload {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Errors encountered during execution of the mutation.
"""
errors: [String!]!
"""
ID of the scanner profile.
"""
id: ID
}
""" """
Autogenerated input type of DastSiteProfileCreate Autogenerated input type of DastSiteProfileCreate
""" """
...@@ -8225,6 +8275,7 @@ type Mutation { ...@@ -8225,6 +8275,7 @@ type Mutation {
createNote(input: CreateNoteInput!): CreateNotePayload createNote(input: CreateNoteInput!): CreateNotePayload
createRequirement(input: CreateRequirementInput!): CreateRequirementPayload createRequirement(input: CreateRequirementInput!): CreateRequirementPayload
createSnippet(input: CreateSnippetInput!): CreateSnippetPayload createSnippet(input: CreateSnippetInput!): CreateSnippetPayload
dastScannerProfileCreate(input: DastScannerProfileCreateInput!): DastScannerProfileCreatePayload
dastSiteProfileCreate(input: DastSiteProfileCreateInput!): DastSiteProfileCreatePayload dastSiteProfileCreate(input: DastSiteProfileCreateInput!): DastSiteProfileCreatePayload
deleteAnnotation(input: DeleteAnnotationInput!): DeleteAnnotationPayload deleteAnnotation(input: DeleteAnnotationInput!): DeleteAnnotationPayload
designManagementDelete(input: DesignManagementDeleteInput!): DesignManagementDeletePayload designManagementDelete(input: DesignManagementDeleteInput!): DesignManagementDeletePayload
......
...@@ -5785,6 +5785,142 @@ ...@@ -5785,6 +5785,142 @@
], ],
"possibleTypes": null "possibleTypes": null
}, },
{
"kind": "INPUT_OBJECT",
"name": "DastScannerProfileCreateInput",
"description": "Autogenerated input type of DastScannerProfileCreate",
"fields": null,
"inputFields": [
{
"name": "fullPath",
"description": "The project the scanner profile belongs to.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "profileName",
"description": "The name of the scanner profile.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "spiderTimeout",
"description": "The maximum number of seconds allowed for the spider to traverse the site.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "targetTimeout",
"description": "The maximum number of seconds allowed for the site under test to respond to a request.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
}
],
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "DastScannerProfileCreatePayload",
"description": "Autogenerated return type of DastScannerProfileCreate",
"fields": [
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "errors",
"description": "Errors encountered during execution of the mutation.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
}
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "id",
"description": "ID of the scanner profile.",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{ {
"kind": "INPUT_OBJECT", "kind": "INPUT_OBJECT",
"name": "DastSiteProfileCreateInput", "name": "DastSiteProfileCreateInput",
...@@ -23576,6 +23712,33 @@ ...@@ -23576,6 +23712,33 @@
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
}, },
{
"name": "dastScannerProfileCreate",
"description": null,
"args": [
{
"name": "input",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "DastScannerProfileCreateInput",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "DastScannerProfileCreatePayload",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{ {
"name": "dastSiteProfileCreate", "name": "dastSiteProfileCreate",
"description": null, "description": null,
...@@ -382,6 +382,16 @@ Autogenerated return type of CreateSnippet ...@@ -382,6 +382,16 @@ Autogenerated return type of CreateSnippet
| `errors` | String! => Array | Errors encountered during execution of the mutation. | | `errors` | String! => Array | Errors encountered during execution of the mutation. |
| `snippet` | Snippet | The snippet after mutation | | `snippet` | Snippet | The snippet after mutation |
## DastScannerProfileCreatePayload
Autogenerated return type of DastScannerProfileCreate
| Name | Type | Description |
| --- | ---- | ---------- |
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
| `id` | ID | ID of the scanner profile. |
## DastSiteProfileCreatePayload ## DastSiteProfileCreatePayload
Autogenerated return type of DastSiteProfileCreate Autogenerated return type of DastSiteProfileCreate
......
...@@ -23,6 +23,7 @@ module EE ...@@ -23,6 +23,7 @@ module EE
mount_mutation ::Mutations::InstanceSecurityDashboard::RemoveProject mount_mutation ::Mutations::InstanceSecurityDashboard::RemoveProject
mount_mutation ::Mutations::Pipelines::RunDastScan mount_mutation ::Mutations::Pipelines::RunDastScan
mount_mutation ::Mutations::DastSiteProfiles::Create mount_mutation ::Mutations::DastSiteProfiles::Create
mount_mutation ::Mutations::DastScannerProfiles::Create
end end
end end
end end
......
# frozen_string_literal: true
module Mutations
module DastScannerProfiles
class Create < BaseMutation
include ResolvesProject
graphql_name 'DastScannerProfileCreate'
field :id, GraphQL::ID_TYPE,
null: true,
description: 'ID of the scanner profile.'
argument :full_path, GraphQL::ID_TYPE,
required: true,
description: 'The project the scanner profile belongs to.'
argument :profile_name, GraphQL::STRING_TYPE,
required: true,
description: 'The name of the scanner profile.'
argument :spider_timeout, GraphQL::INT_TYPE,
required: false,
description: 'The maximum number of seconds allowed for the spider to traverse the site.'
argument :target_timeout, GraphQL::INT_TYPE,
required: false,
description: 'The maximum number of seconds allowed for the site under test to respond to a request.'
authorize :run_ondemand_dast_scan
def resolve(full_path:, profile_name:, spider_timeout: nil, target_timeout: nil)
project = authorized_find!(full_path: full_path)
raise_resource_not_available_error! unless Feature.enabled?(:security_on_demand_scans_feature_flag, project)
response = ServiceResponse.error(message: 'Not implemented')
{ errors: response.errors }
end
private
def find_object(full_path:)
resolve_project(full_path: full_path)
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Mutations::DastScannerProfiles::Create do
let(:group) { create(:group) }
let(:project) { create(:project, group: group) }
let(:user) { create(:user) }
let(:full_path) { project.full_path }
let(:profile_name) { SecureRandom.hex }
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
describe '#resolve' do
subject do
mutation.resolve(
full_path: full_path,
profile_name: profile_name
)
end
context 'when the project does not exist' do
let(:full_path) { SecureRandom.hex }
it 'raises an exception' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'when the user is not associated with the project' do
it 'raises an exception' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'when the user can run a dast scan' do
before do
group.add_owner(user)
end
it 'stubs out the response' do
expect(subject[:errors]).to eq(['Not implemented'])
end
context 'when security_on_demand_scans_feature_flag is disabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
end
it 'raises an exception' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Creating a DAST Scanner Profile' do
include GraphqlHelpers
let(:project) { create(:project, :repository, creator: current_user) }
let(:current_user) { create(:user) }
let(:full_path) { project.full_path }
let(:profile_name) { FFaker::Company.catch_phrase }
let(:mutation) do
graphql_mutation(
:dast_scanner_profile_create,
full_path: full_path,
profile_name: profile_name
)
end
def mutation_response
graphql_mutation_response(:dast_scanner_profile_create)
end
context 'when a user does not have access to the project' do
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
"exist or you don't have permission to perform this action"]
end
context 'when a user does not have access to run a dast scan on the project' do
before do
project.add_guest(current_user)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
"exist or you don't have permission to perform this action"]
end
context 'when a user has access to run a DAST scan on the project' do
before do
project.add_developer(current_user)
end
it_behaves_like 'a mutation that returns errors in the response', errors: ['Not implemented']
context 'when on demand scan feature is disabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
"exist or you don't have permission to perform this action"]
end
end
end
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