Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
58867eff
Commit
58867eff
authored
Dec 09, 2015
by
Zeger-Jan van de Weg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Unsubscribe from thread through link in email footer
parent
c81647ae
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
176 additions
and
85 deletions
+176
-85
CHANGELOG
CHANGELOG
+1
-0
app/controllers/sent_notifications_controller.rb
app/controllers/sent_notifications_controller.rb
+25
-0
app/mailers/emails/issues.rb
app/mailers/emails/issues.rb
+18
-20
app/mailers/emails/merge_requests.rb
app/mailers/emails/merge_requests.rb
+21
-34
app/mailers/emails/notes.rb
app/mailers/emails/notes.rb
+20
-22
app/mailers/notify.rb
app/mailers/notify.rb
+2
-3
app/models/concerns/issuable.rb
app/models/concerns/issuable.rb
+6
-0
app/models/sent_notification.rb
app/models/sent_notification.rb
+5
-3
app/views/layouts/notify.html.haml
app/views/layouts/notify.html.haml
+6
-2
config/routes.rb
config/routes.rb
+6
-0
spec/controllers/sent_notification_controller_spec.rb
spec/controllers/sent_notification_controller_spec.rb
+26
-0
spec/factories.rb
spec/factories.rb
+7
-0
spec/mailers/notify_spec.rb
spec/mailers/notify_spec.rb
+33
-1
No files found.
CHANGELOG
View file @
58867eff
...
@@ -59,6 +59,7 @@ v 8.3.0
...
@@ -59,6 +59,7 @@ v 8.3.0
- Add open_issues_count to project API (Stan Hu)
- Add open_issues_count to project API (Stan Hu)
- Expand character set of usernames created by Omniauth (Corey Hinshaw)
- Expand character set of usernames created by Omniauth (Corey Hinshaw)
- Add button to automatically merge a merge request when the build succeeds (Zeger-Jan van de Weg)
- Add button to automatically merge a merge request when the build succeeds (Zeger-Jan van de Weg)
- Add unsubscribe link in the email footer (Zeger-Jan van de Weg)
- Provide better diagnostic message upon project creation errors (Stan Hu)
- Provide better diagnostic message upon project creation errors (Stan Hu)
- Bump devise to 3.5.3 to fix reset token expiring after account creation (Stan Hu)
- Bump devise to 3.5.3 to fix reset token expiring after account creation (Stan Hu)
- Remove api credentials from link to build_page
- Remove api credentials from link to build_page
...
...
app/controllers/sent_notifications_controller.rb
0 → 100644
View file @
58867eff
class
SentNotificationsController
<
ApplicationController
skip_before_action
:authenticate_user!
def
unsubscribe
@sent_notification
=
SentNotification
.
for
(
params
[
:id
])
return
render_404
unless
@sent_notification
&&
!
@sent_notification
.
for_commit?
noteable
=
@sent_notification
.
noteable
noteable
.
unsubscribe
(
@sent_notification
.
recipient
)
flash
[
:notice
]
=
"You have been unsubscribed from this thread."
if
current_user
case
@sent_notification
.
noteable
when
Issue
redirect_to
issue_path
(
noteable
)
when
MergeRequest
redirect_to
merge_request_path
(
noteable
)
else
redirect_to
root_path
end
else
redirect_to
new_user_session_path
end
end
end
app/mailers/emails/issues.rb
View file @
58867eff
module
Emails
module
Emails
module
Issues
module
Issues
def
new_issue_email
(
recipient_id
,
issue_id
)
def
new_issue_email
(
recipient_id
,
issue_id
)
issue_mail_with_notification
(
issue_id
,
recipient_id
)
do
setup_issue_mail
(
issue_id
,
recipient_id
)
mail_new_thread
(
@issue
,
issue_thread_options
(
@issue
.
author_id
,
recipient_id
))
end
mail_new_thread
(
@issue
,
issue_thread_options
(
@issue
.
author_id
,
recipient_id
))
end
end
def
reassigned_issue_email
(
recipient_id
,
issue_id
,
previous_assignee_id
,
updated_by_user_id
)
def
reassigned_issue_email
(
recipient_id
,
issue_id
,
previous_assignee_id
,
updated_by_user_id
)
issue_mail_with_notification
(
issue_id
,
recipient_id
)
do
setup_issue_mail
(
issue_id
,
recipient_id
)
@previous_assignee
=
User
.
find_by
(
id:
previous_assignee_id
)
if
previous_assignee_id
mail_answer_thread
(
@issue
,
issue_thread_options
(
updated_by_user_id
,
recipient_id
))
@previous_assignee
=
User
.
find_by
(
id:
previous_assignee_id
)
if
previous_assignee_id
end
mail_answer_thread
(
@issue
,
issue_thread_options
(
updated_by_user_id
,
recipient_id
))
end
end
def
closed_issue_email
(
recipient_id
,
issue_id
,
updated_by_user_id
)
def
closed_issue_email
(
recipient_id
,
issue_id
,
updated_by_user_id
)
issue_mail_with_notification
(
issue_id
,
recipient_id
)
do
setup_issue_mail
(
issue_id
,
recipient_id
)
@updated_by
=
User
.
find
updated_by_user_id
mail_answer_thread
(
@issue
,
issue_thread_options
(
updated_by_user_id
,
recipient_id
))
@updated_by
=
User
.
find
updated_by_user_id
end
mail_answer_thread
(
@issue
,
issue_thread_options
(
updated_by_user_id
,
recipient_id
))
end
end
def
issue_status_changed_email
(
recipient_id
,
issue_id
,
status
,
updated_by_user_id
)
def
issue_status_changed_email
(
recipient_id
,
issue_id
,
status
,
updated_by_user_id
)
issue_mail_with_notification
(
issue_id
,
recipient_id
)
do
setup_issue_mail
(
issue_id
,
recipient_id
)
@issue_status
=
status
@updated_by
=
User
.
find
updated_by_user_id
@issue_status
=
status
mail_answer_thread
(
@issue
,
issue_thread_options
(
updated_by_user_id
,
recipient_id
))
@updated_by
=
User
.
find
updated_by_user_id
end
mail_answer_thread
(
@issue
,
issue_thread_options
(
updated_by_user_id
,
recipient_id
))
end
end
private
private
...
@@ -38,14 +38,12 @@ module Emails
...
@@ -38,14 +38,12 @@ module Emails
}
}
end
end
def
issue_mail_with_notification
(
issue_id
,
recipient_id
)
def
setup_issue_mail
(
issue_id
,
recipient_id
)
@issue
=
Issue
.
find
(
issue_id
)
@issue
=
Issue
.
find
(
issue_id
)
@project
=
@issue
.
project
@project
=
@issue
.
project
@target_url
=
namespace_project_issue_url
(
@project
.
namespace
,
@project
,
@issue
)
@target_url
=
namespace_project_issue_url
(
@project
.
namespace
,
@project
,
@issue
)
yield
@sent_notification
=
SentNotification
.
record
(
@issue
,
recipient_id
,
reply_key
)
SentNotification
.
record
(
@issue
,
recipient_id
,
reply_key
)
end
end
end
end
end
end
app/mailers/emails/merge_requests.rb
View file @
58867eff
module
Emails
module
Emails
module
MergeRequests
module
MergeRequests
def
new_merge_request_email
(
recipient_id
,
merge_request_id
)
def
new_merge_request_email
(
recipient_id
,
merge_request_id
)
@merge_request
=
MergeRequest
.
find
(
merge_request_id
)
setup_merge_request_mail
(
merge_request_id
,
recipient_id
)
@project
=
@merge_request
.
project
@target_url
=
namespace_project_merge_request_url
(
@project
.
namespace
,
@project
,
@merge_request
)
mail_new_thread
(
@merge_request
,
mail_new_thread
(
@merge_request
,
from:
sender
(
@merge_request
.
author_id
),
from:
sender
(
@merge_request
.
author_id
),
to:
recipient
(
recipient_id
),
to:
recipient
(
recipient_id
),
subject:
subject
(
"
#{
@merge_request
.
title
}
(#
#{
@merge_request
.
iid
}
)"
))
subject:
subject
(
"
#{
@merge_request
.
title
}
(#
#{
@merge_request
.
iid
}
)"
))
SentNotification
.
record
(
@merge_request
,
recipient_id
,
reply_key
)
end
end
def
reassigned_merge_request_email
(
recipient_id
,
merge_request_id
,
previous_assignee_id
,
updated_by_user_id
)
def
reassigned_merge_request_email
(
recipient_id
,
merge_request_id
,
previous_assignee_id
,
updated_by_user_id
)
@merge_request
=
MergeRequest
.
find
(
merge_request_id
)
setup_merge_request_mail
(
merge_request_id
,
recipient_id
)
@previous_assignee
=
User
.
find_by
(
id:
previous_assignee_id
)
if
previous_assignee_id
@previous_assignee
=
User
.
find_by
(
id:
previous_assignee_id
)
if
previous_assignee_id
@project
=
@merge_request
.
project
@target_url
=
namespace_project_merge_request_url
(
@project
.
namespace
,
@project
,
@merge_request
)
mail_answer_thread
(
@merge_request
,
mail_answer_thread
(
@merge_request
,
from:
sender
(
updated_by_user_id
),
from:
sender
(
updated_by_user_id
),
to:
recipient
(
recipient_id
),
to:
recipient
(
recipient_id
),
subject:
subject
(
"
#{
@merge_request
.
title
}
(#
#{
@merge_request
.
iid
}
)"
))
subject:
subject
(
"
#{
@merge_request
.
title
}
(#
#{
@merge_request
.
iid
}
)"
))
SentNotification
.
record
(
@merge_request
,
recipient_id
,
reply_key
)
end
end
def
closed_merge_request_email
(
recipient_id
,
merge_request_id
,
updated_by_user_id
)
def
closed_merge_request_email
(
recipient_id
,
merge_request_id
,
updated_by_user_id
)
@merge_request
=
MergeRequest
.
find
(
merge_request_id
)
setup_merge_request_mail
(
merge_request_id
,
recipient_id
)
@updated_by
=
User
.
find
updated_by_user_id
@updated_by
=
User
.
find
updated_by_user_id
@project
=
@merge_request
.
project
@target_url
=
namespace_project_merge_request_url
(
@project
.
namespace
,
@project
,
@merge_request
)
mail_answer_thread
(
@merge_request
,
mail_answer_thread
(
@merge_request
,
from:
sender
(
updated_by_user_id
),
from:
sender
(
updated_by_user_id
),
to:
recipient
(
recipient_id
),
to:
recipient
(
recipient_id
),
subject:
subject
(
"
#{
@merge_request
.
title
}
(#
#{
@merge_request
.
iid
}
)"
))
subject:
subject
(
"
#{
@merge_request
.
title
}
(#
#{
@merge_request
.
iid
}
)"
))
SentNotification
.
record
(
@merge_request
,
recipient_id
,
reply_key
)
end
end
def
merged_merge_request_email
(
recipient_id
,
merge_request_id
,
updated_by_user_id
)
def
merged_merge_request_email
(
recipient_id
,
merge_request_id
,
updated_by_user_id
)
@merge_request
=
MergeRequest
.
find
(
merge_request_id
)
setup_merge_request_mail
(
merge_request_id
,
recipient_id
)
@project
=
@merge_request
.
project
@target_url
=
namespace_project_merge_request_url
(
@project
.
namespace
,
@project
,
@merge_request
)
mail_answer_thread
(
@merge_request
,
mail_answer_thread
(
@merge_request
,
from:
sender
(
updated_by_user_id
),
from:
sender
(
updated_by_user_id
),
to:
recipient
(
recipient_id
),
to:
recipient
(
recipient_id
),
subject:
subject
(
"
#{
@merge_request
.
title
}
(#
#{
@merge_request
.
iid
}
)"
))
subject:
subject
(
"
#{
@merge_request
.
title
}
(#
#{
@merge_request
.
iid
}
)"
))
SentNotification
.
record
(
@merge_request
,
recipient_id
,
reply_key
)
end
end
def
merge_request_status_email
(
recipient_id
,
merge_request_id
,
status
,
updated_by_user_id
)
def
merge_request_status_email
(
recipient_id
,
merge_request_id
,
status
,
updated_by_user_id
)
@merge_request
=
MergeRequest
.
find
(
merge_request_id
)
setup_merge_request_mail
(
merge_request_id
,
recipient_id
)
@mr_status
=
status
@mr_status
=
status
@project
=
@merge_request
.
project
@updated_by
=
User
.
find
updated_by_user_id
@updated_by
=
User
.
find
updated_by_user_id
@target_url
=
namespace_project_merge_request_url
(
@project
.
namespace
,
@project
,
@merge_request
)
mail_answer_thread
(
@merge_request
,
mail_answer_thread
(
@merge_request
,
from:
sender
(
updated_by_user_id
),
from:
sender
(
updated_by_user_id
),
to:
recipient
(
recipient_id
),
to:
recipient
(
recipient_id
),
subject:
subject
(
"
#{
@merge_request
.
title
}
(#
#{
@merge_request
.
iid
}
)"
))
subject:
subject
(
"
#{
@merge_request
.
title
}
(#
#{
@merge_request
.
iid
}
)"
))
end
private
def
setup_merge_request_mail
(
merge_request_id
,
recipient_id
)
@merge_request
=
MergeRequest
.
find
(
merge_request_id
)
@project
=
@merge_request
.
project
@target_url
=
namespace_project_merge_request_url
(
@project
.
namespace
,
@project
,
@merge_request
)
SentNotification
.
record
(
@merge_request
,
recipient_id
,
reply_key
)
@sent_notification
=
SentNotification
.
record
(
@merge_request
,
recipient_id
,
reply_key
)
end
end
end
end
end
end
app/mailers/emails/notes.rb
View file @
58867eff
module
Emails
module
Emails
module
Notes
module
Notes
def
note_commit_email
(
recipient_id
,
note_id
)
def
note_commit_email
(
recipient_id
,
note_id
)
note_mail_with_notification
(
note_id
,
recipient_id
)
do
note_mail_with_notification
(
note_id
,
recipient_id
)
@commit
=
@note
.
noteable
@target_url
=
namespace_project_commit_url
(
*
note_target_url_options
)
@commit
=
@note
.
noteable
@target_url
=
namespace_project_commit_url
(
*
note_target_url_options
)
mail_answer_thread
(
@commit
,
from:
sender
(
@note
.
author_id
)
,
mail_answer_thread
(
@commit
,
to:
recipient
(
recipient
_id
),
from:
sender
(
@note
.
author
_id
),
subject:
subject
(
"
#{
@commit
.
title
}
(
#{
@commit
.
short_id
}
)"
))
to:
recipient
(
recipient_id
),
end
subject:
subject
(
"
#{
@commit
.
title
}
(
#{
@commit
.
short_id
}
)"
))
end
end
def
note_issue_email
(
recipient_id
,
note_id
)
def
note_issue_email
(
recipient_id
,
note_id
)
note_mail_with_notification
(
note_id
,
recipient_id
)
do
note_mail_with_notification
(
note_id
,
recipient_id
)
@issue
=
@note
.
noteable
@target_url
=
namespace_project_issue_url
(
*
note_target_url_options
)
@issue
=
@note
.
noteable
mail_answer_thread
(
@issue
,
note_thread_options
(
recipient_id
)
)
@target_url
=
namespace_project_issue_url
(
*
note_target_url_options
)
end
mail_answer_thread
(
@issue
,
note_thread_options
(
recipient_id
))
end
end
def
note_merge_request_email
(
recipient_id
,
note_id
)
def
note_merge_request_email
(
recipient_id
,
note_id
)
note_mail_with_notification
(
note_id
,
recipient_id
)
do
note_mail_with_notification
(
note_id
,
recipient_id
)
@merge_request
=
@note
.
noteable
@target_url
=
namespace_project_merge_request_url
(
*
note_target_url_options
)
@merge_request
=
@note
.
noteable
mail_answer_thread
(
@merge_request
,
note_thread_options
(
recipient_id
)
)
@target_url
=
namespace_project_merge_request_url
(
*
note_target_url_options
)
end
mail_answer_thread
(
@merge_request
,
note_thread_options
(
recipient_id
))
end
end
private
private
...
@@ -46,9 +46,7 @@ module Emails
...
@@ -46,9 +46,7 @@ module Emails
@note
=
Note
.
find
(
note_id
)
@note
=
Note
.
find
(
note_id
)
@project
=
@note
.
project
@project
=
@note
.
project
yield
@sent_notification
=
SentNotification
.
record_note
(
@note
,
recipient_id
,
reply_key
)
SentNotification
.
record_note
(
@note
,
recipient_id
,
reply_key
)
end
end
end
end
end
end
app/mailers/notify.rb
View file @
58867eff
...
@@ -107,10 +107,9 @@ class Notify < BaseMailer
...
@@ -107,10 +107,9 @@ class Notify < BaseMailer
end
end
headers
[
"X-GitLab-
#{
model
.
class
.
name
}
-ID"
]
=
model
.
id
headers
[
"X-GitLab-
#{
model
.
class
.
name
}
-ID"
]
=
model
.
id
headers
[
'X-GitLab-Reply-Key'
]
=
reply_key
if
reply_key
if
Gitlab
::
IncomingEmail
.
enabled?
headers
[
'X-GitLab-Reply-Key'
]
=
reply_key
address
=
Mail
::
Address
.
new
(
Gitlab
::
IncomingEmail
.
reply_address
(
reply_key
))
address
=
Mail
::
Address
.
new
(
Gitlab
::
IncomingEmail
.
reply_address
(
reply_key
))
address
.
display_name
=
@project
.
name_with_namespace
address
.
display_name
=
@project
.
name_with_namespace
...
...
app/models/concerns/issuable.rb
View file @
58867eff
...
@@ -119,6 +119,12 @@ module Issuable
...
@@ -119,6 +119,12 @@ module Issuable
update
(
subscribed:
!
subscribed?
(
user
))
update
(
subscribed:
!
subscribed?
(
user
))
end
end
def
unsubscribe
(
user
)
subscriptions
.
find_or_initialize_by
(
user_id:
user
.
id
).
update
(
subscribed:
false
)
end
def
to_hook_data
(
user
)
def
to_hook_data
(
user
)
{
{
object_kind:
self
.
class
.
name
.
underscore
,
object_kind:
self
.
class
.
name
.
underscore
,
...
...
app/models/sent_notification.rb
View file @
58867eff
...
@@ -25,8 +25,6 @@ class SentNotification < ActiveRecord::Base
...
@@ -25,8 +25,6 @@ class SentNotification < ActiveRecord::Base
class
<<
self
class
<<
self
def
reply_key
def
reply_key
return
nil
unless
Gitlab
::
IncomingEmail
.
enabled?
SecureRandom
.
hex
(
16
)
SecureRandom
.
hex
(
16
)
end
end
...
@@ -59,7 +57,7 @@ class SentNotification < ActiveRecord::Base
...
@@ -59,7 +57,7 @@ class SentNotification < ActiveRecord::Base
def
record_note
(
note
,
recipient_id
,
reply_key
,
params
=
{})
def
record_note
(
note
,
recipient_id
,
reply_key
,
params
=
{})
params
[
:line_code
]
=
note
.
line_code
params
[
:line_code
]
=
note
.
line_code
record
(
note
.
noteable
,
recipient_id
,
reply_key
,
params
)
record
(
note
.
noteable
,
recipient_id
,
reply_key
,
params
)
end
end
end
end
...
@@ -75,4 +73,8 @@ class SentNotification < ActiveRecord::Base
...
@@ -75,4 +73,8 @@ class SentNotification < ActiveRecord::Base
super
super
end
end
end
end
def
to_param
self
.
reply_key
end
end
end
app/views/layouts/notify.html.haml
View file @
58867eff
...
@@ -44,6 +44,10 @@
...
@@ -44,6 +44,10 @@
%br
%br
-# Don't link the host is the line below, one link in the email is easier to quickly click than two.
-# Don't link the host is the line below, one link in the email is easier to quickly click than two.
You're receiving this email because of your account on
#{
Gitlab
.
config
.
gitlab
.
host
}
.
You're receiving this email because of your account on
#{
Gitlab
.
config
.
gitlab
.
host
}
.
If you'd like to receive fewer emails, you can adjust your notification settings.
If you'd like to receive fewer emails, you can
-
if
@sent_notification
&&
!
@sent_notification
.
for_commit?
=
link_to
"unsubscribe"
,
unsubscribe_sent_notification_url
(
@sent_notification
)
from this thread or
adjust your notification settings.
=
email_action
@target_url
=
email_action
@target_url
\ No newline at end of file
config/routes.rb
View file @
58867eff
...
@@ -88,6 +88,12 @@ Rails.application.routes.draw do
...
@@ -88,6 +88,12 @@ Rails.application.routes.draw do
end
end
end
end
resources
:sent_notifications
,
only:
[],
constraints:
{
id:
/[0-9a-f]{32}/
}
do
member
do
get
:unsubscribe
end
end
# Spam reports
# Spam reports
resources
:abuse_reports
,
only:
[
:new
,
:create
]
resources
:abuse_reports
,
only:
[
:new
,
:create
]
...
...
spec/controllers/sent_notification_controller_spec.rb
0 → 100644
View file @
58867eff
require
'rails_helper'
describe
SentNotificationsController
,
type: :controller
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:issue
)
{
create
(
:issue
,
author:
user
)
}
let
(
:sent_notification
)
{
create
(
:sent_notification
,
noteable:
issue
)
}
describe
'GET #unsubscribe'
do
it
'returns a 404 when calling without existing id'
do
get
(
:unsubscribe
,
id:
'0'
*
32
)
expect
(
response
.
status
).
to
be
404
end
context
'calling with id'
do
it
'shows a flash message to the user'
do
get
(
:unsubscribe
,
id:
sent_notification
.
reply_key
)
expect
(
response
.
status
).
to
be
302
expect
(
response
).
to
redirect_to
new_user_session_path
expect
(
controller
).
to
set_flash
[
:notice
].
to
(
/unsubscribed/
).
now
end
end
end
end
spec/factories.rb
View file @
58867eff
...
@@ -212,4 +212,11 @@ FactoryGirl.define do
...
@@ -212,4 +212,11 @@ FactoryGirl.define do
provider
'ldapmain'
provider
'ldapmain'
extern_uid
'my-ldap-id'
extern_uid
'my-ldap-id'
end
end
factory
:sent_notification
do
project
recipient
factory: :user
noteable
factory: :issue
reply_key
"0123456789abcdef"
*
2
end
end
end
spec/mailers/notify_spec.rb
View file @
58867eff
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment