Skip to content
Snippets Groups Projects
Unverified Commit 52967b10 authored by Douwe Maan's avatar Douwe Maan Committed by James Lopez
Browse files

Merge branch 'jej/mattermost-notification-confidentiality-10-6' into 'security-10-6'

[10.6] Prevent notes on confidential issues from being sent to chat

See merge request gitlab/gitlabhq!2366
# Conflicts:
#	app/helpers/services_helper.rb
parent 98106ec5
No related branches found
No related tags found
No related merge requests found
Showing
with 204 additions and 10 deletions
module ServicesHelper
def service_event_description(event)
case event
when "push", "push_events"
"Event will be triggered by a push to the repository"
when "tag_push", "tag_push_events"
"Event will be triggered when a new tag is pushed to the repository"
when "note", "note_events"
"Event will be triggered when someone adds a comment"
when "confidential_note", "confidential_note_events"
"Event will be triggered when someone adds a comment on a confidential issue"
when "issue", "issue_events"
"Event will be triggered when an issue is created/updated/closed"
when "confidential_issue", "confidential_issues_events"
"Event will be triggered when a confidential issue is created/updated/closed"
when "merge_request", "merge_request_events"
"Event will be triggered when a merge request is created/updated/merged"
when "pipeline", "pipeline_events"
"Event will be triggered when a pipeline status changes"
when "wiki_page", "wiki_page_events"
"Event will be triggered when a wiki page is created/updated"
when "commit", "commit_events"
"Event will be triggered when a commit is created/updated"
end
end
def service_event_field_name(event)
event = event.pluralize if %w[merge_request issue confidential_issue].include?(event)
"#{event}_events"
Loading
Loading
Loading
Loading
@@ -7,6 +7,7 @@ class ProjectHook < WebHook
:issue_hooks,
:confidential_issue_hooks,
:note_hooks,
:confidential_note_hooks,
:merge_request_hooks,
:job_hooks,
:pipeline_hooks,
Loading
Loading
Loading
Loading
@@ -268,6 +268,10 @@ class Note < ActiveRecord::Base
self.special_role = Note::SpecialRole::FIRST_TIME_CONTRIBUTOR
end
 
def confidential?
noteable.try(:confidential?)
end
def editable?
!system?
end
Loading
Loading
Loading
Loading
@@ -21,8 +21,16 @@ class ChatNotificationService < Service
end
end
 
