Commit 87e707ec authored by David Fernandez's avatar David Fernandez

Merge branch '299234-add-postman-collection' into 'master'

Add Postman API specification mode to API fuzzing CI configuration page

See merge request gitlab-org/gitlab!55601
parents e8d2c7d2 749d114e
...@@ -5190,6 +5190,7 @@ All possible ways to specify the API surface for an API fuzzing scan. ...@@ -5190,6 +5190,7 @@ All possible ways to specify the API surface for an API fuzzing scan.
| ----- | ----------- | | ----- | ----------- |
| `HAR` | The API surface is specified by a HAR file. | | `HAR` | The API surface is specified by a HAR file. |
| `OPENAPI` | The API surface is specified by a OPENAPI file. | | `OPENAPI` | The API surface is specified by a OPENAPI file. |
| `POSTMAN` | The API surface is specified by a POSTMAN file. |
### `AvailabilityEnum` ### `AvailabilityEnum`
......
...@@ -17,6 +17,14 @@ export const SCAN_MODES = { ...@@ -17,6 +17,14 @@ export const SCAN_MODES = {
'APIFuzzing|We recommend that you review the JSON specifications file before adding it to a repository.', 'APIFuzzing|We recommend that you review the JSON specifications file before adding it to a repository.',
), ),
}, },
POSTMAN: {
scanModeLabel: __('Postman collection'),
label: __('Postman collection'),
placeholder: s__('APIFuzzing|Ex: Project_Test/File/example_fuzz'),
description: s__(
'APIFuzzing|Postman collections are a group of saved requests you can organize into folders.',
),
},
}; };
export const CONFIGURATION_SNIPPET_MODAL_ID = 'CONFIGURATION_SNIPPET_MODAL_ID'; export const CONFIGURATION_SNIPPET_MODAL_ID = 'CONFIGURATION_SNIPPET_MODAL_ID';
...@@ -68,7 +68,7 @@ module EE ...@@ -68,7 +68,7 @@ module EE
mount_mutation ::Mutations::IncidentManagement::OncallSchedule::Destroy mount_mutation ::Mutations::IncidentManagement::OncallSchedule::Destroy
mount_mutation ::Mutations::IncidentManagement::OncallRotation::Create mount_mutation ::Mutations::IncidentManagement::OncallRotation::Create
mount_mutation ::Mutations::IncidentManagement::OncallRotation::Destroy mount_mutation ::Mutations::IncidentManagement::OncallRotation::Destroy
mount_mutation ::Mutations::Security::CiConfiguration::ApiFuzzing::Create mount_mutation ::Mutations::AppSec::Fuzzing::Api::CiConfiguration::Create
prepend(Types::DeprecatedMutations) prepend(Types::DeprecatedMutations)
end end
......
...@@ -128,7 +128,7 @@ module EE ...@@ -128,7 +128,7 @@ module EE
resolver: ::Resolvers::IncidentManagement::OncallScheduleResolver resolver: ::Resolvers::IncidentManagement::OncallScheduleResolver
field :api_fuzzing_ci_configuration, field :api_fuzzing_ci_configuration,
::Types::CiConfiguration::ApiFuzzingType, ::Types::AppSec::Fuzzing::Api::CiConfigurationType,
null: true, null: true,
description: 'API fuzzing configuration for the project.', description: 'API fuzzing configuration for the project.',
feature_flag: :api_fuzzing_configuration_ui feature_flag: :api_fuzzing_configuration_ui
...@@ -143,10 +143,10 @@ module EE ...@@ -143,10 +143,10 @@ module EE
def api_fuzzing_ci_configuration def api_fuzzing_ci_configuration
return unless Ability.allowed?(current_user, :read_vulnerability, object) return unless Ability.allowed?(current_user, :read_vulnerability, object)
configuration = ::Security::ApiFuzzing::CiConfiguration.new(project: object) configuration = ::AppSec::Fuzzing::Api::CiConfiguration.new(project: object)
{ {
scan_modes: ::Security::ApiFuzzing::CiConfiguration::SCAN_MODES, scan_modes: ::AppSec::Fuzzing::Api::CiConfiguration::SCAN_MODES,
scan_profiles: configuration.scan_profiles scan_profiles: configuration.scan_profiles
} }
end end
......
# frozen_string_literal: true
module Mutations
module AppSec
module Fuzzing
module Api
module CiConfiguration
class Create < BaseMutation
include FindsProject
graphql_name 'ApiFuzzingCiConfigurationCreate'
argument :project_path, GraphQL::ID_TYPE,
required: true,
description: 'Full path of the project.'
argument :api_specification_file, GraphQL::STRING_TYPE,
required: true,
description: 'File path or URL to the file that defines the API surface for scanning. '\
'Must be in the format specified by the `scanMode` argument.'
argument :auth_password, GraphQL::STRING_TYPE,
required: false,
description: 'CI variable containing the password for authenticating with the target API.'
argument :auth_username, GraphQL::STRING_TYPE,
required: false,
description: 'CI variable containing the username for authenticating with the target API.'
argument :scan_mode, ::Types::AppSec::Fuzzing::Api::ScanModeEnum,
required: true,
description: 'The mode for API fuzzing scans.'
argument :scan_profile, GraphQL::STRING_TYPE,
required: false,
description: 'Name of a default profile to use for scanning. Ex: Quick-10.'
argument :target, GraphQL::STRING_TYPE,
required: true,
description: 'URL for the target of API fuzzing scans.'
field :configuration_yaml, GraphQL::STRING_TYPE,
null: true,
description: "A YAML snippet that can be inserted into the project's "\
'`.gitlab-ci.yml` to set up API fuzzing scans.'
field :gitlab_ci_yaml_edit_path, GraphQL::STRING_TYPE,
null: true,
description: "The location at which the project's `.gitlab-ci.yml` file can be edited in the browser."
authorize :create_vulnerability
def resolve(args)
project = authorized_find!(args[:project_path])
raise_feature_off_error unless feature_enabled?(project)
create_service = ::AppSec::Fuzzing::Api::CiConfigurationCreateService.new(
container: project, current_user: current_user, params: args
)
{
configuration_yaml: create_service.create[:yaml].to_yaml,
errors: [],
gitlab_ci_yaml_edit_path: Rails.application.routes.url_helpers.project_ci_pipeline_editor_path(project)
}
end
private
def raise_feature_off_error
raise ::Gitlab::Graphql::Errors::ResourceNotAvailable,
'The API fuzzing CI configuration feature is off'
end
def feature_enabled?(project)
Feature.enabled?(:api_fuzzing_configuration_ui, project, default_enabled: :yaml)
end
end
end
end
end
end
end
# frozen_string_literal: true
module Mutations
module Security
module CiConfiguration
module ApiFuzzing
class Create < BaseMutation
include FindsProject
graphql_name 'ApiFuzzingCiConfigurationCreate'
argument :project_path, GraphQL::ID_TYPE,
required: true,
description: 'Full path of the project.'
argument :api_specification_file, GraphQL::STRING_TYPE,
required: true,
description: 'File path or URL to the file that defines the API surface for scanning. '\
'Must be in the format specified by the `scanMode` argument.'
argument :auth_password, GraphQL::STRING_TYPE,
required: false,
description: 'CI variable containing the password for authenticating with the target API.'
argument :auth_username, GraphQL::STRING_TYPE,
required: false,
description: 'CI variable containing the username for authenticating with the target API.'
argument :scan_mode, ::Types::CiConfiguration::ApiFuzzing::ScanModeEnum,
required: true,
description: 'The mode for API fuzzing scans.'
argument :scan_profile, GraphQL::STRING_TYPE,
required: false,
description: 'Name of a default profile to use for scanning. Ex: Quick-10.'
argument :target, GraphQL::STRING_TYPE,
required: true,
description: 'URL for the target of API fuzzing scans.'
field :configuration_yaml, GraphQL::STRING_TYPE,
null: true,
description: "A YAML snippet that can be inserted into the project's "\
'`.gitlab-ci.yml` to set up API fuzzing scans.'
field :gitlab_ci_yaml_edit_path, GraphQL::STRING_TYPE,
null: true,
description: "The location at which the project's `.gitlab-ci.yml` file can be edited in the browser."
authorize :create_vulnerability
def resolve(args)
project = authorized_find!(args[:project_path])
raise_feature_off_error unless feature_enabled?(project)
create_service = ::Security::CiConfiguration::ApiFuzzing::CreateService.new(
container: project, current_user: current_user, params: args
)
{
configuration_yaml: create_service.create[:yaml].to_yaml,
errors: [],
gitlab_ci_yaml_edit_path: Rails.application.routes.url_helpers.project_ci_pipeline_editor_path(project)
}
end
private
def raise_feature_off_error
raise ::Gitlab::Graphql::Errors::ResourceNotAvailable,
'The API fuzzing CI configuration feature is off'
end
def feature_enabled?(project)
Feature.enabled?(:api_fuzzing_configuration_ui, project, default_enabled: :yaml)
end
end
end
end
end
end
# frozen_string_literal: true
module Types
module AppSec
module Fuzzing
module Api
# rubocop: disable Graphql/AuthorizeTypes
class CiConfigurationType < BaseObject
graphql_name 'ApiFuzzingCiConfiguration'
description 'Data associated with configuring API fuzzing scans in GitLab CI'
field :scan_modes, [ScanModeEnum], null: true,
description: 'All available scan modes.'
field :scan_profiles, [ScanProfileType], null: true,
description: 'All default scan profiles.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
end
end
end
# frozen_string_literal: true
module Types
module AppSec
module Fuzzing
module Api
class ScanModeEnum < BaseEnum
graphql_name 'ApiFuzzingScanMode'
description 'All possible ways to specify the API surface for an API fuzzing scan.'
::AppSec::Fuzzing::Api::CiConfiguration::SCAN_MODES.each do |mode|
value mode.upcase, value: mode, description: "The API surface is specified by a #{mode.upcase} file."
end
end
end
end
end
end
# frozen_string_literal: true
module Types
module AppSec
module Fuzzing
module Api
# rubocop: disable Graphql/AuthorizeTypes
class ScanProfileType < BaseObject
graphql_name 'ApiFuzzingScanProfile'
description 'An API Fuzzing scan profile.'
field :name, GraphQL::STRING_TYPE, null: true,
description: 'The unique name of the profile.'
field :description, GraphQL::STRING_TYPE, null: true,
description: 'A short description of the profile.'
field :yaml, GraphQL::STRING_TYPE, null: true,
description: 'A syntax highlit HTML representation of the YAML.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
end
end
end
# frozen_string_literal: true
module Types
module CiConfiguration
module ApiFuzzing
class ScanModeEnum < BaseEnum
graphql_name 'ApiFuzzingScanMode'
description 'All possible ways to specify the API surface for an API fuzzing scan'
::Security::ApiFuzzing::CiConfiguration::SCAN_MODES.each do |mode|
value mode.upcase, value: mode, description: "The API surface is specified by a #{mode.upcase} file."
end
end
end
end
end
# frozen_string_literal: true
module Types
module CiConfiguration
module ApiFuzzing
# rubocop: disable Graphql/AuthorizeTypes
class ScanProfileType < BaseObject
graphql_name 'ApiFuzzingScanProfile'
description 'An API Fuzzing scan profile.'
field :name, GraphQL::STRING_TYPE, null: true,
description: 'The unique name of the profile.'
field :description, GraphQL::STRING_TYPE, null: true,
description: 'A short description of the profile.'
field :yaml, GraphQL::STRING_TYPE, null: true,
description: 'A syntax highlit HTML representation of the YAML.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
end
end
# frozen_string_literal: true
module Types
module CiConfiguration
# rubocop: disable Graphql/AuthorizeTypes
class ApiFuzzingType < BaseObject
graphql_name 'ApiFuzzingCiConfiguration'
description 'Data associated with configuring API fuzzing scans in GitLab CI'
field :scan_modes, [ApiFuzzing::ScanModeEnum], null: true,
description: 'All available scan modes.'
field :scan_profiles, [ApiFuzzing::ScanProfileType], null: true,
description: 'All default scan profiles.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
end
# frozen_string_literal: true
module AppSec
module Fuzzing
module Api
class CiConfiguration
PROFILES_DEFINITION_FILE = 'https://gitlab.com/gitlab-org/security-products/analyzers' \
'/api-fuzzing/-/raw/master/gitlab-api-fuzzing-config.yml'
SCAN_MODES = [:har, :openapi, :postman].freeze
def initialize(project:)
@project = project
end
def scan_profiles
fetch_scan_profiles.map do |profile|
next unless ScanProfile::NAMES.include?(profile[:Name])
ScanProfile.new(
name: profile[:Name],
project: project,
yaml: profile.deep_stringify_keys.to_yaml
)
end.compact
end
private
attr_reader :project
def fetch_scan_profiles
response = Gitlab::HTTP.try_get(PROFILES_DEFINITION_FILE)
if response&.success?
content = Gitlab::Config::Loader::Yaml.new(response.to_s).load!
content.fetch(:Profiles, [])
else
[]
end
end
end
end
end
end
# frozen_string_literal: true
module AppSec
module Fuzzing
module Api
class ScanProfile
NAMES = %w(Quick-10 Medium-20 Medium-50 Long-100).freeze
DESCRIPTIONS = {
'Quick-10' => 'Fuzzing 10 times per parameter',
'Medium-20' => 'Fuzzing 20 times per parameter',
'Medium-50' => 'Fuzzing 50 times per parameter',
'Long-100' => 'Fuzzing 100 times per parameter'
}.freeze
attr_reader :description, :name, :project, :yaml
def initialize(name:, project:, yaml:)
@description = DESCRIPTIONS[name]
@name = name
@project = project
@yaml = yaml
end
end
end
end
end
# frozen_string_literal: true
module Security
module ApiFuzzing
class CiConfiguration
PROFILES_DEFINITION_FILE = 'https://gitlab.com/gitlab-org/security-products/analyzers' \
'/api-fuzzing/-/raw/master/gitlab-api-fuzzing-config.yml'
SCAN_MODES = [:har, :openapi].freeze
def initialize(project:)
@project = project
end
def scan_profiles
fetch_scan_profiles.map do |profile|
next unless ScanProfile::NAMES.include?(profile[:Name])
ScanProfile.new(
name: profile[:Name],
project: project,
yaml: profile.deep_stringify_keys.to_yaml
)
end.compact
end
private
attr_reader :project
def fetch_scan_profiles
response = Gitlab::HTTP.try_get(PROFILES_DEFINITION_FILE)
if response && response.code.to_i < 300
content = Gitlab::Config::Loader::Yaml.new(response.to_s).load!
content.fetch(:Profiles, [])
else
[]
end
end
end
end
end
# frozen_string_literal: true
module Security
module ApiFuzzing
class ScanProfile
NAMES = %w(Quick-10 Medium-20 Medium-50 Long-100).freeze
DESCRIPTIONS = {
'Quick-10' => 'Fuzzing 10 times per parameter',
'Medium-20' => 'Fuzzing 20 times per parameter',
'Medium-50' => 'Fuzzing 50 times per parameter',
'Long-100' => 'Fuzzing 100 times per parameter'
}.freeze
attr_reader :description, :name, :project, :yaml
def initialize(name:, project:, yaml:)
@description = DESCRIPTIONS[name]
@name = name
@project = project
@yaml = yaml
end
end
end
end
# frozen_string_literal: true # frozen_string_literal: true
module Security module AppSec
module CiConfiguration module Fuzzing
module ApiFuzzing module Api
class CreateService < ::BaseContainerService class CiConfigurationCreateService < ::BaseContainerService
API_SPECIFICATION_CI_VARIABLES = {
har: 'FUZZAPI_HAR',
openapi: 'FUZZAPI_OPENAPI',
postman: 'FUZZAPI_POSTMAN_COLLECTION'
}.freeze
def create def create
success(yaml: preset_configuration.merge({ 'variables' => variables })) success(yaml: preset_configuration.merge({ 'variables' => variables }))
end end
...@@ -24,11 +30,7 @@ module Security ...@@ -24,11 +30,7 @@ module Security
end end
def api_specification_file def api_specification_file
if params[:scan_mode] == 'HAR' { API_SPECIFICATION_CI_VARIABLES[params[:scan_mode]] => params[:api_specification_file] }
{ 'FUZZAPI_HAR' => params[:api_specification_file] }
else
{ 'FUZZAPI_OPENAPI' => params[:api_specification_file] }
end
end end
def optional_variables def optional_variables
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Mutations::Security::CiConfiguration::ApiFuzzing::Create do RSpec.describe Mutations::AppSec::Fuzzing::Api::CiConfiguration::Create do
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
...@@ -19,7 +19,7 @@ RSpec.describe Mutations::Security::CiConfiguration::ApiFuzzing::Create do ...@@ -19,7 +19,7 @@ RSpec.describe Mutations::Security::CiConfiguration::ApiFuzzing::Create do
auth_password: '$PASSWORD', auth_password: '$PASSWORD',
auth_username: '$USERNAME', auth_username: '$USERNAME',
project_path: project.full_path, project_path: project.full_path,
scan_mode: 'HAR', scan_mode: :har,
scan_profile: 'Quick-10', scan_profile: 'Quick-10',
target: 'https://api.gov' target: 'https://api.gov'
) )
......
...@@ -4,6 +4,6 @@ require 'spec_helper' ...@@ -4,6 +4,6 @@ require 'spec_helper'
RSpec.describe GitlabSchema.types['ApiFuzzingScanMode'] do RSpec.describe GitlabSchema.types['ApiFuzzingScanMode'] do
it 'exposes all API fuzzing scan modes' do it 'exposes all API fuzzing scan modes' do
expect(described_class.values.keys).to match_array(%w[HAR OPENAPI]) expect(described_class.values.keys).to match_array(%w[HAR OPENAPI POSTMAN])
end end
end end
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Security::ApiFuzzing::CiConfiguration do RSpec.describe AppSec::Fuzzing::Api::CiConfiguration do
include StubRequests include StubRequests
describe '#scan_profiles' do describe '#scan_profiles' do
...@@ -10,7 +10,7 @@ RSpec.describe Security::ApiFuzzing::CiConfiguration do ...@@ -10,7 +10,7 @@ RSpec.describe Security::ApiFuzzing::CiConfiguration do
it 'returns all scan profiles' do it 'returns all scan profiles' do
profiles_yaml = YAML.dump(Profiles: [{ Name: 'Quick-10' }]) profiles_yaml = YAML.dump(Profiles: [{ Name: 'Quick-10' }])
stub_full_request( stub_full_request(
::Security::ApiFuzzing::CiConfiguration::PROFILES_DEFINITION_FILE described_class::PROFILES_DEFINITION_FILE
).to_return(body: profiles_yaml) ).to_return(body: profiles_yaml)
profiles = described_class.new(project: double(Project)).scan_profiles profiles = described_class.new(project: double(Project)).scan_profiles
...@@ -22,7 +22,7 @@ RSpec.describe Security::ApiFuzzing::CiConfiguration do ...@@ -22,7 +22,7 @@ RSpec.describe Security::ApiFuzzing::CiConfiguration do
it 'excludes them from the returned profiles' do it 'excludes them from the returned profiles' do
profiles_yaml = YAML.dump(Profiles: [{ Name: 'UNKNOWN!' }]) profiles_yaml = YAML.dump(Profiles: [{ Name: 'UNKNOWN!' }])
stub_full_request( stub_full_request(
::Security::ApiFuzzing::CiConfiguration::PROFILES_DEFINITION_FILE described_class::PROFILES_DEFINITION_FILE
).to_return(body: profiles_yaml) ).to_return(body: profiles_yaml)
profiles = described_class.new(project: double(Project)).scan_profiles profiles = described_class.new(project: double(Project)).scan_profiles
...@@ -45,7 +45,7 @@ RSpec.describe Security::ApiFuzzing::CiConfiguration do ...@@ -45,7 +45,7 @@ RSpec.describe Security::ApiFuzzing::CiConfiguration do
context 'when the request returns an unsuccessful status code' do context 'when the request returns an unsuccessful status code' do
it 'returns an empty array' do it 'returns an empty array' do
stub_full_request( stub_full_request(
::Security::ApiFuzzing::CiConfiguration::PROFILES_DEFINITION_FILE described_class::PROFILES_DEFINITION_FILE
).to_return(status: [500, 'everything is broken']) ).to_return(status: [500, 'everything is broken'])
profiles = described_class.new(project: double(Project)).scan_profiles profiles = described_class.new(project: double(Project)).scan_profiles
......
...@@ -38,7 +38,7 @@ RSpec.describe 'Query.project(fullPath).apiFuzzingCiConfiguration' do ...@@ -38,7 +38,7 @@ RSpec.describe 'Query.project(fullPath).apiFuzzingCiConfiguration' do
project.add_developer(user) project.add_developer(user)
stub_full_request( stub_full_request(
::Security::ApiFuzzing::CiConfiguration::PROFILES_DEFINITION_FILE ::AppSec::Fuzzing::Api::CiConfiguration::PROFILES_DEFINITION_FILE
).to_return(body: profiles_yaml) ).to_return(body: profiles_yaml)
end end
...@@ -60,7 +60,7 @@ RSpec.describe 'Query.project(fullPath).apiFuzzingCiConfiguration' do ...@@ -60,7 +60,7 @@ RSpec.describe 'Query.project(fullPath).apiFuzzingCiConfiguration' do
fuzzing_config = graphql_data.dig('project', 'apiFuzzingCiConfiguration') fuzzing_config = graphql_data.dig('project', 'apiFuzzingCiConfiguration')
modes = fuzzing_config['scanModes'] modes = fuzzing_config['scanModes']
profiles = fuzzing_config['scanProfiles'] profiles = fuzzing_config['scanProfiles']
expect(modes).to contain_exactly('HAR', 'OPENAPI') expect(modes).to contain_exactly('HAR', 'OPENAPI', 'POSTMAN')
expect(profiles).to contain_exactly({ expect(profiles).to contain_exactly({
'name' => 'Quick-10', 'name' => 'Quick-10',
'description' => 'Fuzzing 10 times per parameter', 'description' => 'Fuzzing 10 times per parameter',
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe ::Security::CiConfiguration::ApiFuzzing::CreateService do RSpec.describe ::AppSec::Fuzzing::Api::CiConfigurationCreateService do
let(:service) { described_class.new(container: double(Project), current_user: double(User), params: params) } let(:service) { described_class.new(container: double(Project), current_user: double(User), params: params) }
describe '#create' do describe '#create' do
...@@ -14,7 +14,7 @@ RSpec.describe ::Security::CiConfiguration::ApiFuzzing::CreateService do ...@@ -14,7 +14,7 @@ RSpec.describe ::Security::CiConfiguration::ApiFuzzing::CreateService do
api_specification_file: 'https://api.gov/api_spec', api_specification_file: 'https://api.gov/api_spec',
auth_password: '$PASSWORD', auth_password: '$PASSWORD',
auth_username: '$USERNAME', auth_username: '$USERNAME',
scan_mode: 'OPENAPI', scan_mode: :openapi,
scan_profile: 'Quick-10', scan_profile: 'Quick-10',
target: 'https://api.gov' target: 'https://api.gov'
} }
...@@ -41,7 +41,7 @@ RSpec.describe ::Security::CiConfiguration::ApiFuzzing::CreateService do ...@@ -41,7 +41,7 @@ RSpec.describe ::Security::CiConfiguration::ApiFuzzing::CreateService do
api_specification_file: 'https://api.gov/api_spec', api_specification_file: 'https://api.gov/api_spec',
auth_password: '$PASSWORD', auth_password: '$PASSWORD',
auth_username: '$USERNAME', auth_username: '$USERNAME',
scan_mode: 'HAR', scan_mode: :har,
scan_profile: 'Quick-10', scan_profile: 'Quick-10',
target: 'https://api.gov' target: 'https://api.gov'
} }
...@@ -62,11 +62,38 @@ RSpec.describe ::Security::CiConfiguration::ApiFuzzing::CreateService do ...@@ -62,11 +62,38 @@ RSpec.describe ::Security::CiConfiguration::ApiFuzzing::CreateService do
end end
end end
context 'when given a POSTMAN specification file' do
let(:params) do
{
api_specification_file: 'postman-collection.json',
auth_password: '$PASSWORD',
auth_username: '$USERNAME',
scan_mode: :postman,
scan_profile: 'Quick-10',
target: 'https://api.gov'
}
end
it 'returns the API fuzzing configuration based on the given parameters' do
is_expected.to eq({
'stages' => ['fuzz'],
'include' => [{ 'template' => 'API-Fuzzing.gitlab-ci.yml' }],
'variables' => {
'FUZZAPI_HTTP_PASSWORD' => '$PASSWORD',
'FUZZAPI_HTTP_USERNAME' => '$USERNAME',
'FUZZAPI_POSTMAN_COLLECTION' => 'postman-collection.json',
'FUZZAPI_PROFILE' => 'Quick-10',
'FUZZAPI_TARGET_URL' => 'https://api.gov'
}
})
end
end
context 'when values for optional variables are not given' do context 'when values for optional variables are not given' do
let(:params) do let(:params) do
{ {
api_specification_file: 'https://api.gov/api_spec', api_specification_file: 'https://api.gov/api_spec',
scan_mode: 'HAR', scan_mode: :har,
target: 'https://api.gov' target: 'https://api.gov'
} }
end end
......
...@@ -1483,6 +1483,9 @@ msgstr "" ...@@ -1483,6 +1483,9 @@ msgstr ""
msgid "APIFuzzing|Ex: $TestUsername" msgid "APIFuzzing|Ex: $TestUsername"
msgstr "" msgstr ""
msgid "APIFuzzing|Ex: Project_Test/File/example_fuzz"
msgstr ""
msgid "APIFuzzing|Ex: Project_Test/File/example_fuzz.har" msgid "APIFuzzing|Ex: Project_Test/File/example_fuzz.har"
msgstr "" msgstr ""
...@@ -1507,6 +1510,9 @@ msgstr "" ...@@ -1507,6 +1510,9 @@ msgstr ""
msgid "APIFuzzing|Password for basic authentication" msgid "APIFuzzing|Password for basic authentication"
msgstr "" msgstr ""
msgid "APIFuzzing|Postman collections are a group of saved requests you can organize into folders."
msgstr ""
msgid "APIFuzzing|Scan mode" msgid "APIFuzzing|Scan mode"
msgstr "" msgstr ""
...@@ -22823,6 +22829,9 @@ msgstr "" ...@@ -22823,6 +22829,9 @@ msgstr ""
msgid "Policy project doesn't exists" msgid "Policy project doesn't exists"
msgstr "" msgstr ""
msgid "Postman collection"
msgstr ""
msgid "Pre-defined push rules." msgid "Pre-defined push rules."
msgstr "" msgstr ""
......
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