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
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-03-09 02:49:11 +0300
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-03-09 02:49:11 +0300
commit8b551ee31858db9c5da1ff5245359151d5b71211 (patch)
tree39fc875c2e2cade77dd4723630782200fef33dcf
parentc025c0d58948680c3021a598822c2814f7fe1cce (diff)
parent4658e554b7129c44221a73fe8ec3b73b4b9b8b24 (diff)
Merge branch 'emails-on-push'
Conflicts: app/controllers/projects/services_controller.rb app/models/project_services/emails_on_push_service.rb
-rw-r--r--app/controllers/admin/services_controller.rb3
-rw-r--r--app/controllers/projects/services_controller.rb2
-rw-r--r--app/mailers/emails/projects.rb26
-rw-r--r--app/mailers/notify.rb22
-rw-r--r--app/models/project_services/emails_on_push_service.rb21
-rw-r--r--app/views/admin/services/_form.html.haml6
-rw-r--r--app/views/layouts/notify.html.haml14
-rw-r--r--app/views/notify/repository_push_email.html.haml68
-rw-r--r--app/views/notify/repository_push_email.text.haml52
-rw-r--r--app/views/projects/diffs/_stats.html.haml2
-rw-r--r--app/views/projects/services/_form.html.haml6
-rw-r--r--app/workers/emails_on_push_worker.rb24
-rw-r--r--spec/mailers/notify_spec.rb59
13 files changed, 249 insertions, 56 deletions
diff --git a/app/controllers/admin/services_controller.rb b/app/controllers/admin/services_controller.rb
index e80cabd6e18..44a3f1379d8 100644
--- a/app/controllers/admin/services_controller.rb
+++ b/app/controllers/admin/services_controller.rb
@@ -45,7 +45,8 @@ class Admin::ServicesController < Admin::ApplicationController
:room, :recipients, :project_url, :webhook,
:user_key, :device, :priority, :sound, :bamboo_url, :username, :password,
:build_key, :server, :teamcity_url, :build_type,
- :description, :issues_url, :new_issue_url, :restrict_to_branch
+ :description, :issues_url, :new_issue_url, :restrict_to_branch,
+ :send_from_committer_email, :disable_diffs
])
end
end
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index 382d63d053b..570447c746c 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -53,7 +53,7 @@ class Projects::ServicesController < Projects::ApplicationController
:description, :issues_url, :new_issue_url, :restrict_to_branch, :channel,
:colorize_messages, :channels,
:push_events, :issues_events, :merge_requests_events, :tag_push_events,
- :note_events
+ :note_events, :send_from_committer_email, :disable_diffs
)
end
end
diff --git a/app/mailers/emails/projects.rb b/app/mailers/emails/projects.rb
index 4bc40b35f2d..9ea121d83a4 100644
--- a/app/mailers/emails/projects.rb
+++ b/app/mailers/emails/projects.rb
@@ -16,28 +16,38 @@ module Emails
subject: subject("Project was moved"))
end
- def repository_push_email(project_id, recipient, author_id, branch, compare)
+ def repository_push_email(project_id, recipient, author_id, branch, compare, reverse_compare = false, send_from_committer_email = false, disable_diffs = false)
@project = Project.find(project_id)
@author = User.find(author_id)
+ @reverse_compare = reverse_compare
@compare = compare
@commits = Commit.decorate(compare.commits)
@diffs = compare.diffs
- @branch = branch
+ @branch = branch.gsub("refs/heads/", "")
+ @disable_diffs = disable_diffs
+
+ @subject = "[#{@project.path_with_namespace}][#{@branch}] "
+
if @commits.length > 1
@target_url = namespace_project_compare_url(@project.namespace,
@project,
- from: @commits.first,
- to: @commits.last)
- @subject = "#{@commits.length} new commits pushed to repository"
+ from: Commit.new(@compare.base),
+ to: Commit.new(@compare.head))
+ @subject << "Deleted " if @reverse_compare
+ @subject << "#{@commits.length} commits: #{@commits.first.title}"
else
@target_url = namespace_project_commit_url(@project.namespace,
@project, @commits.first)
- @subject = @commits.first.title
+
+ @subject << "Deleted 1 commit: " if @reverse_compare
+ @subject << @commits.first.title
end
- mail(from: sender(author_id),
+ @disable_footer = true
+
+ mail(from: sender(author_id, send_from_committer_email),
to: recipient,
- subject: subject(@subject))
+ subject: @subject)
end
end
end
diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb
index 46ead62f75f..65925b61e94 100644
--- a/app/mailers/notify.rb
+++ b/app/mailers/notify.rb
@@ -34,6 +34,20 @@ class Notify < ActionMailer::Base
)
end
+ # Splits "gitlab.corp.company.com" up into "gitlab.corp.company.com",
+ # "corp.company.com" and "company.com".
+ # Respects set tld length so "company.co.uk" won't match "somethingelse.uk"
+ def self.allowed_email_domains
+ domain_parts = Gitlab.config.gitlab.host.split(".")
+ allowed_domains = []
+ begin
+ allowed_domains << domain_parts.join(".")
+ domain_parts.shift
+ end while domain_parts.length > ActionDispatch::Http::URL.tld_length
+
+ allowed_domains
+ end
+
private
# The default email address to send emails from
@@ -45,10 +59,16 @@ class Notify < ActionMailer::Base
# Return an email address that displays the name of the sender.
# Only the displayed name changes; the actual email address is always the same.
- def sender(sender_id)
+ def sender(sender_id, send_from_user_email = false)
if sender = User.find(sender_id)
address = default_sender_address
address.display_name = sender.name
+
+ sender_domain = sender.email.split("@").last
+ if send_from_user_email && self.class.allowed_email_domains.include?(sender_domain)
+ address.address = sender.email
+ end
+
address.format
end
end
diff --git a/app/models/project_services/emails_on_push_service.rb b/app/models/project_services/emails_on_push_service.rb
index d894d2913d7..acb5e7f1af5 100644
--- a/app/models/project_services/emails_on_push_service.rb
+++ b/app/models/project_services/emails_on_push_service.rb
@@ -18,6 +18,8 @@
#
class EmailsOnPushService < Service
+ prop_accessor :send_from_committer_email
+ prop_accessor :disable_diffs
prop_accessor :recipients
validates :recipients, presence: true, if: :activated?
@@ -37,14 +39,27 @@ class EmailsOnPushService < Service
%w(push)
end
- def execute(data)
- return unless supported_events.include?(data[:object_kind])
+ def execute(push_data)
+ return unless supported_events.include?(push_data[:object_kind])
- EmailsOnPushWorker.perform_async(project_id, recipients, data)
+ EmailsOnPushWorker.perform_async(project_id, recipients, push_data, send_from_committer_email?, disable_diffs?)
+ end
+
+ def send_from_committer_email?
+ self.send_from_committer_email == "1"
+ end
+
+ def disable_diffs?
+ self.disable_diffs == "1"
end
def fields
+ domains = Notify.allowed_email_domains.map { |domain| "user@#{domain}" }.join(", ")
[
+ { type: 'checkbox', name: 'send_from_committer_email', title: "Send from committer",
+ help: "Send notifications from the committer's email address if the domain is part of the domain GitLab is running on (e.g. #{domains})." },
+ { type: 'checkbox', name: 'disable_diffs', title: "Disable code diffs",
+ help: "Don't include possibly sensitive code diffs in notification body." },
{ type: 'textarea', name: 'recipients', placeholder: 'Emails separated by whitespace' },
]
end
diff --git a/app/views/admin/services/_form.html.haml b/app/views/admin/services/_form.html.haml
index 4ddddbd46ea..291e48efc12 100644
--- a/app/views/admin/services/_form.html.haml
+++ b/app/views/admin/services/_form.html.haml
@@ -53,14 +53,16 @@
- @service.fields.each do |field|
- name = field[:name]
+ - title = field[:title] || name.humanize
- value = @service.send(name) unless field[:type] == 'password'
- type = field[:type]
- placeholder = field[:placeholder]
- choices = field[:choices]
- default_choice = field[:default_choice]
+ - help = field[:help]
.form-group
- = f.label name, class: "control-label"
+ = f.label name, title, class: "control-label"
.col-sm-10
- if type == 'text'
= f.text_field name, class: "form-control", placeholder: placeholder
@@ -72,6 +74,8 @@
= f.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control" }
- elsif type == 'password'
= f.password_field name, class: 'form-control'
+ - if help
+ %span.help-block= help
.form-actions
= f.submit 'Save', class: 'btn btn-save'
diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml
index 8cca80e5248..7eec93abdf6 100644
--- a/app/views/layouts/notify.html.haml
+++ b/app/views/layouts/notify.html.haml
@@ -16,6 +16,18 @@
font-size:small;
color:#777
}
+ pre.commit-message {
+ white-space: pre-wrap;
+ }
+ .file-stats a {
+ text-decoration: none;
+ }
+ .file-stats .new-file {
+ color: #090;
+ }
+ .file-stats .deleted-file {
+ color: #B00;
+ }
#{add_email_highlight_css}
%body
%div.content
@@ -27,5 +39,5 @@
- if @target_url
#{link_to "View it on GitLab", @target_url}
= email_action @target_url
- - if @project
+ - if @project && !@disable_footer
You're receiving this notification because you are a member of the #{link_to_unless @target_url, @project.name_with_namespace, namespace_project_url(@project.namespace, @project)} project team.
diff --git a/app/views/notify/repository_push_email.html.haml b/app/views/notify/repository_push_email.html.haml
index a45d1dedcd1..039b92df2be 100644
--- a/app/views/notify/repository_push_email.html.haml
+++ b/app/views/notify/repository_push_email.html.haml
@@ -1,6 +1,12 @@
%h3 #{@author.name} pushed to #{@branch} at #{link_to @project.name_with_namespace, namespace_project_url(@project.namespace, @project)}
-%h4 Commits:
+- if @reverse_compare
+ %p
+ %strong WARNING:
+ The push did not contain any new commits, but force pushed to delete the commits and changes below.
+
+%h4
+ = @reverse_compare ? "Deleted commits:" : "Commits:"
%ul
- @commits.each do |commit|
@@ -9,22 +15,52 @@
%div
%span by #{commit.author_name}
%i at #{commit.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ")}
- %pre #{commit.safe_message}
+ %pre.commit-message
+ = commit.safe_message
+
+%h4 #{pluralize @diffs.count, "changed file"}:
+
+%ul
+ - @diffs.each_with_index do |diff, i|
+ %li.file-stats
+ %a{href: "#{@target_url if @disable_diffs}#diff-#{i}" }
+ - if diff.deleted_file
+ %span.deleted-file
+ &minus;
+ = diff.old_path
+ - elsif diff.renamed_file
+ = diff.old_path
+ &rarr;
+ = diff.new_path
+ - elsif diff.new_file
+ %span.new-file
+ &plus;
+ = diff.new_path
+ - else
+ = diff.new_path
-%h4 Changes:
-- @diffs.each do |diff|
- %li
- %strong
- - if diff.old_path == diff.new_path
- = diff.new_path
- - elsif diff.new_path && diff.old_path
- #{diff.old_path} &rarr; #{diff.new_path}
- - else
- = diff.new_path || diff.old_path
- %hr
- %pre
- = color_email_diff(diff.diff)
- %br
+- unless @disable_diffs
+ %h4 Changes:
+ - @diffs.each_with_index do |diff, i|
+ %li{id: "diff-#{i}"}
+ %a{href: @target_url + "#diff-#{i}"}
+ - if diff.deleted_file
+ %strong
+ = diff.old_path
+ deleted
+ - elsif diff.renamed_file
+ %strong
+ = diff.old_path
+ &rarr;
+ %strong
+ = diff.new_path
+ - else
+ %strong
+ = diff.new_path
+ %hr
+ %pre
+ = color_email_diff(diff.diff)
+ %br
- if @compare.timeout
%h5 Huge diff. To prevent performance issues changes are hidden
diff --git a/app/views/notify/repository_push_email.text.haml b/app/views/notify/repository_push_email.text.haml
index fa355cb5269..8d67a42234e 100644
--- a/app/views/notify/repository_push_email.text.haml
+++ b/app/views/notify/repository_push_email.text.haml
@@ -1,25 +1,47 @@
-#{@author.name} pushed to #{@branch} at #{link_to @project.name_with_namespace, namespace_project_url(@project.namespace, @project)}
-
+#{@author.name} pushed to #{@branch} at #{@project.name_with_namespace}
\
-Commits:
+\
+- if @reverse_compare
+ WARNING: The push did not contain any new commits, but force pushed to delete the commits and changes below.
+ \
+ \
+= @reverse_compare ? "Deleted commits:" : "Commits:"
- @commits.each do |commit|
- #{link_to commit.short_id, namespace_project_commit_url(@project.namespace, @project, commit)} by #{commit.author_name}
+ #{commit.short_id} by #{commit.author_name} at #{commit.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ")}
#{commit.safe_message}
\- - - - -
\
\
-Changes:
+#{pluralize @diffs.count, "changed file"}:
+\
- @diffs.each do |diff|
- \
- \=====================================
- - if diff.old_path == diff.new_path
- = diff.new_path
- - elsif diff.new_path && diff.old_path
- #{diff.old_path} &rarr; #{diff.new_path}
+ - if diff.deleted_file
+ \- − #{diff.old_path}
+ - elsif diff.renamed_file
+ \- #{diff.old_path} → #{diff.new_path}
+ - elsif diff.new_file
+ \- + #{diff.new_path}
- else
- = diff.new_path || diff.old_path
- \=====================================
- != diff.diff
-\
+ \- #{diff.new_path}
+- unless @disable_diffs
+ \
+ \
+ Changes:
+ - @diffs.each do |diff|
+ \
+ \=====================================
+ - if diff.deleted_file
+ #{diff.old_path} deleted
+ - elsif diff.renamed_file
+ #{diff.old_path} → #{diff.new_path}
+ - else
+ = diff.new_path
+ \=====================================
+ != diff.diff
- if @compare.timeout
+ \
+ \
Huge diff. To prevent performance issues it was hidden
+\
+\
+View it on GitLab: #{@target_url}
diff --git a/app/views/projects/diffs/_stats.html.haml b/app/views/projects/diffs/_stats.html.haml
index 20e51d18da5..9b5eb84a86d 100644
--- a/app/views/projects/diffs/_stats.html.haml
+++ b/app/views/projects/diffs/_stats.html.haml
@@ -26,7 +26,7 @@
%a{href: "#diff-#{i}"}
%i.fa.fa-minus
= diff.old_path
- \->
+ &rarr;
= diff.new_path
- elsif diff.new_file
%span.new-file
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index 8afae91d757..eda59e6708b 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -74,14 +74,16 @@
- @service.fields.each do |field|
- name = field[:name]
+ - title = field[:title] || name.humanize
- value = @service.send(name) unless field[:type] == 'password'
- type = field[:type]
- placeholder = field[:placeholder]
- choices = field[:choices]
- default_choice = field[:default_choice]
+ - help = field[:help]
.form-group
- = f.label name, class: "control-label"
+ = f.label name, title, class: "control-label"
.col-sm-10
- if type == 'text'
= f.text_field name, class: "form-control", placeholder: placeholder
@@ -93,6 +95,8 @@
= f.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control" }
- elsif type == 'password'
= f.password_field name, class: 'form-control'
+ - if help
+ %span.help-block= help
.form-actions
= f.submit 'Save', class: 'btn btn-save'
diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb
index e3f6f3a6aef..2e783814824 100644
--- a/app/workers/emails_on_push_worker.rb
+++ b/app/workers/emails_on_push_worker.rb
@@ -1,7 +1,7 @@
class EmailsOnPushWorker
include Sidekiq::Worker
- def perform(project_id, recipients, push_data)
+ def perform(project_id, recipients, push_data, send_from_committer_email = false, disable_diffs = false)
project = Project.find(project_id)
before_sha = push_data["before"]
after_sha = push_data["after"]
@@ -15,11 +15,27 @@ class EmailsOnPushWorker
compare = Gitlab::Git::Compare.new(project.repository.raw_repository, before_sha, after_sha)
- # Do not send emails if git compare failed
- return false unless compare && compare.commits.present?
+ return false if compare.same
+
+ if compare.commits.empty?
+ compare = Gitlab::Git::Compare.new(project.repository.raw_repository, after_sha, before_sha)
+
+ reverse_compare = true
+
+ return false if compare.commits.empty?
+ end
recipients.split(" ").each do |recipient|
- Notify.repository_push_email(project_id, recipient, author_id, branch, compare).deliver
+ Notify.repository_push_email(
+ project_id,
+ recipient,
+ author_id,
+ branch,
+ compare,
+ reverse_compare,
+ send_from_committer_email,
+ disable_diffs
+ ).deliver
end
ensure
compare = nil
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 3b09c618f2a..4090fa46205 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -568,9 +568,10 @@ describe Notify do
let(:user) { create(:user) }
let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_image_commit.id, sample_commit.id) }
let(:commits) { Commit.decorate(compare.commits) }
- let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: commits.first, to: commits.last) }
+ let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: Commit.new(compare.base), to: Commit.new(compare.head)) }
+ let(:send_from_committer_email) { false }
- subject { Notify.repository_push_email(project.id, 'devs@company.name', user.id, 'master', compare) }
+ subject { Notify.repository_push_email(project.id, 'devs@company.name', user.id, 'master', compare, false, send_from_committer_email) }
it 'is sent as the author' do
sender = subject.header[:from].addrs[0]
@@ -583,7 +584,7 @@ describe Notify do
end
it 'has the correct subject' do
- is_expected.to have_subject /#{commits.length} new commits pushed to repository/
+ is_expected.to have_subject /\[#{project.path_with_namespace}\]\[master\] #{commits.length} commits:/
end
it 'includes commits list' do
@@ -597,6 +598,58 @@ describe Notify do
it 'contains a link to the diff' do
is_expected.to have_body_text /#{diff_path}/
end
+
+ it 'doesn not contain the misleading footer' do
+ is_expected.not_to have_body_text /you are a member of/
+ end
+
+ context "when set to send from committer email if domain matches" do
+
+ let(:send_from_committer_email) { true }
+
+ before do
+ allow(Gitlab.config.gitlab).to receive(:host).and_return("gitlab.corp.company.com")
+ end
+
+ context "when the committer email domain is within the GitLab domain" do
+
+ before do
+ user.update_attribute(:email, "user@company.com")
+ user.confirm!
+ end
+
+ it "is sent from the committer email" do
+ sender = subject.header[:from].addrs[0]
+ expect(sender.address).to eq(user.email)
+ end
+ end
+
+ context "when the committer email domain is not completely within the GitLab domain" do
+
+ before do
+ user.update_attribute(:email, "user@something.company.com")
+ user.confirm!
+ end
+
+ it "is sent from the default email" do
+ sender = subject.header[:from].addrs[0]
+ expect(sender.address).to eq(gitlab_sender)
+ end
+ end
+
+ context "when the committer email domain is outside the GitLab domain" do
+
+ before do
+ user.update_attribute(:email, "user@mpany.com")
+ user.confirm!
+ end
+
+ it "is sent from the default email" do
+ sender = subject.header[:from].addrs[0]
+ expect(sender.address).to eq(gitlab_sender)
+ end
+ end
+ end
end
describe 'email on push with a single commit' do