Show public RSS feeds to anonymous users

This commit is contained in:
Michael Kozono 2017-02-28 12:50:57 -08:00
parent 05c8ec6cb8
commit a2670ee06b
35 changed files with 348 additions and 63 deletions

View file

@ -0,0 +1,5 @@
module RssHelper
def rss_url_options
{ format: :atom, private_token: current_user.try(:private_token) }
end
end

View file

@ -2,10 +2,9 @@
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
.nav-block .nav-block
- if current_user .controls
.controls = link_to dashboard_projects_path(rss_url_options), class: 'btn rss-btn has-tooltip', title: 'Subscribe' do
= link_to dashboard_projects_path(:atom, { private_token: current_user.private_token }), class: 'btn rss-btn has-tooltip', title: 'Subscribe' do %i.fa.fa-rss
%i.fa.fa-rss
= render 'shared/event_filter' = render 'shared/event_filter'
.content_list .content_list

View file

@ -1,6 +1,5 @@
= content_for :meta_tags do = content_for :meta_tags do
- if current_user = auto_discovery_link_tag(:atom, dashboard_projects_url(rss_url_options), title: "All activity")
= auto_discovery_link_tag(:atom, dashboard_projects_url(format: :atom, private_token: current_user.private_token), title: "All activity")
- page_title "Activity" - page_title "Activity"
- header_title "Activity", activity_dashboard_path - header_title "Activity", activity_dashboard_path

View file

@ -1,17 +1,15 @@
- page_title "Issues" - page_title "Issues"
- header_title "Issues", issues_dashboard_path(assignee_id: current_user.id) - header_title "Issues", issues_dashboard_path(assignee_id: current_user.id)
= content_for :meta_tags do = content_for :meta_tags do
- if current_user = auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{current_user.name} issues")
= auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{current_user.name} issues")
.top-area .top-area
= render 'shared/issuable/nav', type: :issues = render 'shared/issuable/nav', type: :issues
.nav-controls .nav-controls
- if current_user = link_to params.merge(rss_url_options), class: 'btn' do
= link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn' do = icon('rss')
= icon('rss') %span.icon-label
%span.icon-label Subscribe
Subscribe
= render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue" = render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue"
= render 'shared/issuable/filter', type: :issues = render 'shared/issuable/filter', type: :issues

View file

@ -1,7 +1,7 @@
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "Activity" xml.title "Activity"
xml.link href: dashboard_projects_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" xml.link href: dashboard_projects_url(rss_url_options), rel: "self", type: "application/atom+xml"
xml.link href: dashboard_projects_url, rel: "alternate", type: "text/html" xml.link href: dashboard_projects_url, rel: "alternate", type: "text/html"
xml.id dashboard_projects_url xml.id dashboard_projects_url
xml.updated @events[0].updated_at.xmlschema if @events[0] xml.updated @events[0].updated_at.xmlschema if @events[0]

View file

@ -1,6 +1,5 @@
= content_for :meta_tags do = content_for :meta_tags do
- if current_user = auto_discovery_link_tag(:atom, dashboard_projects_url(rss_url_options), title: "All activity")
= auto_discovery_link_tag(:atom, dashboard_projects_url(format: :atom, private_token: current_user.private_token), title: "All activity")
- page_title "Projects" - page_title "Projects"
- header_title "Projects", dashboard_projects_path - header_title "Projects", dashboard_projects_path

View file

@ -2,10 +2,9 @@
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
.nav-block .nav-block
- if current_user .controls
.controls = link_to group_path(@group, rss_url_options), class: 'btn rss-btn has-tooltip' , title: 'Subscribe' do
= link_to group_path(@group, format: :atom, private_token: current_user.private_token), class: 'btn rss-btn has-tooltip' , title: 'Subscribe' do %i.fa.fa-rss
%i.fa.fa-rss
= render 'shared/event_filter' = render 'shared/event_filter'
.content_list .content_list

View file

