diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-11-06 03:09:48 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-11-06 03:09:48 +0300 |
commit | 9cc2aa99c032c8b813ab1bfc439a56d39d83e679 (patch) | |
tree | 34044358d91b25cc29ea7bc0832de091f2d1114e | |
parent | 98e2f18e5b9716416d183262c21c31524de7331a (diff) |
Add latest changes from gitlab-org/gitlab@master
-rw-r--r-- | app/graphql/mutations/organizations/create.rb | 35 | ||||
-rw-r--r-- | app/graphql/types/mutation_type.rb | 1 | ||||
-rw-r--r-- | app/services/organizations/base_service.rb | 14 | ||||
-rw-r--r-- | app/services/organizations/create_service.rb | 27 | ||||
-rw-r--r-- | doc/api/graphql/reference/index.md | 24 | ||||
-rw-r--r-- | doc/architecture/blueprints/secret_detection/index.md | 18 | ||||
-rw-r--r-- | doc/user/application_security/container_scanning/index.md | 2 | ||||
-rw-r--r-- | doc/user/application_security/dependency_scanning/index.md | 11 | ||||
-rw-r--r-- | doc/user/application_security/vulnerability_report/index.md | 1 | ||||
-rw-r--r-- | locale/gitlab.pot | 6 | ||||
-rw-r--r-- | spec/requests/api/graphql/mutations/organizations/create_spec.rb | 64 | ||||
-rw-r--r-- | spec/services/organizations/create_service_spec.rb | 40 |
12 files changed, 233 insertions, 10 deletions
diff --git a/app/graphql/mutations/organizations/create.rb b/app/graphql/mutations/organizations/create.rb new file mode 100644 index 00000000000..0d1b204a4c1 --- /dev/null +++ b/app/graphql/mutations/organizations/create.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module Mutations + module Organizations + class Create < BaseMutation + graphql_name 'OrganizationCreate' + + authorize :create_organization + + field :organization, + ::Types::Organizations::OrganizationType, + null: true, + description: 'Organization created.' + + argument :name, GraphQL::Types::String, + required: true, + description: 'Name for the organization.' + + argument :path, GraphQL::Types::String, + required: true, + description: 'Path for the organization.' + + def resolve(args) + authorize!(:global) + + result = ::Organizations::CreateService.new( + current_user: current_user, + params: args + ).execute + + { organization: result.payload, errors: result.errors } + end + end + end +end diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb index 4ff64d6f60c..e1bd1f603ad 100644 --- a/app/graphql/types/mutation_type.rb +++ b/app/graphql/types/mutation_type.rb @@ -106,6 +106,7 @@ module Types mount_mutation Mutations::Notes::Update::ImageDiffNote mount_mutation Mutations::Notes::RepositionImageDiffNote mount_mutation Mutations::Notes::Destroy + mount_mutation Mutations::Organizations::Create, alpha: { milestone: '16.6' } mount_mutation Mutations::Projects::SyncFork, calls_gitaly: true, alpha: { milestone: '15.9' } mount_mutation Mutations::Releases::Create mount_mutation Mutations::Releases::Update diff --git a/app/services/organizations/base_service.rb b/app/services/organizations/base_service.rb new file mode 100644 index 00000000000..19bbc64ebdd --- /dev/null +++ b/app/services/organizations/base_service.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Organizations + class BaseService + include BaseServiceUtility + + attr_reader :current_user, :params + + def initialize(current_user: nil, params: {}) + @current_user = current_user + @params = params.dup + end + end +end diff --git a/app/services/organizations/create_service.rb b/app/services/organizations/create_service.rb new file mode 100644 index 00000000000..89c579032d2 --- /dev/null +++ b/app/services/organizations/create_service.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Organizations + class CreateService < ::Organizations::BaseService + def execute + return error_no_permissions unless current_user&.can?(:create_organization) + + organization = Organization.create(params) + + return error_creating(organization) unless organization.persisted? + + ServiceResponse.success(payload: organization) + end + + private + + def error_no_permissions + ServiceResponse.error(message: [_('You have insufficient permissions to create organizations')]) + end + + def error_creating(organization) + message = organization.errors.full_messages || _('Failed to create organization') + + ServiceResponse.error(message: Array(message)) + end + end +end diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 3a0825fc5dd..3a4ff0c369a 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -5602,6 +5602,30 @@ Input type: `OncallScheduleUpdateInput` | <a id="mutationoncallscheduleupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | | <a id="mutationoncallscheduleupdateoncallschedule"></a>`oncallSchedule` | [`IncidentManagementOncallSchedule`](#incidentmanagementoncallschedule) | On-call schedule. | +### `Mutation.organizationCreate` + +WARNING: +**Introduced** in 16.6. +This feature is an Experiment. It can be changed or removed at any time. + +Input type: `OrganizationCreateInput` + +#### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mutationorganizationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | +| <a id="mutationorganizationcreatename"></a>`name` | [`String!`](#string) | Name for the organization. | +| <a id="mutationorganizationcreatepath"></a>`path` | [`String!`](#string) | Path for the organization. | + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mutationorganizationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | +| <a id="mutationorganizationcreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | +| <a id="mutationorganizationcreateorganization"></a>`organization` | [`Organization`](#organization) | Organization created. | + ### `Mutation.pagesMarkOnboardingComplete` Input type: `PagesMarkOnboardingCompleteInput` diff --git a/doc/architecture/blueprints/secret_detection/index.md b/doc/architecture/blueprints/secret_detection/index.md index 81f0dd3fcb2..76bf6dd4088 100644 --- a/doc/architecture/blueprints/secret_detection/index.md +++ b/doc/architecture/blueprints/secret_detection/index.md @@ -34,8 +34,8 @@ See [target types](#target-types) for scan target priorities. ### Non-Goals -Initial proposal is limited to detection and alerting across plaform, with rejection only -during preceive Git interactions. +Initial proposal is limited to detection and alerting across platform, with rejection only +during [preceive Git interactions and browser-based detection](#iterations). Secret revocation and rotation is also beyond the scope of this new capability. @@ -134,7 +134,7 @@ In order of priority this includes: Targets out of scope for the initial phases include: -- Media types (JPEGs, PDFs,...) +- Media types (JPEG, PDF, ...) - Snippets - Wikis - Container images @@ -155,17 +155,17 @@ Token types to identify in order of importance: ### Detection engine -Our current secret detection offering utilizes [Gitleaks](https://github.com/zricethezav/gitleaks/) +Our current secret detection offering uses [Gitleaks](https://github.com/zricethezav/gitleaks/) for all secret scanning in pipeline contexts. By using its `--no-git` configuration we can scan arbitrary text blobs outside of a repository context and continue to -utilize it for non-pipeline scanning. +use it for non-pipeline scanning. -In the case of prereceive detection, we rely on a combination of keyword/substring matches -for prefiltering and `re2` for regex detections. See [spike issue](https://gitlab.com/gitlab-org/gitlab/-/issues/423832) for initial benchmarks +In the case of PreReceive detection, we rely on a combination of keyword/substring matches +for pre-filtering and `re2` for regex detections. See [spike issue](https://gitlab.com/gitlab-org/gitlab/-/issues/423832) for initial benchmarks Changes to the detection engine are out of scope until benchmarking unveils performance concerns. -Notable alternatives include high-performance regex engines such as [hyperscan](https://github.com/intel/hyperscan) or it's portable fork [vectorscan](https://github.com/VectorCamp/vectorscan). +Notable alternatives include high-performance regex engines such as [Hyperscan](https://github.com/intel/hyperscan) or it's portable fork [Vectorscan](https://github.com/VectorCamp/vectorscan). ### High-level architecture @@ -217,7 +217,7 @@ sequenceDiagram - ✓ Implement [Browser-based detection of GitLab tokens in comments/issues](https://gitlab.com/gitlab-org/gitlab/-/issues/368434) - ✓ [PoC of secret scanning service](https://gitlab.com/gitlab-org/secure/pocs/secret-detection-go-poc/) - ✓ [PoC of secret scanning gem](https://gitlab.com/gitlab-org/gitlab/-/issues/426823) -- [Pre Production Performance Profiling for pre-receive PoCs](https://gitlab.com/gitlab-org/gitlab/-/issues/428499) +- [Pre-Production Performance Profiling for pre-receive PoCs](https://gitlab.com/gitlab-org/gitlab/-/issues/428499) - Profiling service capabilities - ✓ [Benchmarking regex performance between Ruby and Go approaches](https://gitlab.com/gitlab-org/gitlab/-/issues/423832) - gRPC commit retrieval from Gitaly diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md index 34699360228..f3fca8f2def 100644 --- a/doc/user/application_security/container_scanning/index.md +++ b/doc/user/application_security/container_scanning/index.md @@ -59,7 +59,7 @@ information directly in the merge request. ### Capabilities -| Capability | In Free | In Ultimate | +| Capability | In Free and Premium | In Ultimate | | --- | ------ | ------ | | [Configure Scanners](#configuration) | Yes | Yes | | Customize Settings ([Variables](#available-cicd-variables), [Overriding](#overriding-the-container-scanning-template), [offline environment support](#running-container-scanning-in-an-offline-environment), etc) | Yes | Yes | diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md index 4ea813374e8..787552ef717 100644 --- a/doc/user/application_security/dependency_scanning/index.md +++ b/doc/user/application_security/dependency_scanning/index.md @@ -1097,6 +1097,17 @@ variables: GRADLE_CLI_OPTS: "-Dhttps.proxyHost=squid-proxy -Dhttps.proxyPort=3128 -Dhttp.proxyHost=squid-proxy -Dhttp.proxyPort=3128 -Dhttp.nonProxyHosts=localhost" ``` +## Using a proxy with Maven projects + +Maven does not read the `HTTP(S)_PROXY` environment variables. + +To make the Maven dependency scanner use a proxy, you can specify the options using the `MAVEN_CLI_OPTS` CI/CD variable: + +```yaml +variables: + MAVEN_CLI_OPTS: "-DproxySet=true -Dhttps.proxyHost=squid-proxy -Dhttps.proxyPort=3128 -Dhttp.proxyHost=squid-proxy -Dhttp.proxyPort=3218" +``` + ## Specific settings for languages and package managers See the following sections for configuring specific languages and package managers. diff --git a/doc/user/application_security/vulnerability_report/index.md b/doc/user/application_security/vulnerability_report/index.md index 210cce456f9..577567f04e3 100644 --- a/doc/user/application_security/vulnerability_report/index.md +++ b/doc/user/application_security/vulnerability_report/index.md @@ -139,6 +139,7 @@ Selection behavior when using the Activity filter: - **With issues**: Only vulnerabilities with one or more associated issues. Does not include vulnerabilities that also are no longer detected. - **No longer detected**: Only vulnerabilities that are no longer detected in the latest pipeline scan of the `default` branch. Does not include vulnerabilities with one or more associated issues. - **With issues** and **No longer detected**: Only vulnerabilities that have one or more associated issues and also are no longer detected in the latest pipeline scan of the `default` branch. +- **Has merge request**: Only vulnerabilities with one or more associated merge requests. ## View details of a vulnerability diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 92b0cb58e9d..b01185abfd2 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -20064,6 +20064,9 @@ msgstr "" msgid "Failed to create import label for jira import." msgstr "" +msgid "Failed to create organization" +msgstr "" + msgid "Failed to create repository" msgstr "" @@ -55220,6 +55223,9 @@ msgstr "" msgid "You have insufficient permissions to create an on-call schedule for this project" msgstr "" +msgid "You have insufficient permissions to create organizations" +msgstr "" + msgid "You have insufficient permissions to delete a target branch rule" msgstr "" diff --git a/spec/requests/api/graphql/mutations/organizations/create_spec.rb b/spec/requests/api/graphql/mutations/organizations/create_spec.rb new file mode 100644 index 00000000000..ac6b04104ba --- /dev/null +++ b/spec/requests/api/graphql/mutations/organizations/create_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Mutations::Organizations::Create, feature_category: :cell do + include GraphqlHelpers + + let_it_be(:user) { create(:user) } + + let(:mutation) { graphql_mutation(:organization_create, params) } + let(:name) { 'Name' } + let(:path) { 'path' } + let(:params) do + { + name: name, + path: path + } + end + + subject(:create_organization) { post_graphql_mutation(mutation, current_user: current_user) } + + it { expect(described_class).to require_graphql_authorizations(:create_organization) } + + def mutation_response + graphql_mutation_response(:organization_create) + end + + context 'when the user does not have permission' do + let(:current_user) { nil } + + it_behaves_like 'a mutation that returns a top-level access error' + + it 'does not create an organization' do + expect { create_organization }.not_to change { Organizations::Organization.count } + end + end + + context 'when the user has permission' do + let(:current_user) { user } + + context 'when the params are invalid' do + let(:name) { '' } + + it 'returns the validation error' do + create_organization + + expect(mutation_response).to include('errors' => ["Name can't be blank"]) + end + end + + it 'creates an organization' do + expect { create_organization }.to change { Organizations::Organization.count }.by(1) + end + + it 'returns the new organization' do + create_organization + + expect(graphql_data_at(:organization_create, :organization)).to match a_hash_including( + 'name' => name, + 'path' => path + ) + end + end +end diff --git a/spec/services/organizations/create_service_spec.rb b/spec/services/organizations/create_service_spec.rb new file mode 100644 index 00000000000..7d9bf64ddd3 --- /dev/null +++ b/spec/services/organizations/create_service_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Organizations::CreateService, feature_category: :cell do + describe '#execute' do + let_it_be(:user) { create(:user) } + + let(:current_user) { user } + let(:params) { attributes_for(:organization) } + + subject(:response) { described_class.new(current_user: current_user, params: params).execute } + + context 'when user does not have permission' do + let(:current_user) { nil } + + it 'returns an error' do + expect(response).to be_error + + expect(response.message).to match_array( + ['You have insufficient permissions to create organizations']) + end + end + + context 'when user has permission' do + it 'creates an organization' do + expect { response }.to change { Organizations::Organization.count } + + expect(response).to be_success + end + + it 'returns an error when the organization is not persisted' do + params[:name] = nil + + expect(response).to be_error + expect(response.message).to match_array(["Name can't be blank"]) + end + end + end +end |