diff options
author | Robert Speicher <rspeicher@gmail.com> | 2019-03-12 20:03:50 +0300 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2019-03-12 20:03:50 +0300 |
commit | ccbbc1000d12da078a6fd1e88d8c215673e202d6 (patch) | |
tree | e2bd046199b389aa6edc4b3d8fe638571e2d16b4 /lib | |
parent | 173645639080b4d4d889c20af1420ece14f8db08 (diff) | |
parent | a7004e282586c2158fc13d5f82f210b4a63a7b92 (diff) |
Merge branch 'resolve-lib-differences' into 'master'
Resolve CE to EE differences in the lib/api directory
See merge request gitlab-org/gitlab-ce!25430
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/discussions.rb | 4 | ||||
-rw-r--r-- | lib/api/groups.rb | 20 | ||||
-rw-r--r-- | lib/api/helpers/discussions_helpers.rb | 13 | ||||
-rw-r--r-- | lib/api/helpers/notes_helpers.rb | 6 | ||||
-rw-r--r-- | lib/api/helpers/resource_label_events_helpers.rb | 13 | ||||
-rw-r--r-- | lib/api/helpers/search_helpers.rb | 22 | ||||
-rw-r--r-- | lib/api/helpers/services_helpers.rb | 721 | ||||
-rw-r--r-- | lib/api/internal.rb | 10 | ||||
-rw-r--r-- | lib/api/notes.rb | 4 | ||||
-rw-r--r-- | lib/api/resource_label_events.rb | 4 | ||||
-rw-r--r-- | lib/api/search.rb | 25 | ||||
-rw-r--r-- | lib/api/services.rb | 698 | ||||
-rw-r--r-- | lib/api/settings.rb | 7 | ||||
-rw-r--r-- | lib/api/triggers.rb | 2 | ||||
-rw-r--r-- | lib/api/variables.rb | 10 |
15 files changed, 842 insertions, 717 deletions
diff --git a/lib/api/discussions.rb b/lib/api/discussions.rb index 91eb6a23701..8afe6dda414 100644 --- a/lib/api/discussions.rb +++ b/lib/api/discussions.rb @@ -7,9 +7,7 @@ module API before { authenticate! } - NOTEABLE_TYPES = [Issue, Snippet, MergeRequest, Commit].freeze - - NOTEABLE_TYPES.each do |noteable_type| + Helpers::DiscussionsHelpers.noteable_types.each do |noteable_type| parent_type = noteable_type.parent_class.to_s.underscore noteables_str = noteable_type.to_s.underscore.pluralize noteables_path = noteable_type == Commit ? "repository/#{noteables_str}" : noteables_str diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 64958ff982a..cb0d6d96f29 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -58,6 +58,22 @@ module API end # rubocop: enable CodeReuse/ActiveRecord + def create_group + # This is a separate method so that EE can extend its behaviour, without + # having to modify this code directly. + ::Groups::CreateService + .new(current_user, declared_params(include_missing: false)) + .execute + end + + def update_group(group) + # This is a separate method so that EE can extend its behaviour, without + # having to modify this code directly. + ::Groups::UpdateService + .new(group, current_user, declared_params(include_missing: false)) + .execute + end + def find_group_projects(params) group = find_group!(params[:id]) options = { @@ -127,7 +143,7 @@ module API authorize! :create_group end - group = ::Groups::CreateService.new(current_user, declared_params(include_missing: false)).execute + group = create_group if group.persisted? present group, with: Entities::GroupDetail, current_user: current_user @@ -153,7 +169,7 @@ module API group = find_group!(params[:id]) authorize! :admin_group, group - if ::Groups::UpdateService.new(group, current_user, declared_params(include_missing: false)).execute + if update_group(group) present group, with: Entities::GroupDetail, current_user: current_user else render_validation_error!(group) diff --git a/lib/api/helpers/discussions_helpers.rb b/lib/api/helpers/discussions_helpers.rb new file mode 100644 index 00000000000..94a5bf75c39 --- /dev/null +++ b/lib/api/helpers/discussions_helpers.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module API + module Helpers + module DiscussionsHelpers + def self.noteable_types + # This is a method instead of a constant, allowing EE to more easily + # extend it. + [Issue, Snippet, MergeRequest, Commit] + end + end + end +end diff --git a/lib/api/helpers/notes_helpers.rb b/lib/api/helpers/notes_helpers.rb index 795dca5cf03..a068de4361c 100644 --- a/lib/api/helpers/notes_helpers.rb +++ b/lib/api/helpers/notes_helpers.rb @@ -3,6 +3,12 @@ module API module Helpers module NotesHelpers + def self.noteable_types + # This is a method instead of a constant, allowing EE to more easily + # extend it. + [Issue, MergeRequest, Snippet] + end + def update_note(noteable, note_id) note = noteable.notes.find(params[:note_id]) diff --git a/lib/api/helpers/resource_label_events_helpers.rb b/lib/api/helpers/resource_label_events_helpers.rb new file mode 100644 index 00000000000..23574deb59b --- /dev/null +++ b/lib/api/helpers/resource_label_events_helpers.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module API + module Helpers + module ResourceLabelEventsHelpers + def self.eventable_types + # This is a method instead of a constant, allowing EE to more easily + # extend it. + [Issue, MergeRequest] + end + end + end +end diff --git a/lib/api/helpers/search_helpers.rb b/lib/api/helpers/search_helpers.rb new file mode 100644 index 00000000000..47fb5a36327 --- /dev/null +++ b/lib/api/helpers/search_helpers.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module API + module Helpers + module SearchHelpers + def self.global_search_scopes + # This is a separate method so that EE can redefine it. + %w(projects issues merge_requests milestones snippet_titles snippet_blobs) + end + + def self.group_search_scopes + # This is a separate method so that EE can redefine it. + %w(projects issues merge_requests milestones) + end + + def self.project_search_scopes + # This is a separate method so that EE can redefine it. + %w(issues merge_requests milestones notes wiki_blobs commits blobs) + end + end + end +end diff --git a/lib/api/helpers/services_helpers.rb b/lib/api/helpers/services_helpers.rb new file mode 100644 index 00000000000..8582c45798f --- /dev/null +++ b/lib/api/helpers/services_helpers.rb @@ -0,0 +1,721 @@ +# frozen_string_literal: true + +module API + module Helpers + # Helpers module for API::Services + # + # The data structures inside this model are returned using class methods, + # allowing EE to extend them where necessary. + module ServicesHelpers + def self.chat_notification_settings + [ + { + required: true, + name: :webhook, + type: String, + desc: 'The chat webhook' + }, + { + required: false, + name: :username, + type: String, + desc: 'The chat username' + }, + { + required: false, + name: :channel, + type: String, + desc: 'The default chat channel' + } + ].freeze + end + + def self.chat_notification_flags + [ + { + required: false, + name: :notify_only_broken_pipelines, + type: Boolean, + desc: 'Send notifications for broken pipelines' + }, + { + required: false, + name: :notify_only_default_branch, + type: Boolean, + desc: 'Send notifications only for the default branch' + } + ].freeze + end + + def self.chat_notification_channels + [ + { + required: false, + name: :push_channel, + type: String, + desc: 'The name of the channel to receive push_events notifications' + }, + { + required: false, + name: :issue_channel, + type: String, + desc: 'The name of the channel to receive issues_events notifications' + }, + { + required: false, + name: :confidential_issue_channel, + type: String, + desc: 'The name of the channel to receive confidential_issues_events notifications' + }, + { + required: false, + name: :merge_request_channel, + type: String, + desc: 'The name of the channel to receive merge_requests_events notifications' + }, + { + required: false, + name: :note_channel, + type: String, + desc: 'The name of the channel to receive note_events notifications' + }, + { + required: false, + name: :tag_push_channel, + type: String, + desc: 'The name of the channel to receive tag_push_events notifications' + }, + { + required: false, + name: :pipeline_channel, + type: String, + desc: 'The name of the channel to receive pipeline_events notifications' + }, + { + required: false, + name: :wiki_page_channel, + type: String, + desc: 'The name of the channel to receive wiki_page_events notifications' + } + ].freeze + end + + def self.chat_notification_events + [ + { + required: false, + name: :push_events, + type: Boolean, + desc: 'Enable notifications for push_events' + }, + { + required: false, + name: :issues_events, + type: Boolean, + desc: 'Enable notifications for issues_events' + }, + { + required: false, + name: :confidential_issues_events, + type: Boolean, + desc: 'Enable notifications for confidential_issues_events' + }, + { + required: false, + name: :merge_requests_events, + type: Boolean, + desc: 'Enable notifications for merge_requests_events' + }, + { + required: false, + name: :note_events, + type: Boolean, + desc: 'Enable notifications for note_events' + }, + { + required: false, + name: :tag_push_events, + type: Boolean, + desc: 'Enable notifications for tag_push_events' + }, + { + required: false, + name: :pipeline_events, + type: Boolean, + desc: 'Enable notifications for pipeline_events' + }, + { + required: false, + name: :wiki_page_events, + type: Boolean, + desc: 'Enable notifications for wiki_page_events' + } + ].freeze + end + + def self.services + { + 'asana' => [ + { + required: true, + name: :api_key, + type: String, + desc: 'User API token' + }, + { + required: false, + name: :restrict_to_branch, + type: String, + desc: 'Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches' + } + ], + 'assembla' => [ + { + required: true, + name: :token, + type: String, + desc: 'The authentication token' + }, + { + required: false, + name: :subdomain, + type: String, + desc: 'Subdomain setting' + } + ], + 'bamboo' => [ + { + required: true, + name: :bamboo_url, + type: String, + desc: 'Bamboo root URL like https://bamboo.example.com' + }, + { + required: true, + name: :build_key, + type: String, + desc: 'Bamboo build plan key like' + }, + { + required: true, + name: :username, + type: String, + desc: 'A user with API access, if applicable' + }, + { + required: true, + name: :password, + type: String, + desc: 'Password of the user' + } + ], + 'bugzilla' => [ + { + required: true, + name: :new_issue_url, + type: String, + desc: 'New issue URL' + }, + { + required: true, + name: :issues_url, + type: String, + desc: 'Issues URL' + }, + { + required: true, + name: :project_url, + type: String, + desc: 'Project URL' + }, + { + required: false, + name: :description, + type: String, + desc: 'Description' + }, + { + required: false, + name: :title, + type: String, + desc: 'Title' + } + ], + 'buildkite' => [ + { + required: true, + name: :token, + type: String, + desc: 'Buildkite project GitLab token' + }, + { + required: true, + name: :project_url, + type: String, + desc: 'The buildkite project URL' + }, + { + required: false, + name: :enable_ssl_verification, + type: Boolean, + desc: 'Enable SSL verification for communication' + } + ], + 'campfire' => [ + { + required: true, + name: :token, + type: String, + desc: 'Campfire token' + }, + { + required: false, + name: :subdomain, + type: String, + desc: 'Campfire subdomain' + }, + { + required: false, + name: :room, + type: String, + desc: 'Campfire room' + } + ], + 'custom-issue-tracker' => [ + { + required: true, + name: :new_issue_url, + type: String, + desc: 'New issue URL' + }, + { + required: true, + name: :issues_url, + type: String, + desc: 'Issues URL' + }, + { + required: true, + name: :project_url, + type: String, + desc: 'Project URL' + }, + { + required: false, + name: :description, + type: String, + desc: 'Description' + }, + { + required: false, + name: :title, + type: String, + desc: 'Title' + } + ], + 'discord' => [ + { + required: true, + name: :webhook, + type: String, + desc: 'Discord webhook. e.g. https://discordapp.com/api/webhooks/…' + } + ], + 'drone-ci' => [ + { + required: true, + name: :token, + type: String, + desc: 'Drone CI token' + }, + { + required: true, + name: :drone_url, + type: String, + desc: 'Drone CI URL' + }, + { + required: false, + name: :enable_ssl_verification, + type: Boolean, + desc: 'Enable SSL verification for communication' + } + ], + 'emails-on-push' => [ + { + required: true, + name: :recipients, + type: String, + desc: 'Comma-separated list of recipient email addresses' + }, + { + required: false, + name: :disable_diffs, + type: Boolean, + desc: 'Disable code diffs' + }, + { + required: false, + name: :send_from_committer_email, + type: Boolean, + desc: 'Send from committer' + } + ], + 'external-wiki' => [ + { + required: true, + name: :external_wiki_url, + type: String, + desc: 'The URL of the external Wiki' + } + ], + 'flowdock' => [ + { + required: true, + name: :token, + type: String, + desc: 'Flowdock token' + } + ], + 'hangouts-chat' => [ + { + required: true, + name: :webhook, + type: String, + desc: 'The Hangouts Chat webhook. e.g. https://chat.googleapis.com/v1/spaces…' + }, + chat_notification_events + ].flatten, + 'irker' => [ + { + required: true, + name: :recipients, + type: String, + desc: 'Recipients/channels separated by whitespaces' + }, + { + required: false, + name: :default_irc_uri, + type: String, + desc: 'Default: irc://irc.network.net:6697' + }, + { + required: false, + name: :server_host, + type: String, + desc: 'Server host. Default localhost' + }, + { + required: false, + name: :server_port, + type: Integer, + desc: 'Server port. Default 6659' + }, + { + required: false, + name: :colorize_messages, + type: Boolean, + desc: 'Colorize messages' + } + ], + 'jira' => [ + { + required: true, + name: :url, + type: String, + desc: 'The base URL to the JIRA instance web interface which is being linked to this GitLab project. E.g., https://jira.example.com' + }, + { + required: false, + name: :api_url, + type: String, + desc: 'The base URL to the JIRA instance API. Web URL value will be used if not set. E.g., https://jira-api.example.com' + }, + { + required: true, + name: :username, + type: String, + desc: 'The username of the user created to be used with GitLab/JIRA' + }, + { + required: true, + name: :password, + type: String, + desc: 'The password of the user created to be used with GitLab/JIRA' + }, + { + required: false, + name: :jira_issue_transition_id, + type: String, + desc: 'The ID of a transition that moves issues to a closed state. You can find this number under the JIRA workflow administration (**Administration > Issues > Workflows**) by selecting **View** under **Operations** of the desired workflow of your project. The ID of each state can be found inside the parenthesis of each transition name under the **Transitions (id)** column ([see screenshot][trans]). By default, this ID is set to `2`' + } + ], + 'kubernetes' => [ + { + required: true, + name: :namespace, + type: String, + desc: 'The Kubernetes namespace to use' + }, + { + required: true, + name: :api_url, + type: String, + desc: 'The URL to the Kubernetes cluster API, e.g., https://kubernetes.example.com' + }, + { + required: true, + name: :token, + type: String, + desc: 'The service token to authenticate against the Kubernetes cluster with' + }, + { + required: false, + name: :ca_pem, + type: String, + desc: 'A custom certificate authority bundle to verify the Kubernetes cluster with (PEM format)' + } + ], + 'mattermost-slash-commands' => [ + { + required: true, + name: :token, + type: String, + desc: 'The Mattermost token' + } + ], + 'slack-slash-commands' => [ + { + required: true, + name: :token, + type: String, + desc: 'The Slack token' + } + ], + 'packagist' => [ + { + required: true, + name: :username, + type: String, + desc: 'The username' + }, + { + required: true, + name: :token, + type: String, + desc: 'The Packagist API token' + }, + { + required: false, + name: :server, + type: String, + desc: 'The server' + } + ], + 'pipelines-email' => [ + { + required: true, + name: :recipients, + type: String, + desc: 'Comma-separated list of recipient email addresses' + }, + { + required: false, + name: :notify_only_broken_pipelines, + type: Boolean, + desc: 'Notify only broken pipelines' + } + ], + 'pivotaltracker' => [ + { + required: true, + name: :token, + type: String, + desc: 'The Pivotaltracker token' + }, + { + required: false, + name: :restrict_to_branch, + type: String, + desc: 'Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches.' + } + ], + 'prometheus' => [ + { + required: true, + name: :api_url, + type: String, + desc: 'Prometheus API Base URL, like http://prometheus.example.com/' + } + ], + 'pushover' => [ + { + required: true, + name: :api_key, + type: String, + desc: 'The application key' + }, + { + required: true, + name: :user_key, + type: String, + desc: 'The user key' + }, + { + required: true, + name: :priority, + type: String, + desc: 'The priority' + }, + { + required: true, + name: :device, + type: String, + desc: 'Leave blank for all active devices' + }, + { + required: true, + name: :sound, + type: String, + desc: 'The sound of the notification' + } + ], + 'redmine' => [ + { + required: true, + name: :new_issue_url, + type: String, + desc: 'The new issue URL' + }, + { + required: true, + name: :project_url, + type: String, + desc: 'The project URL' + }, + { + required: true, + name: :issues_url, + type: String, + desc: 'The issues URL' + }, + { + required: false, + name: :description, + type: String, + desc: 'The description of the tracker' + } + ], + 'youtrack' => [ + { + required: true, + name: :project_url, + type: String, + desc: 'The project URL' + }, + { + required: true, + name: :issues_url, + type: String, + desc: 'The issues URL' + }, + { + required: false, + name: :description, + type: String, + desc: 'The description of the tracker' + } + ], + 'slack' => [ + chat_notification_settings, + chat_notification_flags, + chat_notification_channels, + chat_notification_events + ].flatten, + 'microsoft-teams' => [ + { + required: true, + name: :webhook, + type: String, + desc: 'The Microsoft Teams webhook. e.g. https://outlook.office.com/webhook/…' + } + ], + 'mattermost' => [ + chat_notification_settings, + chat_notification_flags, + chat_notification_channels, + chat_notification_events + ].flatten, + 'teamcity' => [ + { + required: true, + name: :teamcity_url, + type: String, + desc: 'TeamCity root URL like https://teamcity.example.com' + }, + { + required: true, + name: :build_type, + type: String, + desc: 'Build configuration ID' + }, + { + required: true, + name: :username, + type: String, + desc: 'A user with permissions to trigger a manual build' + }, + { + required: true, + name: :password, + type: String, + desc: 'The password of the user' + } + ] + } + end + + def self.service_classes + [ + ::AsanaService, + ::AssemblaService, + ::BambooService, + ::BugzillaService, + ::BuildkiteService, + ::CampfireService, + ::CustomIssueTrackerService, + ::DiscordService, + ::DroneCiService, + ::EmailsOnPushService, + ::ExternalWikiService, + ::FlowdockService, + ::HangoutsChatService, + ::IrkerService, + ::JiraService, + ::KubernetesService, + ::MattermostSlashCommandsService, + ::SlackSlashCommandsService, + ::PackagistService, + ::PipelinesEmailService, + ::PivotaltrackerService, + ::PrometheusService, + ::PushoverService, + ::RedmineService, + ::YoutrackService, + ::SlackService, + ::MattermostService, + ::MicrosoftTeamsService, + ::TeamcityService + ] + end + + def self.development_service_classes + [ + ::MockCiService, + ::MockDeploymentService, + ::MockMonitoringService + ] + end + end + end +end diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 73fda55bac2..7f4a00f1389 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -15,6 +15,12 @@ module API status code { status: success, message: message }.merge(extra_options).compact end + + def lfs_authentication_url(project) + # This is a separate method so that EE can alter its behaviour more + # easily. + project.http_url_to_repo + end end namespace 'internal' do @@ -113,7 +119,9 @@ module API raise ActiveRecord::RecordNotFound.new("No key_id or user_id passed!") end - Gitlab::LfsToken.new(actor).authentication_payload(project.http_url_to_repo) + Gitlab::LfsToken + .new(actor) + .authentication_payload(lfs_authentication_url(project)) end # rubocop: enable CodeReuse/ActiveRecord diff --git a/lib/api/notes.rb b/lib/api/notes.rb index f7bd092ce50..416cf39d3ec 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -7,9 +7,7 @@ module API before { authenticate! } - NOTEABLE_TYPES = [Issue, MergeRequest, Snippet].freeze - - NOTEABLE_TYPES.each do |noteable_type| + Helpers::NotesHelpers.noteable_types.each do |noteable_type| parent_type = noteable_type.parent_class.to_s.underscore noteables_str = noteable_type.to_s.underscore.pluralize diff --git a/lib/api/resource_label_events.rb b/lib/api/resource_label_events.rb index 0c328f7268e..448bef12cec 100644 --- a/lib/api/resource_label_events.rb +++ b/lib/api/resource_label_events.rb @@ -7,9 +7,7 @@ module API before { authenticate! } - EVENTABLE_TYPES = [Issue, MergeRequest].freeze - - EVENTABLE_TYPES.each do |eventable_type| + Helpers::ResourceLabelEventsHelpers.eventable_types.each do |eventable_type| parent_type = eventable_type.parent_class.to_s.underscore eventables_str = eventable_type.to_s.underscore.pluralize diff --git a/lib/api/search.rb b/lib/api/search.rb index f5db692afe5..f65e810bf90 100644 --- a/lib/api/search.rb +++ b/lib/api/search.rb @@ -45,6 +45,12 @@ module API def entity SCOPE_ENTITY[params[:scope].to_sym] end + + def verify_search_scope! + # In EE we have additional validation requirements for searches. + # Defining this method here as a noop allows us to easily extend it in + # EE, without having to modify this file directly. + end end resource :search do @@ -55,12 +61,13 @@ module API requires :search, type: String, desc: 'The expression it should be searched for' requires :scope, type: String, - desc: 'The scope of search, available scopes: - projects, issues, merge_requests, milestones, snippet_titles, snippet_blobs', - values: %w(projects issues merge_requests milestones snippet_titles snippet_blobs) + desc: 'The scope of the search', + values: Helpers::SearchHelpers.global_search_scopes use :pagination end get do + verify_search_scope! + present search, with: entity end end @@ -74,12 +81,13 @@ module API requires :search, type: String, desc: 'The expression it should be searched for' requires :scope, type: String, - desc: 'The scope of search, available scopes: - projects, issues, merge_requests, milestones', - values: %w(projects issues merge_requests milestones) + desc: 'The scope of the search', + values: Helpers::SearchHelpers.group_search_scopes use :pagination end get ':id/(-/)search' do + verify_search_scope! + present search(group_id: user_group.id), with: entity end end @@ -93,9 +101,8 @@ module API requires :search, type: String, desc: 'The expression it should be searched for' requires :scope, type: String, - desc: 'The scope of search, available scopes: - issues, merge_requests, milestones, notes, wiki_blobs, commits, blobs', - values: %w(issues merge_requests milestones notes wiki_blobs commits blobs) + desc: 'The scope of the search', + values: Helpers::SearchHelpers.project_search_scopes use :pagination end get ':id/(-/)search' do diff --git a/lib/api/services.rb b/lib/api/services.rb index bda6be51553..bc77fae87fa 100644 --- a/lib/api/services.rb +++ b/lib/api/services.rb @@ -1,696 +1,8 @@ # frozen_string_literal: true module API class Services < Grape::API - CHAT_NOTIFICATION_SETTINGS = [ - { - required: true, - name: :webhook, - type: String, - desc: 'The chat webhook' - }, - { - required: false, - name: :username, - type: String, - desc: 'The chat username' - }, - { - required: false, - name: :channel, - type: String, - desc: 'The default chat channel' - } - ].freeze - - CHAT_NOTIFICATION_FLAGS = [ - { - required: false, - name: :notify_only_broken_pipelines, - type: Boolean, - desc: 'Send notifications for broken pipelines' - }, - { - required: false, - name: :notify_only_default_branch, - type: Boolean, - desc: 'Send notifications only for the default branch' - } - ].freeze - - CHAT_NOTIFICATION_CHANNELS = [ - { - required: false, - name: :push_channel, - type: String, - desc: 'The name of the channel to receive push_events notifications' - }, - { - required: false, - name: :issue_channel, - type: String, - desc: 'The name of the channel to receive issues_events notifications' - }, - { - required: false, - name: :confidential_issue_channel, - type: String, - desc: 'The name of the channel to receive confidential_issues_events notifications' - }, - { - required: false, - name: :merge_request_channel, - type: String, - desc: 'The name of the channel to receive merge_requests_events notifications' - }, - { - required: false, - name: :note_channel, - type: String, - desc: 'The name of the channel to receive note_events notifications' - }, - { - required: false, - name: :tag_push_channel, - type: String, - desc: 'The name of the channel to receive tag_push_events notifications' - }, - { - required: false, - name: :pipeline_channel, - type: String, - desc: 'The name of the channel to receive pipeline_events notifications' - }, - { - required: false, - name: :wiki_page_channel, - type: String, - desc: 'The name of the channel to receive wiki_page_events notifications' - } - ].freeze - - CHAT_NOTIFICATION_EVENTS = [ - { - required: false, - name: :push_events, - type: Boolean, - desc: 'Enable notifications for push_events' - }, - { - required: false, - name: :issues_events, - type: Boolean, - desc: 'Enable notifications for issues_events' - }, - { - required: false, - name: :confidential_issues_events, - type: Boolean, - desc: 'Enable notifications for confidential_issues_events' - }, - { - required: false, - name: :merge_requests_events, - type: Boolean, - desc: 'Enable notifications for merge_requests_events' - }, - { - required: false, - name: :note_events, - type: Boolean, - desc: 'Enable notifications for note_events' - }, - { - required: false, - name: :tag_push_events, - type: Boolean, - desc: 'Enable notifications for tag_push_events' - }, - { - required: false, - name: :pipeline_events, - type: Boolean, - desc: 'Enable notifications for pipeline_events' - }, - { - required: false, - name: :wiki_page_events, - type: Boolean, - desc: 'Enable notifications for wiki_page_events' - } - ].freeze - - services = { - 'asana' => [ - { - required: true, - name: :api_key, - type: String, - desc: 'User API token' - }, - { - required: false, - name: :restrict_to_branch, - type: String, - desc: 'Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches' - } - ], - 'assembla' => [ - { - required: true, - name: :token, - type: String, - desc: 'The authentication token' - }, - { - required: false, - name: :subdomain, - type: String, - desc: 'Subdomain setting' - } - ], - 'bamboo' => [ - { - required: true, - name: :bamboo_url, - type: String, - desc: 'Bamboo root URL like https://bamboo.example.com' - }, - { - required: true, - name: :build_key, - type: String, - desc: 'Bamboo build plan key like' - }, - { - required: true, - name: :username, - type: String, - desc: 'A user with API access, if applicable' - }, - { - required: true, - name: :password, - type: String, - desc: 'Passord of the user' - } - ], - 'bugzilla' => [ - { - required: true, - name: :new_issue_url, - type: String, - desc: 'New issue URL' - }, - { - required: true, - name: :issues_url, - type: String, - desc: 'Issues URL' - }, - { - required: true, - name: :project_url, - type: String, - desc: 'Project URL' - }, - { - required: false, - name: :description, - type: String, - desc: 'Description' - }, - { - required: false, - name: :title, - type: String, - desc: 'Title' - } - ], - 'buildkite' => [ - { - required: true, - name: :token, - type: String, - desc: 'Buildkite project GitLab token' - }, - { - required: true, - name: :project_url, - type: String, - desc: 'The buildkite project URL' - }, - { - required: false, - name: :enable_ssl_verification, - type: Boolean, - desc: 'Enable SSL verification for communication' - } - ], - 'campfire' => [ - { - required: true, - name: :token, - type: String, - desc: 'Campfire token' - }, - { - required: false, - name: :subdomain, - type: String, - desc: 'Campfire subdomain' - }, - { - required: false, - name: :room, - type: String, - desc: 'Campfire room' - } - ], - 'custom-issue-tracker' => [ - { - required: true, - name: :new_issue_url, - type: String, - desc: 'New issue URL' - }, - { - required: true, - name: :issues_url, - type: String, - desc: 'Issues URL' - }, - { - required: true, - name: :project_url, - type: String, - desc: 'Project URL' - }, - { - required: false, - name: :description, - type: String, - desc: 'Description' - }, - { - required: false, - name: :title, - type: String, - desc: 'Title' - } - ], - 'discord' => [ - { - required: true, - name: :webhook, - type: String, - desc: 'Discord webhook. e.g. https://discordapp.com/api/webhooks/…' - } - ], - 'drone-ci' => [ - { - required: true, - name: :token, - type: String, - desc: 'Drone CI token' - }, - { - required: true, - name: :drone_url, - type: String, - desc: 'Drone CI URL' - }, - { - required: false, - name: :enable_ssl_verification, - type: Boolean, - desc: 'Enable SSL verification for communication' - } - ], - 'emails-on-push' => [ - { - required: true, - name: :recipients, - type: String, - desc: 'Comma-separated list of recipient email addresses' - }, - { - required: false, - name: :disable_diffs, - type: Boolean, - desc: 'Disable code diffs' - }, - { - required: false, - name: :send_from_committer_email, - type: Boolean, - desc: 'Send from committer' - } - ], - 'external-wiki' => [ - { - required: true, - name: :external_wiki_url, - type: String, - desc: 'The URL of the external Wiki' - } - ], - 'flowdock' => [ - { - required: true, - name: :token, - type: String, - desc: 'Flowdock token' - } - ], - 'hangouts-chat' => [ - { - required: true, - name: :webhook, - type: String, - desc: 'The Hangouts Chat webhook. e.g. https://chat.googleapis.com/v1/spaces…' - }, - CHAT_NOTIFICATION_EVENTS - ].flatten, - 'irker' => [ - { - required: true, - name: :recipients, - type: String, - desc: 'Recipients/channels separated by whitespaces' - }, - { - required: false, - name: :default_irc_uri, - type: String, - desc: 'Default: irc://irc.network.net:6697' - }, - { - required: false, - name: :server_host, - type: String, - desc: 'Server host. Default localhost' - }, - { - required: false, - name: :server_port, - type: Integer, - desc: 'Server port. Default 6659' - }, - { - required: false, - name: :colorize_messages, - type: Boolean, - desc: 'Colorize messages' - } - ], - 'jira' => [ - { - required: true, - name: :url, - type: String, - desc: 'The base URL to the JIRA instance web interface which is being linked to this GitLab project. E.g., https://jira.example.com' - }, - { - required: false, - name: :api_url, - type: String, - desc: 'The base URL to the JIRA instance API. Web URL value will be used if not set. E.g., https://jira-api.example.com' - }, - { - required: true, - name: :username, - type: String, - desc: 'The username of the user created to be used with GitLab/JIRA' - }, - { - required: true, - name: :password, - type: String, - desc: 'The password of the user created to be used with GitLab/JIRA' - }, - { - required: false, - name: :jira_issue_transition_id, - type: String, - desc: 'The ID of a transition that moves issues to a closed state. You can find this number under the JIRA workflow administration (**Administration > Issues > Workflows**) by selecting **View** under **Operations** of the desired workflow of your project. The ID of each state can be found inside the parenthesis of each transition name under the **Transitions (id)** column ([see screenshot][trans]). By default, this ID is set to `2`' - } - ], - - 'kubernetes' => [ - { - required: true, - name: :namespace, - type: String, - desc: 'The Kubernetes namespace to use' - }, - { - required: true, - name: :api_url, - type: String, - desc: 'The URL to the Kubernetes cluster API, e.g., https://kubernetes.example.com' - }, - { - required: true, - name: :token, - type: String, - desc: 'The service token to authenticate against the Kubernetes cluster with' - }, - { - required: false, - name: :ca_pem, - type: String, - desc: 'A custom certificate authority bundle to verify the Kubernetes cluster with (PEM format)' - } - ], - 'mattermost-slash-commands' => [ - { - required: true, - name: :token, - type: String, - desc: 'The Mattermost token' - } - ], - 'slack-slash-commands' => [ - { - required: true, - name: :token, - type: String, - desc: 'The Slack token' - } - ], - 'packagist' => [ - { - required: true, - name: :username, - type: String, - desc: 'The username' - }, - { - required: true, - name: :token, - type: String, - desc: 'The Packagist API token' - }, - { - required: false, - name: :server, - type: String, - desc: 'The server' - } - ], - 'pipelines-email' => [ - { - required: true, - name: :recipients, - type: String, - desc: 'Comma-separated list of recipient email addresses' - }, - { - required: false, - name: :notify_only_broken_pipelines, - type: Boolean, - desc: 'Notify only broken pipelines' - } - ], - 'pivotaltracker' => [ - { - required: true, - name: :token, - type: String, - desc: 'The Pivotaltracker token' - }, - { - required: false, - name: :restrict_to_branch, - type: String, - desc: 'Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches.' - } - ], - 'prometheus' => [ - { - required: true, - name: :api_url, - type: String, - desc: 'Prometheus API Base URL, like http://prometheus.example.com/' - } - ], - 'pushover' => [ - { - required: true, - name: :api_key, - type: String, - desc: 'The application key' - }, - { - required: true, - name: :user_key, - type: String, - desc: 'The user key' - }, - { - required: true, - name: :priority, - type: String, - desc: 'The priority' - }, - { - required: true, - name: :device, - type: String, - desc: 'Leave blank for all active devices' - }, - { - required: true, - name: :sound, - type: String, - desc: 'The sound of the notification' - } - ], - 'redmine' => [ - { - required: true, - name: :new_issue_url, - type: String, - desc: 'The new issue URL' - }, - { - required: true, - name: :project_url, - type: String, - desc: 'The project URL' - }, - { - required: true, - name: :issues_url, - type: String, - desc: 'The issues URL' - }, - { - required: false, - name: :description, - type: String, - desc: 'The description of the tracker' - } - ], - 'youtrack' => [ - { - required: true, - name: :project_url, - type: String, - desc: 'The project URL' - }, - { - required: true, - name: :issues_url, - type: String, - desc: 'The issues URL' - }, - { - required: false, - name: :description, - type: String, - desc: 'The description of the tracker' - } - ], - 'slack' => [ - CHAT_NOTIFICATION_SETTINGS, - CHAT_NOTIFICATION_FLAGS, - CHAT_NOTIFICATION_CHANNELS, - CHAT_NOTIFICATION_EVENTS - ].flatten, - 'microsoft-teams' => [ - { - required: true, - name: :webhook, - type: String, - desc: 'The Microsoft Teams webhook. e.g. https://outlook.office.com/webhook/…' - } - ], - 'mattermost' => [ - CHAT_NOTIFICATION_SETTINGS, - CHAT_NOTIFICATION_FLAGS, - CHAT_NOTIFICATION_CHANNELS, - CHAT_NOTIFICATION_EVENTS - ].flatten, - 'teamcity' => [ - { - required: true, - name: :teamcity_url, - type: String, - desc: 'TeamCity root URL like https://teamcity.example.com' - }, - { - required: true, - name: :build_type, - type: String, - desc: 'Build configuration ID' - }, - { - required: true, - name: :username, - type: String, - desc: 'A user with permissions to trigger a manual build' - }, - { - required: true, - name: :password, - type: String, - desc: 'The password of the user' - } - ] - } - - service_classes = [ - AsanaService, - AssemblaService, - BambooService, - BugzillaService, - BuildkiteService, - CampfireService, - CustomIssueTrackerService, - DiscordService, - DroneCiService, - EmailsOnPushService, - ExternalWikiService, - FlowdockService, - HangoutsChatService, - IrkerService, - JiraService, - KubernetesService, - MattermostSlashCommandsService, - SlackSlashCommandsService, - PackagistService, - PipelinesEmailService, - PivotaltrackerService, - PrometheusService, - PushoverService, - RedmineService, - YoutrackService, - SlackService, - MattermostService, - MicrosoftTeamsService, - TeamcityService - ] + services = Helpers::ServicesHelpers.services + service_classes = Helpers::ServicesHelpers.service_classes if Rails.env.development? services['mock-ci'] = [ @@ -704,11 +16,7 @@ module API services['mock-deployment'] = [] services['mock-monitoring'] = [] - service_classes += [ - MockCiService, - MockDeploymentService, - MockMonitoringService - ] + service_classes += Helpers::ServicesHelpers.development_service_classes end SERVICES = services.freeze diff --git a/lib/api/settings.rb b/lib/api/settings.rb index b16faffe335..3cb2f69c4ef 100644 --- a/lib/api/settings.rb +++ b/lib/api/settings.rb @@ -9,6 +9,11 @@ module API @current_setting ||= (ApplicationSetting.current_without_cache || ApplicationSetting.create_from_defaults) end + + def filter_attributes_using_license(attrs) + # This method will be redefined in EE. + attrs + end end desc 'Get the current application settings' do @@ -156,6 +161,8 @@ module API attrs[:password_authentication_enabled_for_web] = attrs.delete(:password_authentication_enabled) end + attrs = filter_attributes_using_license(attrs) + if ApplicationSettings::UpdateService.new(current_settings, current_user, attrs).execute present current_settings, with: Entities::ApplicationSetting else diff --git a/lib/api/triggers.rb b/lib/api/triggers.rb index 8fc7c7361e1..0e829c5699b 100644 --- a/lib/api/triggers.rb +++ b/lib/api/triggers.rb @@ -13,7 +13,7 @@ module API end params do requires :ref, type: String, desc: 'The commit sha or name of a branch or tag', allow_blank: false - requires :token, type: String, desc: 'The unique token of trigger' + requires :token, type: String, desc: 'The unique token of trigger or job token' optional :variables, type: Hash, desc: 'The list of variables to be injected into build' end post ":id/(ref/:ref/)trigger/pipeline", requirements: { ref: /.+/ } do diff --git a/lib/api/variables.rb b/lib/api/variables.rb index 148deb86c4c..d0d81ebc870 100644 --- a/lib/api/variables.rb +++ b/lib/api/variables.rb @@ -7,6 +7,14 @@ module API before { authenticate! } before { authorize! :admin_build, user_project } + helpers do + def filter_variable_parameters(params) + # This method exists so that EE can more easily filter out certain + # parameters, without having to modify the source code directly. + params + end + end + params do requires :id, type: String, desc: 'The ID of a project' end @@ -50,6 +58,7 @@ module API end post ':id/variables' do variable_params = declared_params(include_missing: false) + variable_params = filter_variable_parameters(variable_params) variable = user_project.variables.create(variable_params) @@ -75,6 +84,7 @@ module API break not_found!('Variable') unless variable variable_params = declared_params(include_missing: false).except(:key) + variable_params = filter_variable_parameters(variable_params) if variable.update(variable_params) present variable, with: Entities::Variable |