@ -1,6 +1,5 @@
= content_for :meta_tags do = content_for :meta_tags do
- if current_user = auto_discovery_link_tag(:atom, group_url(@group, rss_url_options), title: "#{@group.name} activity")
= auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity")
- page_title "Activity" - page_title "Activity"
= render 'groups/head' = render 'groups/head'

View file

@ -1,19 +1,17 @@
- page_title "Issues" - page_title "Issues"
= render "head_issues" = render "head_issues"
= content_for :meta_tags do = content_for :meta_tags do
- if current_user = auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@group.name} issues")
= auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@group.name} issues")
- if group_issues(@group).exists? - if group_issues(@group).exists?
.top-area .top-area
= render 'shared/issuable/nav', type: :issues = render 'shared/issuable/nav', type: :issues
- if current_user .nav-controls
.nav-controls = link_to params.merge(rss_url_options), class: 'btn' do
= link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn' do = icon('rss')
= icon('rss') %span.icon-label
%span.icon-label Subscribe
Subscribe = render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue"
= render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue"
= render 'shared/issuable/filter', type: :issues = render 'shared/issuable/filter', type: :issues

View file

@ -1,7 +1,7 @@
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@group.name} activity" xml.title "#{@group.name} activity"
xml.link href: group_url(@group, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" xml.link href: group_url(@group, rss_url_options), rel: "self", type: "application/atom+xml"
xml.link href: group_url(@group), rel: "alternate", type: "text/html" xml.link href: group_url(@group), rel: "alternate", type: "text/html"
xml.id group_url(@group) xml.id group_url(@group)
xml.updated @events[0].updated_at.xmlschema if @events[0] xml.updated @events[0].updated_at.xmlschema if @events[0]

View file

@ -1,8 +1,7 @@
- @no_container = true - @no_container = true
= content_for :meta_tags do = content_for :meta_tags do
- if current_user = auto_discovery_link_tag(:atom, group_url(@group, rss_url_options), title: "#{@group.name} activity")
= auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity")
= render 'groups/head' = render 'groups/head'
= render 'groups/home_panel' = render 'groups/home_panel'

View file

@ -2,10 +2,9 @@
%div{ class: container_class } %div{ class: container_class }
.nav-block.activity-filter-block .nav-block.activity-filter-block
- if current_user .controls
.controls = link_to namespace_project_path(@project.namespace, @project, rss_url_options), title: "Subscribe", class: 'btn rss-btn has-tooltip' do
= link_to namespace_project_path(@project.namespace, @project, format: :atom, private_token: current_user.private_token), title: "Subscribe", class: 'btn rss-btn has-tooltip' do = icon('rss')
= icon('rss')
= render 'shared/event_filter' = render 'shared/event_filter'

View file

@ -1,7 +1,7 @@
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@project.name}:#{@ref} commits" xml.title "#{@project.name}:#{@ref} commits"
xml.link href: namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" xml.link href: namespace_project_commits_url(@project.namespace, @project, @ref, rss_url_options), rel: "self", type: "application/atom+xml"
xml.link href: namespace_project_commits_url(@project.namespace, @project, @ref), rel: "alternate", type: "text/html" xml.link href: namespace_project_commits_url(@project.namespace, @project, @ref), rel: "alternate", type: "text/html"
xml.id namespace_project_commits_url(@project.namespace, @project, @ref) xml.id namespace_project_commits_url(@project.namespace, @project, @ref)
xml.updated @commits.first.committed_date.xmlschema if @commits.any? xml.updated @commits.first.committed_date.xmlschema if @commits.any?

View file