def confidential_issue_channel
properties['confidential_issue_channel'].presence || properties['issue_channel']
end
def confidential_note_channel
properties['confidential_note_channel'].presence || properties['note_channel']
end
def self.supported_events
%w[push issue confidential_issue merge_request note tag_push
%w[push issue confidential_issue merge_request note confidential_note tag_push
pipeline wiki_page]
end
 
Loading
Loading
@@ -55,7 +63,9 @@ class ChatNotificationService < Service
 
return false unless message
 
channel_name = get_channel_field(object_kind).presence || channel
event_type = data[:event_type] || object_kind
channel_name = get_channel_field(event_type).presence || channel
 
opts = {}
opts[:channel] = channel_name if channel_name
Loading
Loading
Loading
Loading
@@ -46,7 +46,7 @@ class HipchatService < Service
end
 
def self.supported_events
%w(push issue confidential_issue merge_request note tag_push pipeline)
%w(push issue confidential_issue merge_request note confidential_note tag_push pipeline)
end
 
def execute(data)
Loading
Loading
Loading
Loading
@@ -14,6 +14,7 @@ class Service < ActiveRecord::Base
default_value_for :merge_requests_events, true
default_value_for :tag_push_events, true
default_value_for :note_events, true
default_value_for :confidential_note_events, true
default_value_for :job_events, true
default_value_for :pipeline_events, true
default_value_for :wiki_page_events, true
Loading
Loading
@@ -42,6 +43,7 @@ class Service < ActiveRecord::Base
scope :confidential_issue_hooks, -> { where(confidential_issues_events: true, active: true) }
scope :merge_request_hooks, -> { where(merge_requests_events: true, active: true) }
scope :note_hooks, -> { where(note_events: true, active: true) }
scope :confidential_note_hooks, -> { where(confidential_note_events: true, active: true) }
scope :job_hooks, -> { where(job_events: true, active: true) }
scope :pipeline_hooks, -> { where(pipeline_events: true, active: true) }
scope :wiki_page_hooks, -> { where(wiki_page_events: true, active: true) }
Loading
Loading
@@ -168,8 +170,10 @@ class Service < ActiveRecord::Base
def self.prop_accessor(*args)
args.each do |arg|
class_eval %{
def #{arg}
properties['#{arg}']
unless method_defined?(arg)
def #{arg}
properties['#{arg}']
end
end
 
def #{arg}=(value)
Loading
Loading
Loading
Loading
@@ -24,8 +24,10 @@ module Notes
 
def execute_note_hooks
note_data = hook_data
@note.project.execute_hooks(note_data, :note_hooks)
@note.project.execute_services(note_data, :note_hooks)
hooks_scope = @note.confidential? ? :confidential_note_hooks : :note_hooks
@note.project.execute_hooks(note_data, hooks_scope)
@note.project.execute_services(note_data, hooks_scope)
end
end
end
Loading
Loading
@@ -32,6 +32,13 @@
%strong Comments
%p.light
This URL will be triggered when someone adds a comment
%li
= form.check_box :confidential_note_events, class: 'pull-left'
.prepend-left-20
= form.label :confidential_note_events, class: 'list-label' do
%strong Confidential Comments
%p.light
This URL will be triggered when someone adds a comment on a confidential issue
%li
= form.check_box :issues_events, class: 'pull-left'
.prepend-left-20
Loading
Loading
---
title: Adds confidential notes channel for Slack/Mattermost
merge_request:
author:
type: security
class AddConfidentialNoteEventsToWebHooks < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_column :web_hooks, :confidential_note_events, :boolean
end
def down
remove_column :web_hooks, :confidential_note_events
end
end
class AddConfidentialNoteEventsToServices < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_column :services, :confidential_note_events, :boolean
change_column_default :services, :confidential_note_events, true
end
def down
remove_column :services, :confidential_note_events
end
end
class ScheduleSetConfidentialNoteEventsOnWebhooks < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
BATCH_SIZE = 1_000
INTERVAL = 5.minutes
disable_ddl_transaction!
def up
migration = Gitlab::BackgroundMigration::SetConfidentialNoteEventsOnWebhooks
migration_name = migration.to_s.demodulize
relation = migration::WebHook.hooks_to_update
queue_background_migration_jobs_by_range_at_intervals(relation,
migration_name,
INTERVAL,
batch_size: BATCH_SIZE)
end
def down
end
end
class ScheduleSetConfidentialNoteEventsOnServices < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
BATCH_SIZE = 1_000
INTERVAL = 20.minutes
disable_ddl_transaction!
def up
migration = Gitlab::BackgroundMigration::SetConfidentialNoteEventsOnServices
migration_name = migration.to_s.demodulize
relation = migration::Service.services_to_update
queue_background_migration_jobs_by_range_at_intervals(relation,
migration_name,
INTERVAL,
batch_size: BATCH_SIZE)
end
def down
end
end
Loading
Loading
@@ -1684,6 +1684,7 @@ ActiveRecord::Schema.define(version: 20180327101207) do
t.boolean "confidential_issues_events", default: true, null: false
t.boolean "commit_events", default: true, null: false
t.boolean "job_events", default: false, null: false
t.boolean "confidential_note_events", default: true
end
 
add_index "services", ["project_id"], name: "index_services_on_project_id", using: :btree
Loading
Loading
@@ -2022,6 +2023,7 @@ ActiveRecord::Schema.define(version: 20180327101207) do
t.boolean "confidential_issues_events", default: false, null: false
t.boolean "repository_update_events", default: false, null: false
t.boolean "job_events", default: false, null: false
t.boolean "confidential_note_events"
end
 
add_index "web_hooks", ["project_id"], name: "index_web_hooks_on_project_id", using: :btree
Loading
Loading
Loading
Loading
@@ -72,7 +72,7 @@ module API
 
class ProjectHook < Hook
expose :project_id, :issues_events, :confidential_issues_events
expose :note_events, :pipeline_events, :wiki_page_events
expose :note_events, :confidential_note_events, :pipeline_events, :wiki_page_events
expose :job_events
end
 
Loading
Loading
@@ -794,7 +794,7 @@ module API
expose :id, :title, :created_at, :updated_at, :active
expose :push_events, :issues_events, :confidential_issues_events
expose :merge_requests_events, :tag_push_events, :note_events
expose :pipeline_events, :wiki_page_events
expose :confidential_note_events, :pipeline_events, :wiki_page_events
expose :job_events
# Expose serialized properties
expose :properties do |service, options|
Loading
Loading
Loading
Loading
@@ -14,6 +14,7 @@ module API
optional :merge_requests_events, type: Boolean, desc: "Trigger hook on merge request events"
optional :tag_push_events, type: Boolean, desc: "Trigger hook on tag push events"
optional :note_events, type: Boolean, desc: "Trigger hook on note(comment) events"
optional :confidential_note_events, type: Boolean, desc: "Trigger hook on confidential note(comment) events"
optional :job_events, type: Boolean, desc: "Trigger hook on job events"
optional :pipeline_events, type: Boolean, desc: "Trigger hook on pipeline events"
optional :wiki_page_events, type: Boolean, desc: "Trigger hook on wiki events"
Loading
Loading
# frozen_string_literal: true
# rubocop:disable Style/Documentation
module Gitlab
module BackgroundMigration
# Ensures services which previously recieved all notes events continue
# to recieve confidential ones.
class SetConfidentialNoteEventsOnServices
class Service < ActiveRecord::Base
self.table_name = 'services'
include ::EachBatch
def self.services_to_update
where(confidential_note_events: nil, note_events: true)
end
end
def perform(start_id, stop_id)
Service.services_to_update
.where(id: start_id..stop_id)
.update_all(confidential_note_events: true)
end
end
end
end
# frozen_string_literal: true
# rubocop:disable Style/Documentation
module Gitlab
module BackgroundMigration
# Ensures hooks which previously recieved all notes events continue
# to recieve confidential ones.
class SetConfidentialNoteEventsOnWebhooks
class WebHook < ActiveRecord::Base
self.table_name = 'web_hooks'
include ::EachBatch
def self.hooks_to_update
where(confidential_note_events: nil, note_events: true)
end
end
def perform(start_id, stop_id)
WebHook.hooks_to_update
.where(id: start_id..stop_id)
.update_all(confidential_note_events: true)
end
end
end
end
Loading
Loading
@@ -9,6 +9,7 @@ module Gitlab
#
# data = {
# object_kind: "note",
# event_type: "confidential_note",
# user: {
# name: String,
# username: String,
Loading
Loading
@@ -51,8 +52,11 @@ module Gitlab
end
 
def build_base_data(project, user, note)
event_type = note.confidential? ? 'confidential_note' : 'note'
base_data = {
object_kind: "note",
event_type: event_type,
user: user.hook_attrs,
project_id: project.id,
project: project.hook_attrs,
Loading
Loading
Loading
Loading
@@ -860,7 +860,7 @@ into similar problems in the future (e.g. when new tables are created).
# Each job is scheduled with a `delay_interval` in between.
# If you use a small interval, then some jobs may run at the same time.
#
# model_class - The table being iterated over
# model_class - The table or relation being iterated over
# job_class_name - The background migration job class as a string
# delay_interval - The duration between each job's scheduled time (must respond to `to_f`)
# batch_size - The maximum number of rows per job
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment