Merge branch '47672-set_inline_content_type_for_ics' into 'master'

Render calendar feed inline when accessed from GitLab

Closes #47672

See merge request gitlab-org/gitlab-ce!19698
This commit is contained in:
Douwe Maan 2018-06-18 09:35:20 +00:00
commit a170c587a0
7 changed files with 87 additions and 42 deletions

View file

@ -1,6 +1,7 @@
module IssuesAction module IssuesAction
extend ActiveSupport::Concern extend ActiveSupport::Concern
include IssuableCollections include IssuableCollections
include IssuesCalendar
# rubocop:disable Gitlab/ModuleWithInstanceVariables # rubocop:disable Gitlab/ModuleWithInstanceVariables
def issues def issues
@ -17,18 +18,9 @@ module IssuesAction
end end
# rubocop:enable Gitlab/ModuleWithInstanceVariables # rubocop:enable Gitlab/ModuleWithInstanceVariables
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def issues_calendar def issues_calendar
@issues = issuables_collection render_issues_calendar(issuables_collection)
.non_archived
.with_due_date
.limit(100)
respond_to do |format|
format.ics { response.headers['Content-Disposition'] = 'inline' }
end end
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
private private

View file

@ -0,0 +1,24 @@
module IssuesCalendar
extend ActiveSupport::Concern
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def render_issues_calendar(issuables)
@issues = issuables
.non_archived
.with_due_date
.limit(100)
respond_to do |format|
format.ics do
# NOTE: with text/calendar as Content-Type, the browser always downloads
# the content as a file (even ignoring the Content-Disposition
# header). We want to display the content inline when accessed
# from GitLab, similarly to the RSS feed.
if request.referer&.start_with?(::Settings.gitlab.base_url)
response.headers['Content-Type'] = 'text/plain'
end
end
end
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
end

View file

@ -4,6 +4,7 @@ class Projects::IssuesController < Projects::ApplicationController
include IssuableActions include IssuableActions
include ToggleAwardEmoji include ToggleAwardEmoji
include IssuableCollections include IssuableCollections
include IssuesCalendar
include SpammableActions include SpammableActions
prepend_before_action :authenticate_user!, only: [:new] prepend_before_action :authenticate_user!, only: [:new]
@ -40,14 +41,7 @@ class Projects::IssuesController < Projects::ApplicationController
end end
def calendar def calendar
@issues = @issuables render_issues_calendar(@issuables)
.non_archived
.with_due_date
.limit(100)
respond_to do |format|
format.ics { response.headers['Content-Disposition'] = 'inline' }
end
end end
def new def new

View file

@ -0,0 +1,5 @@
---
title: Render calendar feed inline when accessed from GitLab
merge_request:
author:
type: fixed

View file

@ -11,16 +11,28 @@ describe 'Dashboard Issues Calendar Feed' do
end end
context 'when authenticated' do context 'when authenticated' do
context 'with no referer' do
it 'renders calendar feed' do it 'renders calendar feed' do
sign_in user sign_in user
visit issues_dashboard_path(:ics) visit issues_dashboard_path(:ics)
expect(response_headers['Content-Type']).to have_content('text/calendar') expect(response_headers['Content-Type']).to have_content('text/calendar')
expect(response_headers['Content-Disposition']).to have_content('inline')
expect(body).to have_text('BEGIN:VCALENDAR') expect(body).to have_text('BEGIN:VCALENDAR')
end end
end end
context 'with GitLab as the referer' do
it 'renders calendar feed as text/plain' do
sign_in user
page.driver.header('Referer', issues_dashboard_url(host: Settings.gitlab.base_url))
visit issues_dashboard_path(:ics)
expect(response_headers['Content-Type']).to have_content('text/plain')
expect(body).to have_text('BEGIN:VCALENDAR')
end
end
end
context 'when authenticated via personal access token' do context 'when authenticated via personal access token' do
it 'renders calendar feed' do it 'renders calendar feed' do
personal_access_token = create(:personal_access_token, user: user) personal_access_token = create(:personal_access_token, user: user)
@ -28,7 +40,6 @@ describe 'Dashboard Issues Calendar Feed' do
visit issues_dashboard_path(:ics, private_token: personal_access_token.token) visit issues_dashboard_path(:ics, private_token: personal_access_token.token)
expect(response_headers['Content-Type']).to have_content('text/calendar') expect(response_headers['Content-Type']).to have_content('text/calendar')
expect(response_headers['Content-Disposition']).to have_content('inline')
expect(body).to have_text('BEGIN:VCALENDAR') expect(body).to have_text('BEGIN:VCALENDAR')
end end
end end
@ -38,7 +49,6 @@ describe 'Dashboard Issues Calendar Feed' do
visit issues_dashboard_path(:ics, feed_token: user.feed_token) visit issues_dashboard_path(:ics, feed_token: user.feed_token)
expect(response_headers['Content-Type']).to have_content('text/calendar') expect(response_headers['Content-Type']).to have_content('text/calendar')
expect(response_headers['Content-Disposition']).to have_content('inline')
expect(body).to have_text('BEGIN:VCALENDAR') expect(body).to have_text('BEGIN:VCALENDAR')
end end
end end

View file

@ -13,16 +13,28 @@ describe 'Group Issues Calendar Feed' do
end end
context 'when authenticated' do context 'when authenticated' do
context 'with no referer' do
it 'renders calendar feed' do it 'renders calendar feed' do
sign_in user sign_in user
visit issues_group_path(group, :ics) visit issues_group_path(group, :ics)
expect(response_headers['Content-Type']).to have_content('text/calendar') expect(response_headers['Content-Type']).to have_content('text/calendar')
expect(response_headers['Content-Disposition']).to have_content('inline')
expect(body).to have_text('BEGIN:VCALENDAR') expect(body).to have_text('BEGIN:VCALENDAR')
end end
end end
context 'with GitLab as the referer' do
it 'renders calendar feed as text/plain' do
sign_in user
page.driver.header('Referer', issues_group_url(group, host: Settings.gitlab.base_url))
visit issues_group_path(group, :ics)
expect(response_headers['Content-Type']).to have_content('text/plain')
expect(body).to have_text('BEGIN:VCALENDAR')
end
end
end
context 'when authenticated via personal access token' do context 'when authenticated via personal access token' do
it 'renders calendar feed' do it 'renders calendar feed' do
personal_access_token = create(:personal_access_token, user: user) personal_access_token = create(:personal_access_token, user: user)
@ -30,7 +42,6 @@ describe 'Group Issues Calendar Feed' do
visit issues_group_path(group, :ics, private_token: personal_access_token.token) visit issues_group_path(group, :ics, private_token: personal_access_token.token)
expect(response_headers['Content-Type']).to have_content('text/calendar') expect(response_headers['Content-Type']).to have_content('text/calendar')
expect(response_headers['Content-Disposition']).to have_content('inline')
expect(body).to have_text('BEGIN:VCALENDAR') expect(body).to have_text('BEGIN:VCALENDAR')
end end
end end
@ -40,7 +51,6 @@ describe 'Group Issues Calendar Feed' do
visit issues_group_path(group, :ics, feed_token: user.feed_token) visit issues_group_path(group, :ics, feed_token: user.feed_token)
expect(response_headers['Content-Type']).to have_content('text/calendar') expect(response_headers['Content-Type']).to have_content('text/calendar')
expect(response_headers['Content-Disposition']).to have_content('inline')
expect(body).to have_text('BEGIN:VCALENDAR') expect(body).to have_text('BEGIN:VCALENDAR')
end end
end end

View file

@ -12,16 +12,28 @@ describe 'Project Issues Calendar Feed' do
end end
context 'when authenticated' do context 'when authenticated' do
context 'with no referer' do
it 'renders calendar feed' do it 'renders calendar feed' do
sign_in user sign_in user
visit project_issues_path(project, :ics) visit project_issues_path(project, :ics)
expect(response_headers['Content-Type']).to have_content('text/calendar') expect(response_headers['Content-Type']).to have_content('text/calendar')
expect(response_headers['Content-Disposition']).to have_content('inline')
expect(body).to have_text('BEGIN:VCALENDAR') expect(body).to have_text('BEGIN:VCALENDAR')
end end
end end
context 'with GitLab as the referer' do
it 'renders calendar feed as text/plain' do
sign_in user
page.driver.header('Referer', project_issues_url(project, host: Settings.gitlab.base_url))
visit project_issues_path(project, :ics)
expect(response_headers['Content-Type']).to have_content('text/plain')
expect(body).to have_text('BEGIN:VCALENDAR')
end
end
end
context 'when authenticated via personal access token' do context 'when authenticated via personal access token' do
it 'renders calendar feed' do it 'renders calendar feed' do
personal_access_token = create(:personal_access_token, user: user) personal_access_token = create(:personal_access_token, user: user)
@ -29,7 +41,6 @@ describe 'Project Issues Calendar Feed' do
visit project_issues_path(project, :ics, private_token: personal_access_token.token) visit project_issues_path(project, :ics, private_token: personal_access_token.token)
expect(response_headers['Content-Type']).to have_content('text/calendar') expect(response_headers['Content-Type']).to have_content('text/calendar')
expect(response_headers['Content-Disposition']).to have_content('inline')
expect(body).to have_text('BEGIN:VCALENDAR') expect(body).to have_text('BEGIN:VCALENDAR')
end end
end end
@ -39,7 +50,6 @@ describe 'Project Issues Calendar Feed' do
visit project_issues_path(project, :ics, feed_token: user.feed_token) visit project_issues_path(project, :ics, feed_token: user.feed_token)
expect(response_headers['Content-Type']).to have_content('text/calendar') expect(response_headers['Content-Type']).to have_content('text/calendar')
expect(response_headers['Content-Disposition']).to have_content('inline')
expect(body).to have_text('BEGIN:VCALENDAR') expect(body).to have_text('BEGIN:VCALENDAR')
end end
end end