@ -2,8 +2,7 @@
- page_title "Commits", @ref - page_title "Commits", @ref
= content_for :meta_tags do = content_for :meta_tags do
- if current_user = auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits")
= auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits")
= content_for :sub_nav do = content_for :sub_nav do
= render "head" = render "head"
@ -27,10 +26,9 @@
.control .control
= form_tag(namespace_project_commits_path(@project.namespace, @project, @id), method: :get, class: 'commits-search-form') do = form_tag(namespace_project_commits_path(@project.namespace, @project, @id), method: :get, class: 'commits-search-form') do
= search_field_tag :search, params[:search], { placeholder: 'Filter by commit message', id: 'commits-search', class: 'form-control search-text-input input-short', spellcheck: false } = search_field_tag :search, params[:search], { placeholder: 'Filter by commit message', id: 'commits-search', class: 'form-control search-text-input input-short', spellcheck: false }
- if current_user && current_user.private_token .control
.control = link_to namespace_project_commits_path(@project.namespace, @project, @ref, rss_url_options), title: "Commits Feed", class: 'btn' do
= link_to namespace_project_commits_path(@project.namespace, @project, @ref, { format: :atom, private_token: current_user.private_token }), title: "Commits Feed", class: 'btn' do = icon("rss")
= icon("rss")
%div{ id: dom_id(@project) } %div{ id: dom_id(@project) }
%ol#commits-list.list-unstyled.content_list %ol#commits-list.list-unstyled.content_list

View file

