Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-05-07 00:10:00 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-05-07 00:10:00 +0300
commit5f0e3773e9695fd0c9e92ea9180c8a1f5cfaa5c5 (patch)
tree64fc0ecbf508a24345ffe11d856fd13124c2e464 /app
parent73886079f3f877ffb8f8938d700643a5e99bc849 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/integrations/edit/components/integration_form.vue42
-rw-r--r--app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue99
-rw-r--r--app/assets/javascripts/integrations/edit/index.js37
-rw-r--r--app/controllers/admin/application_settings_controller.rb2
-rw-r--r--app/helpers/x509_helper.rb4
-rw-r--r--app/models/application_setting.rb2
-rw-r--r--app/models/merge_request_diff.rb8
-rw-r--r--app/models/project_services/jira_service.rb61
-rw-r--r--app/models/snippet_repository.rb18
-rw-r--r--app/models/x509_commit_signature.rb4
-rw-r--r--app/views/projects/commit/_signature.html.haml2
-rw-r--r--app/views/projects/commit/_signature_badge.html.haml6
-rw-r--r--app/views/projects/commit/x509/_signature_badge_user.html.haml2
-rw-r--r--app/views/projects/tags/_tag.html.haml3
-rw-r--r--app/views/projects/tags/show.html.haml2
-rw-r--r--app/views/shared/_service_settings.html.haml21
16 files changed, 268 insertions, 45 deletions
diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue
new file mode 100644
index 00000000000..ab6a3f97bfd
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue
@@ -0,0 +1,42 @@
+<script>
+import ActiveToggle from './active_toggle.vue';
+import JiraTriggerFields from './jira_trigger_fields.vue';
+
+export default {
+ name: 'IntegrationForm',
+ components: {
+ ActiveToggle,
+ JiraTriggerFields,
+ },
+ props: {
+ activeToggleProps: {
+ type: Object,
+ required: true,
+ },
+ showActive: {
+ type: Boolean,
+ required: true,
+ },
+ triggerFieldsProps: {
+ type: Object,
+ required: true,
+ },
+ type: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ isJira() {
+ return this.type === 'jira';
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <active-toggle v-if="showActive" v-bind="activeToggleProps" />
+ <jira-trigger-fields v-if="isJira" v-bind="triggerFieldsProps" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
new file mode 100644
index 00000000000..70278e401ce
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
@@ -0,0 +1,99 @@
+<script>
+import { GlFormCheckbox, GlFormRadio } from '@gitlab/ui';
+
+export default {
+ name: 'JiraTriggerFields',
+ components: {
+ GlFormCheckbox,
+ GlFormRadio,
+ },
+ props: {
+ initialTriggerCommit: {
+ type: Boolean,
+ required: true,
+ },
+ initialTriggerMergeRequest: {
+ type: Boolean,
+ required: true,
+ },
+ initialEnableComments: {
+ type: Boolean,
+ required: true,
+ },
+ initialCommentDetail: {
+ type: String,
+ required: false,
+ default: 'standard',
+ },
+ },
+ data() {
+ return {
+ triggerCommit: this.initialTriggerCommit,
+ triggerMergeRequest: this.initialTriggerMergeRequest,
+ enableComments: this.initialEnableComments,
+ commentDetail: this.initialCommentDetail,
+ };
+ },
+};
+</script>
+
+<template>
+ <div class="form-group row pt-2" role="group">
+ <label for="service[trigger]" class="col-form-label col-sm-2 pt-0">{{ __('Trigger') }}</label>
+ <div class="col-sm-10">
+ <label class="weight-normal mb-2">
+ {{
+ s__(
+ 'Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created.',
+ )
+ }}
+ </label>
+
+ <input name="service[commit_events]" type="hidden" value="false" />
+ <gl-form-checkbox v-model="triggerCommit" name="service[commit_events]">
+ {{ __('Commit') }}
+ </gl-form-checkbox>
+
+ <input name="service[merge_requests_events]" type="hidden" value="false" />
+ <gl-form-checkbox v-model="triggerMergeRequest" name="service[merge_requests_events]">
+ {{ __('Merge request') }}
+ </gl-form-checkbox>
+
+ <div
+ v-show="triggerCommit || triggerMergeRequest"
+ class="mt-4"
+ data-testid="comment-settings"
+ >
+ <label>
+ {{ s__('Integrations|Comment settings:') }}
+ </label>
+ <input name="service[comment_on_event_enabled]" type="hidden" value="false" />
+ <gl-form-checkbox v-model="enableComments" name="service[comment_on_event_enabled]">
+ {{ s__('Integrations|Enable comments') }}
+ </gl-form-checkbox>
+
+ <div v-show="enableComments" class="mt-4" data-testid="comment-detail">
+ <label>
+ {{ s__('Integrations|Comment detail:') }}
+ </label>
+ <gl-form-radio v-model="commentDetail" value="standard" name="service[comment_detail]">
+ {{ s__('Integrations|Standard') }}
+ <template #help>
+ {{ s__('Integrations|Includes commit title and branch') }}
+ </template>
+ </gl-form-radio>
+ <gl-form-radio v-model="commentDetail" value="all_details" name="service[comment_detail]">
+ {{ s__('Integrations|All details') }}
+ <template #help>
+ {{
+ s__(
+ 'Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs',
+ )
+ }}
+ </template>
+ </gl-form-radio>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/integrations/edit/index.js b/app/assets/javascripts/integrations/edit/index.js
index 25ae6015f1d..7b476528a33 100644
--- a/app/assets/javascripts/integrations/edit/index.js
+++ b/app/assets/javascripts/integrations/edit/index.js
@@ -1,26 +1,45 @@
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
-import ActiveToggle from './components/active_toggle.vue';
+import IntegrationForm from './components/integration_form.vue';
export default el => {
if (!el) {
return null;
}
- const { showActive: showActiveStr, activated: activatedStr } = el.dataset;
- const showActive = parseBoolean(showActiveStr);
- const activated = parseBoolean(activatedStr);
-
- if (!showActive) {
- return null;
+ function parseBooleanInData(data) {
+ const result = {};
+ Object.entries(data).forEach(([key, value]) => {
+ result[key] = parseBoolean(value);
+ });
+ return result;
}
+ const { type, commentDetail, ...booleanAttributes } = el.dataset;
+ const {
+ showActive,
+ activated,
+ commitEvents,
+ mergeRequestEvents,
+ enableComments,
+ } = parseBooleanInData(booleanAttributes);
+
return new Vue({
el,
render(createElement) {
- return createElement(ActiveToggle, {
+ return createElement(IntegrationForm, {
props: {
- initialActivated: activated,
+ activeToggleProps: {
+ initialActivated: activated,
+ },
+ showActive,
+ type,
+ triggerFieldsProps: {
+ initialTriggerCommit: commitEvents,
+ initialTriggerMergeRequest: mergeRequestEvents,
+ initialEnableComments: enableComments,
+ initialCommentDetail: commentDetail,
+ },
},
});
},
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 942bb4b6b0e..355662bbb38 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -5,7 +5,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
# NOTE: Use @application_setting in this controller when you need to access
# application_settings after it has been modified. This is because the
- # ApplicationSetting model uses Gitlab::ThreadMemoryCache for caching and the
+ # ApplicationSetting model uses Gitlab::ProcessMemoryCache for caching and the
# cache might be stale immediately after an update.
# https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30233
before_action :set_application_setting, except: :integrations
diff --git a/app/helpers/x509_helper.rb b/app/helpers/x509_helper.rb
index c330b599d74..009635fb629 100644
--- a/app/helpers/x509_helper.rb
+++ b/app/helpers/x509_helper.rb
@@ -16,4 +16,8 @@ module X509Helper
rescue
{}
end
+
+ def x509_signature?(sig)
+ sig.is_a?(X509CommitSignature) || sig.is_a?(Gitlab::X509::Signature)
+ end
end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index f9481db2268..d13f0a1a000 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -421,7 +421,7 @@ class ApplicationSetting < ApplicationRecord
# can cause a significant amount of load on Redis, let's cache it in
# memory.
def self.cache_backend
- Gitlab::ThreadMemoryCache.cache_backend
+ Gitlab::ProcessMemoryCache.cache_backend
end
def recaptcha_or_login_protection_enabled
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index 7b15d21c095..ea3e00d9cd3 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -141,7 +141,7 @@ class MergeRequestDiff < ApplicationRecord
after_create :save_git_content, unless: :importing?
after_create_commit :set_as_latest_diff, unless: :importing?
- after_save :update_external_diff_store, if: -> { !importing? && saved_change_to_external_diff? }
+ after_save :update_external_diff_store
def self.find_by_diff_refs(diff_refs)
find_by(start_commit_sha: diff_refs.start_sha, head_commit_sha: diff_refs.head_sha, base_commit_sha: diff_refs.base_sha)
@@ -401,8 +401,10 @@ class MergeRequestDiff < ApplicationRecord
end
def update_external_diff_store
- update_column(:external_diff_store, external_diff.object_store) if
- has_attribute?(:external_diff_store)
+ return unless has_attribute?(:external_diff_store)
+ return unless saved_change_to_external_diff? || saved_change_to_stored_externally?
+
+ update_column(:external_diff_store, external_diff.object_store)
end
def saved_change_to_external_diff?
diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb
index f0a5d8e8cdd..53da874ede8 100644
--- a/app/models/project_services/jira_service.rb
+++ b/app/models/project_services/jira_service.rb
@@ -177,6 +177,7 @@ class JiraService < IssueTrackerService
noteable_id = noteable.respond_to?(:iid) ? noteable.iid : noteable.id
noteable_type = noteable_name(noteable)
entity_url = build_entity_url(noteable_type, noteable_id)
+ entity_meta = build_entity_meta(noteable)
data = {
user: {
@@ -185,12 +186,15 @@ class JiraService < IssueTrackerService
},
project: {
name: project.full_path,
- url: resource_url(namespace_project_path(project.namespace, project)) # rubocop:disable Cop/ProjectPathHelper
+ url: resource_url(project_path(project))
},
entity: {
+ id: entity_meta[:id],
name: noteable_type.humanize.downcase,
url: entity_url,
- title: noteable.title
+ title: noteable.title,
+ description: entity_meta[:description],
+ branch: entity_meta[:branch]
}
}
@@ -264,14 +268,11 @@ class JiraService < IssueTrackerService
end
def add_comment(data, issue)
- user_name = data[:user][:name]
- user_url = data[:user][:url]
entity_name = data[:entity][:name]
entity_url = data[:entity][:url]
entity_title = data[:entity][:title]
- project_name = data[:project][:name]
- message = "[#{user_name}|#{user_url}] mentioned this issue in [a #{entity_name} of #{project_name}|#{entity_url}]:\n'#{entity_title.chomp}'"
+ message = comment_message(data)
link_title = "#{entity_name.capitalize} - #{entity_title}"
link_props = build_remote_link_props(url: entity_url, title: link_title)
@@ -280,6 +281,37 @@ class JiraService < IssueTrackerService
end
end
+ def comment_message(data)
+ user_link = build_jira_link(data[:user][:name], data[:user][:url])
+
+ entity = data[:entity]
+ entity_ref = all_details? ? "#{entity[:name]} #{entity[:id]}" : "a #{entity[:name]}"
+ entity_link = build_jira_link(entity_ref, entity[:url])
+
+ project_link = build_jira_link(project.full_name, Gitlab::Routing.url_helpers.project_url(project))
+ branch =
+ if entity[:branch].present?
+ s_('JiraService| on branch %{branch_link}') % {
+ branch_link: build_jira_link(entity[:branch], project_tree_url(project, entity[:branch]))
+ }
+ end
+
+ entity_message = entity[:description].presence if all_details?
+ entity_message ||= entity[:title].chomp
+
+ s_('JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}') % {
+ user_link: user_link,
+ entity_link: entity_link,
+ project_link: project_link,
+ branch: branch,
+ entity_message: entity_message
+ }
+ end
+
+ def build_jira_link(title, url)
+ "[#{title}|#{url}]"
+ end
+
def has_resolution?(issue)
issue.respond_to?(:resolution) && issue.resolution.present?
end
@@ -353,6 +385,23 @@ class JiraService < IssueTrackerService
)
end
+ def build_entity_meta(noteable)
+ if noteable.is_a?(Commit)
+ {
+ id: noteable.short_id,
+ description: noteable.safe_message,
+ branch: noteable.ref_names(project.repository).first
+ }
+ elsif noteable.is_a?(MergeRequest)
+ {
+ id: noteable.to_reference,
+ branch: noteable.source_branch
+ }
+ else
+ {}
+ end
+ end
+
def noteable_name(noteable)
name = noteable.model_name.singular
diff --git a/app/models/snippet_repository.rb b/app/models/snippet_repository.rb
index e60dbb4d141..1e7c069cfaa 100644
--- a/app/models/snippet_repository.rb
+++ b/app/models/snippet_repository.rb
@@ -7,6 +7,7 @@ class SnippetRepository < ApplicationRecord
EMPTY_FILE_PATTERN = /^#{DEFAULT_EMPTY_FILE_NAME}(\d+)\.txt$/.freeze
CommitError = Class.new(StandardError)
+ InvalidPathError = Class.new(CommitError)
belongs_to :snippet, inverse_of: :snippet_repository
@@ -40,8 +41,9 @@ class SnippetRepository < ApplicationRecord
rescue Gitlab::Git::Index::IndexError,
Gitlab::Git::CommitError,
Gitlab::Git::PreReceiveError,
- Gitlab::Git::CommandError => e
- raise CommitError, e.message
+ Gitlab::Git::CommandError => error
+
+ raise commit_error_exception(error)
end
def transform_file_entries(files)
@@ -85,4 +87,16 @@ class SnippetRepository < ApplicationRecord
def build_empty_file_name(index)
"#{DEFAULT_EMPTY_FILE_NAME}#{index}.txt"
end
+
+ def commit_error_exception(error)
+ if error.is_a?(Gitlab::Git::Index::IndexError) && invalid_path_error?(error.message)
+ InvalidPathError.new('Invalid Path') # To avoid returning the message with the path included
+ else
+ CommitError.new(error.message)
+ end
+ end
+
+ def invalid_path_error?(message)
+ message.downcase.start_with?('invalid path', 'path cannot include directory traversal')
+ end
end
diff --git a/app/models/x509_commit_signature.rb b/app/models/x509_commit_signature.rb
index ed7c638cecc..57d809f7cfb 100644
--- a/app/models/x509_commit_signature.rb
+++ b/app/models/x509_commit_signature.rb
@@ -41,4 +41,8 @@ class X509CommitSignature < ApplicationRecord
Gitlab::X509::Commit.new(commit)
end
+
+ def user
+ commit.committer
+ end
end
diff --git a/app/views/projects/commit/_signature.html.haml b/app/views/projects/commit/_signature.html.haml
index aa7c90bad66..fb31ac44118 100644
--- a/app/views/projects/commit/_signature.html.haml
+++ b/app/views/projects/commit/_signature.html.haml
@@ -1,3 +1,3 @@
- if signature
- - uri = "projects/commit/#{"x509/" if signature.instance_of?(X509CommitSignature)}"
+ - uri = "projects/commit/#{"x509/" if x509_signature?(signature)}"
= render partial: "#{uri}#{signature.verification_status}_signature_badge", locals: { signature: signature }
diff --git a/app/views/projects/commit/_signature_badge.html.haml b/app/views/projects/commit/_signature_badge.html.haml
index 8ecaa1329fd..8004a5facd7 100644
--- a/app/views/projects/commit/_signature_badge.html.haml
+++ b/app/views/projects/commit/_signature_badge.html.haml
@@ -17,13 +17,13 @@
- content = capture do
- if show_user
.clearfix
- - uri_signature_badge_user = "projects/commit/#{"x509/" if signature.instance_of?(X509CommitSignature)}signature_badge_user"
+ - uri_signature_badge_user = "projects/commit/#{"x509/" if x509_signature?(signature)}signature_badge_user"
= render partial: "#{uri_signature_badge_user}", locals: { signature: signature }
- - if signature.instance_of?(X509CommitSignature)
+ - if x509_signature?(signature)
= render partial: "projects/commit/x509/certificate_details", locals: { signature: signature }
- = link_to(_('Learn more about x509 signed commits'), help_page_path('user/project/repository/x509_signed_commits/index.md'), class: 'gpg-popover-help-link')
+ = link_to(_('Learn more about X.509 signed commits'), help_page_path('user/project/repository/x509_signed_commits/index.md'), class: 'gpg-popover-help-link')
- else
= _('GPG Key ID:')
%span.monospace= signature.gpg_key_primary_keyid
diff --git a/app/views/projects/commit/x509/_signature_badge_user.html.haml b/app/views/projects/commit/x509/_signature_badge_user.html.haml
index b64ccba2a18..f3d39b21ec2 100644
--- a/app/views/projects/commit/x509/_signature_badge_user.html.haml
+++ b/app/views/projects/commit/x509/_signature_badge_user.html.haml
@@ -1,5 +1,5 @@
-- user = signature.commit.committer
- user_email = signature.x509_certificate.email
+- user = signature.user
- if user
= link_to user_path(user), class: 'gpg-popover-user-link' do
diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml
index 75805192a61..da693a15ec2 100644
--- a/app/views/projects/tags/_tag.html.haml
+++ b/app/views/projects/tags/_tag.html.haml
@@ -30,6 +30,9 @@
= markdown_field(release, :description)
.row-fixed-content.controls.flex-row
+ - if tag.has_signature?
+ = render partial: 'projects/commit/signature', object: tag.signature
+
= render 'projects/buttons/download', project: @project, ref: tag.name, pipeline: @tags_pipelines[tag.name]
- if can?(current_user, :admin_tag, @project)
diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml
index 8086d47479d..6f53a687fb9 100644
--- a/app/views/projects/tags/show.html.haml
+++ b/app/views/projects/tags/show.html.haml
@@ -39,6 +39,8 @@
= s_("TagsPage|Can't find HEAD commit for this tag")
.nav-controls
+ - if @tag.has_signature?
+ = render partial: 'projects/commit/signature', object: @tag.signature
- if can?(current_user, :admin_tag, @project)
= link_to edit_project_tag_release_path(@project, @tag.name), class: 'btn btn-edit controls-item has-tooltip', title: s_('TagsPage|Edit release notes') do
= icon("pencil")
diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml
index 7262c47f9d3..cb298459dc7 100644
--- a/app/views/shared/_service_settings.html.haml
+++ b/app/views/shared/_service_settings.html.haml
@@ -8,9 +8,10 @@
= markdown @service.help
.service-settings
- .js-vue-integration-settings{ data: { show_active: @service.show_active_box?.to_s, activated: (@service.active || @service.new_record?).to_s } }
+ .js-vue-integration-settings{ data: { show_active: @service.show_active_box?.to_s, activated: (@service.active || @service.new_record?).to_s, type: @service.to_param, merge_request_events: @service.merge_requests_events.to_s,
+commit_events: @service.commit_events.to_s, enable_comments: @service.comment_on_event_enabled.to_s, comment_detail: @service.comment_detail } }
- - if @service.configurable_events.present?
+ - if @service.configurable_events.present? && !@service.is_a?(JiraService)
.form-group.row
%label.col-form-label.col-sm-2= _('Trigger')
@@ -31,22 +32,6 @@
%p.text-muted
= @service.class.event_description(event)
- - if @service.configurable_event_actions.present?
- .form-group.row
- %label.col-form-label.col-sm-2= _('Event Actions')
-
- .col-sm-10
- - @service.configurable_event_actions.each do |action|
- .form-group
- .form-check
- = form.check_box service_event_action_field_name(action), class: 'form-check-input'
- = form.label service_event_action_field_name(action), class: 'form-check-label' do
- %strong
- = event_action_description(action)
-
- %p.text-muted
- = event_action_description(action)
-
- @service.global_fields.each do |field|
- type = field[:type]