@ -10,17 +10,15 @@
= page_specific_javascript_bundle_tag('filtered_search') = page_specific_javascript_bundle_tag('filtered_search')
= content_for :meta_tags do = content_for :meta_tags do
- if current_user = auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@project.name} issues")
= auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@project.name} issues")
- if project_issues(@project).exists? - if project_issues(@project).exists?
%div{ class: (container_class) } %div{ class: (container_class) }
.top-area .top-area
= render 'shared/issuable/nav', type: :issues = render 'shared/issuable/nav', type: :issues
.nav-controls .nav-controls
- if current_user = link_to params.merge(rss_url_options), class: 'btn append-right-10 has-tooltip', title: 'Subscribe' do
= link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn append-right-10 has-tooltip', title: 'Subscribe' do = icon('rss')
= icon('rss')
- if can? current_user, :create_issue, @project - if can? current_user, :create_issue, @project
= link_to new_namespace_project_issue_path(@project.namespace, = link_to new_namespace_project_issue_path(@project.namespace,
@project, @project,

View file

@ -1,7 +1,7 @@
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@project.name} activity" xml.title "#{@project.name} activity"
xml.link href: namespace_project_url(@project.namespace, @project, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" xml.link href: namespace_project_url(@project.namespace, @project, rss_url_options), rel: "self", type: "application/atom+xml"
xml.link href: namespace_project_url(@project.namespace, @project), rel: "alternate", type: "text/html" xml.link href: namespace_project_url(@project.namespace, @project), rel: "alternate", type: "text/html"
xml.id namespace_project_url(@project.namespace, @project) xml.id namespace_project_url(@project.namespace, @project)
xml.updated @events[0].updated_at.xmlschema if @events[0] xml.updated @events[0].updated_at.xmlschema if @events[0]

View file

@ -1,8 +1,7 @@
- @no_container = true - @no_container = true
= content_for :meta_tags do = content_for :meta_tags do
- if current_user = auto_discovery_link_tag(:atom, namespace_project_path(@project.namespace, @project, rss_url_options), title: "#{@project.name} activity")
= auto_discovery_link_tag(:atom, namespace_project_path(@project.namespace, @project, format: :atom, private_token: current_user.private_token), title: "#{@project.name} activity")
= content_for :flash_message do = content_for :flash_message do
- if current_user && can?(current_user, :download_code, @project) - if current_user && can?(current_user, :download_code, @project)

View file

@ -2,8 +2,7 @@
- page_title @path.presence || "Files", @ref - page_title @path.presence || "Files", @ref
= content_for :meta_tags do = content_for :meta_tags do
- if current_user = auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits")
= auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits")
= render "projects/commits/head" = render "projects/commits/head"
= render 'projects/last_push' = render 'projects/last_push'

View file

@ -24,13 +24,12 @@
= link_to new_abuse_report_path(user_id: @user.id, ref_url: request.referrer), class: 'btn btn-gray', = link_to new_abuse_report_path(user_id: @user.id, ref_url: request.referrer), class: 'btn btn-gray',
title: 'Report abuse', data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do title: 'Report abuse', data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= icon('exclamation-circle') = icon('exclamation-circle')
- if current_user = link_to user_path(@user, rss_url_options), class: 'btn btn-gray' do
= link_to user_path(@user, :atom, { private_token: current_user.private_token }), class: 'btn btn-gray' do = icon('rss')
= icon('rss') - if current_user && current_user.admin?
- if current_user.admin? = link_to [:admin, @user], class: 'btn btn-gray', title: 'View user in admin area',
= link_to [:admin, @user], class: 'btn btn-gray', title: 'View user in admin area', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = icon('users')
= icon('users')
.profile-header .profile-header
.avatar-holder .avatar-holder

View file

@ -0,0 +1,4 @@
---
title: Show public RSS feeds to anonymous users
merge_request:
author:

View file

@ -0,0 +1,11 @@
require 'spec_helper'
RSpec.describe 'Dashboard Activity', feature: true do
before do
login_as(create :user)
visit activity_dashboard_path
end
it_behaves_like "it has an RSS button with current_user's private token"
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
end

View file

@ -45,4 +45,7 @@ RSpec.describe 'Dashboard Issues', feature: true do
expect(page).to have_content(assigned_issue.title) expect(page).to have_content(assigned_issue.title)
expect(page).to have_content(other_issue.title) expect(page).to have_content(other_issue.title)
end end
it_behaves_like "it has an RSS button with current_user's private token"
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
end end

View file

@ -0,0 +1,10 @@
require 'spec_helper'
RSpec.describe 'Dashboard Projects', feature: true do
before do
login_as(create :user)
visit dashboard_projects_path
end
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
end

View file

@ -0,0 +1,26 @@
require 'spec_helper'
feature 'Group activity page', feature: true do
let(:group) { create(:group) }
let(:path) { activity_group_path(group) }
context 'when signed in' do
before do
user = create(:group_member, :developer, user: create(:user), group: group ).user
login_as(user)
visit path
end
it_behaves_like "it has an RSS button with current_user's private token"
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
end
context 'when signed out' do
before do
visit path
end
it_behaves_like "it has an RSS button without a private token"
it_behaves_like "an autodiscoverable RSS feed without a private token"
end
end

View file

@ -5,4 +5,22 @@ feature 'Group issues page', feature: true do
let(:issuable) { create(:issue, project: project, title: "this is my created issuable")} let(:issuable) { create(:issue, project: project, title: "this is my created issuable")}
include_examples 'project features apply to issuables', Issue include_examples 'project features apply to issuables', Issue
context 'rss feed' do
let(:access_level) { ProjectFeature::ENABLED }
context 'when signed in' do
let(:user) { user_in_group }
it_behaves_like "it has an RSS button with current_user's private token"
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
end
context 'when signed out' do
let(:user) { nil }
it_behaves_like "it has an RSS button without a private token"
it_behaves_like "an autodiscoverable RSS feed without a private token"
end
end
end end

View file

@ -0,0 +1,24 @@
require 'spec_helper'
feature 'Group show page', feature: true do
let(:group) { create(:group) }
let(:path) { group_path(group) }
context 'when signed in' do
before do
user = create(:group_member, :developer, user: create(:user), group: group ).user
login_as(user)
visit path
end
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
end
context 'when signed out' do
before do
visit path
end
it_behaves_like "an autodiscoverable RSS feed without a private token"
end
end

View file

@ -0,0 +1,29 @@
require 'spec_helper'
feature 'Project Activity RSS' do
let(:project) { create(:empty_project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { activity_namespace_project_path(project.namespace, project) }
before do
create(:issue, project: project)
end
context 'when signed in' do
before do
user = create(:user)
project.team << [user, :developer]
login_as(user)
visit path
end
it_behaves_like "it has an RSS button with current_user's private token"
end
context 'when signed out' do
before do
visit path
end
it_behaves_like "it has an RSS button without a private token"
end
end

View file

@ -0,0 +1,27 @@
require 'spec_helper'
feature 'Project Commits RSS' do
let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { namespace_project_commits_path(project.namespace, project, :master) }
context 'when signed in' do
before do
user = create(:user)
project.team << [user, :developer]
login_as(user)
visit path
end
it_behaves_like "it has an RSS button with current_user's private token"
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
end
context 'when signed out' do
before do
visit path
end
it_behaves_like "it has an RSS button without a private token"
it_behaves_like "an autodiscoverable RSS feed without a private token"
end
end

View file

@ -0,0 +1,31 @@
require 'spec_helper'
feature 'Project Issues RSS' do
let(:project) { create(:empty_project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { namespace_project_issues_path(project.namespace, project) }
before do
create(:issue, project: project)
end
context 'when signed in' do
before do
user = create(:user)
project.team << [user, :developer]
login_as(user)
visit path
end
it_behaves_like "it has an RSS button with current_user's private token"
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
end
context 'when signed out' do
before do
visit path
end
it_behaves_like "it has an RSS button without a private token"
it_behaves_like "an autodiscoverable RSS feed without a private token"
end
end

View file

@ -0,0 +1,25 @@
require 'spec_helper'
feature 'Project RSS' do
let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { namespace_project_path(project.namespace, project) }
context 'when signed in' do
before do
user = create(:user)
project.team << [user, :developer]
login_as(user)
visit path
end
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
end
context 'when signed out' do
before do
visit path
end
it_behaves_like "an autodiscoverable RSS feed without a private token"
end
end

View file

@ -0,0 +1,25 @@
require 'spec_helper'
feature 'Project Tree RSS' do
let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { namespace_project_tree_path(project.namespace, project, :master) }
context 'when signed in' do
before do
user = create(:user)
project.team << [user, :developer]
login_as(user)
visit path
end
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
end
context 'when signed out' do
before do
visit path
end
it_behaves_like "an autodiscoverable RSS feed without a private token"
end
end

View file

@ -0,0 +1,22 @@
require 'spec_helper'
feature 'User RSS' do
let(:path) { user_path(create(:user)) }
context 'when signed in' do
before do
login_as(create(:user))
visit path
end
it_behaves_like "it has an RSS button with current_user's private token"
end
context 'when signed out' do
before do
visit path
end
it_behaves_like "it has an RSS button without a private token"
end
end

View file

@ -0,0 +1,20 @@
require 'spec_helper'
describe RssHelper do
describe '#rss_url_options' do
context 'when signed in' do
it "includes the current_user's private_token" do
current_user = create(:user)
allow(helper).to receive(:current_user).and_return(current_user)
expect(helper.rss_url_options).to include private_token: current_user.private_token
end
end
context 'when signed out' do
it "does not have a private_token" do
allow(helper).to receive(:current_user).and_return(nil)
expect(helper.rss_url_options[:private_token]).to be_nil
end
end
end
end

View file

@ -0,0 +1,23 @@
shared_examples "an autodiscoverable RSS feed with current_user's private token" do
it "has an RSS autodiscovery link tag with current_user's private token" do
expect(page).to have_css("link[type*='atom+xml'][href*='private_token=#{Thread.current[:current_user].private_token}']", visible: false)
end
end
shared_examples "it has an RSS button with current_user's private token" do
it "shows the RSS button with current_user's private token" do
expect(page).to have_css("a:has(.fa-rss)[href*='private_token=#{Thread.current[:current_user].private_token}']")
end
end
shared_examples "an autodiscoverable RSS feed without a private token" do
it "has an RSS autodiscovery link tag without a private token" do
expect(page).to have_css("link[type*='atom+xml']:not([href*='private_token'])", visible: false)
end
end
shared_examples "it has an RSS button without a private token" do
it "shows the RSS button without a private token" do
expect(page).to have_css("a:has(.fa-rss):not([href*='private_token'])")
end
end

View file

@ -18,7 +18,7 @@ shared_examples 'project features apply to issuables' do |klass|
before do before do
_ = issuable _ = issuable
login_as(user) login_as(user) if user
visit path visit path
end end