Skip to content
Snippets Groups Projects
Commit 6efe9c2f authored by Alexis Reigel's avatar Alexis Reigel
Browse files

atom links with rss token instead of private token

parent c1b5c806
No related branches found
No related tags found
No related merge requests found
Showing
with 144 additions and 54 deletions
Loading
Loading
@@ -11,6 +11,7 @@ class ApplicationController < ActionController::Base
include EnforcesTwoFactorAuthentication
 
before_action :authenticate_user_from_private_token!
before_action :authenticate_user_from_rss_token!
before_action :authenticate_user!
before_action :validate_user_service_ticket!
before_action :check_password_expiration
Loading
Loading
@@ -72,13 +73,20 @@ class ApplicationController < ActionController::Base
 
user = User.find_by_authentication_token(token) || User.find_by_personal_access_token(token)
 
if user && can?(user, :log_in)
# Notice we are passing store false, so the user is not
# actually stored in the session and a token is needed
# for every request. If you want the token to work as a
# sign in token, you can simply remove store: false.
sign_in user, store: false
end
sessionless_sign_in(user)
end
# This filter handles authentication for atom request with an rss_token
def authenticate_user_from_rss_token!
return unless request.format.atom?
token = params[:rss_token].presence
return unless token.present?
user = User.find_by_rss_token(token)
sessionless_sign_in(user)
end
 
def log_exception(exception)
Loading
Loading
@@ -282,4 +290,14 @@ class ApplicationController < ActionController::Base
ensure
Gitlab::I18n.reset_locale
end
def sessionless_sign_in(user)
if user && can?(user, :log_in)
# Notice we are passing store false, so the user is not
# actually stored in the session and a token is needed
# for every request. If you want the token to work as a
# sign in token, you can simply remove store: false.
sign_in user, store: false
end
end
end
module RssHelper
def rss_url_options
{ format: :atom, private_token: current_user.try(:private_token) }
{ format: :atom, rss_token: current_user.try(:rss_token) }
end
end
Loading
Loading
@@ -99,6 +99,42 @@ describe ApplicationController do
end
end
 
describe '#authenticate_user_from_rss_token' do
describe "authenticating a user from an rss token" do
controller(described_class) do
def index
render text: 'authenticated'
end
end
context "when the 'rss_token' param is populated with the rss token" do
context 'when the request format is atom' do
it "logs the user in" do
get :index, rss_token: user.rss_token, format: :atom
expect(response).to have_http_status 200
expect(response.body).to eq 'authenticated'
end
end
context 'when the request format is not atom' do
it "doesn't log the user in" do
get :index, rss_token: user.rss_token
expect(response.status).not_to have_http_status 200
expect(response.body).not_to eq 'authenticated'
end
end
end
context "when the 'rss_token' param is populated with an invalid rss token" do
it "doesn't log the user" do
get :index, rss_token: "token"
expect(response.status).not_to eq 200
expect(response.body).not_to eq 'authenticated'
end
end
end
end
describe '#route_not_found' do
it 'renders 404 if authenticated' do
allow(controller).to receive(:current_user).and_return(user)
Loading
Loading
Loading
Loading
@@ -20,13 +20,20 @@ describe "Dashboard Issues Feed", feature: true do
expect(body).to have_selector('title', text: "#{user.name} issues")
end
 
it "renders atom feed via rss token" do
visit issues_dashboard_path(:atom, rss_token: user.rss_token)
expect(response_headers['Content-Type']).to have_content('application/atom+xml')
expect(body).to have_selector('title', text: "#{user.name} issues")
end
it "renders atom feed with url parameters" do
visit issues_dashboard_path(:atom, private_token: user.private_token, state: 'opened', assignee_id: user.id)
visit issues_dashboard_path(:atom, rss_token: user.rss_token, state: 'opened', assignee_id: user.id)
 
link = find('link[type="application/atom+xml"]')
params = CGI.parse(URI.parse(link[:href]).query)
 
expect(params).to include('private_token' => [user.private_token])
expect(params).to include('rss_token' => [user.rss_token])
expect(params).to include('state' => ['opened'])
expect(params).to include('assignee_id' => [user.id.to_s])
end
Loading
Loading
@@ -35,7 +42,7 @@ describe "Dashboard Issues Feed", feature: true do
let!(:issue2) { create(:issue, author: user, assignees: [assignee], project: project2, description: 'test desc') }
 
it "renders issue fields" do
visit issues_dashboard_path(:atom, private_token: user.private_token)
visit issues_dashboard_path(:atom, rss_token: user.rss_token)
 
entry = find(:xpath, "//feed/entry[contains(summary/text(),'#{issue2.title}')]")
 
Loading
Loading
@@ -58,7 +65,7 @@ describe "Dashboard Issues Feed", feature: true do
end
 
it "renders issue label and milestone info" do
visit issues_dashboard_path(:atom, private_token: user.private_token)
visit issues_dashboard_path(:atom, rss_token: user.rss_token)
 
entry = find(:xpath, "//feed/entry[contains(summary/text(),'#{issue1.title}')]")
 
Loading
Loading
Loading
Loading
@@ -11,6 +11,13 @@ describe "Dashboard Feed", feature: true do
end
end
 
context "projects atom feed via rss token" do
it "renders projects atom feed" do
visit dashboard_projects_path(:atom, rss_token: user.rss_token)
expect(body).to have_selector('feed title')
end
end
context 'feed content' do
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project, author: user, description: '') }
Loading
Loading
@@ -20,7 +27,7 @@ describe "Dashboard Feed", feature: true do
project.team << [user, :master]
issue_event(issue, user)
note_event(note, user)
visit dashboard_projects_path(:atom, private_token: user.private_token)
visit dashboard_projects_path(:atom, rss_token: user.rss_token)
end
 
it "has issue opened event" do
Loading
Loading
Loading
Loading
@@ -43,25 +43,40 @@ describe 'Issues Feed', feature: true do
end
end
 
context 'when authenticated via rss token' do
it 'renders atom feed' do
visit namespace_project_issues_path(project.namespace, project, :atom,
rss_token: user.rss_token)
expect(response_headers['Content-Type']).
to have_content('application/atom+xml')
expect(body).to have_selector('title', text: "#{project.name} issues")
expect(body).to have_selector('author email', text: issue.author_public_email)
expect(body).to have_selector('assignees assignee email', text: issue.assignees.first.public_email)
expect(body).to have_selector('assignee email', text: issue.assignees.first.public_email)
expect(body).to have_selector('entry summary', text: issue.title)
end
end
it "renders atom feed with url parameters for project issues" do
visit namespace_project_issues_path(project.namespace, project,
:atom, private_token: user.private_token, state: 'opened', assignee_id: user.id)
:atom, rss_token: user.rss_token, state: 'opened', assignee_id: user.id)
 
link = find('link[type="application/atom+xml"]')
params = CGI.parse(URI.parse(link[:href]).query)
 
expect(params).to include('private_token' => [user.private_token])
expect(params).to include('rss_token' => [user.rss_token])
expect(params).to include('state' => ['opened'])
expect(params).to include('assignee_id' => [user.id.to_s])
end
 
it "renders atom feed with url parameters for group issues" do
visit issues_group_path(group, :atom, private_token: user.private_token, state: 'opened', assignee_id: user.id)
visit issues_group_path(group, :atom, rss_token: user.rss_token, state: 'opened', assignee_id: user.id)
 
link = find('link[type="application/atom+xml"]')
params = CGI.parse(URI.parse(link[:href]).query)
 
expect(params).to include('private_token' => [user.private_token])
expect(params).to include('rss_token' => [user.rss_token])
expect(params).to include('state' => ['opened'])
expect(params).to include('assignee_id' => [user.id.to_s])
end
Loading
Loading
Loading
Loading
@@ -11,6 +11,13 @@ describe "User Feed", feature: true do
end
end
 
context 'user atom feed via rss token' do
it "renders user atom feed" do
visit user_path(user, :atom, rss_token: user.rss_token)
expect(body).to have_selector('feed title')
end
end
context 'feed content' do
let(:project) { create(:project) }
let(:issue) do
Loading
Loading
@@ -40,7 +47,7 @@ describe "User Feed", feature: true do
issue_event(issue, user)
note_event(note, user)
merge_request_event(merge_request, user)
visit user_path(user, :atom, private_token: user.private_token)
visit user_path(user, :atom, rss_token: user.rss_token)
end
 
it 'has issue opened event' do
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@ RSpec.describe 'Dashboard Activity', feature: true 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"
it_behaves_like "it has an RSS button with current_user's rss token"
it_behaves_like "an autodiscoverable RSS feed with current_user's rss token"
end
Loading
Loading
@@ -62,6 +62,6 @@ RSpec.describe 'Dashboard Issues', feature: true do
expect(page).to have_content(other_issue.title)
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"
it_behaves_like "it has an RSS button with current_user's rss token"
it_behaves_like "an autodiscoverable RSS feed with current_user's rss token"
end
Loading
Loading
@@ -31,5 +31,5 @@ RSpec.describe 'Dashboard Projects', feature: true do
end
end
 
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
it_behaves_like "an autodiscoverable RSS feed with current_user's rss token"
end
Loading
Loading
@@ -53,10 +53,10 @@ describe "Dashboard Issues filtering", feature: true, js: true do
auto_discovery_link = find('link[type="application/atom+xml"]', visible: false)
auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query)
 
expect(params).to include('private_token' => [user.private_token])
expect(params).to include('rss_token' => [user.rss_token])
expect(params).to include('milestone_title' => [''])
expect(params).to include('assignee_id' => [user.id.to_s])
expect(auto_discovery_params).to include('private_token' => [user.private_token])
expect(auto_discovery_params).to include('rss_token' => [user.rss_token])
expect(auto_discovery_params).to include('milestone_title' => [''])
expect(auto_discovery_params).to include('assignee_id' => [user.id.to_s])
end
Loading
Loading
Loading
Loading
@@ -11,8 +11,8 @@ feature 'Group activity page', feature: true do
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"
it_behaves_like "it has an RSS button with current_user's rss token"
it_behaves_like "an autodiscoverable RSS feed with current_user's rss token"
end
 
context 'when signed out' do
Loading
Loading
@@ -20,7 +20,7 @@ feature 'Group activity page', feature: true 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"
it_behaves_like "it has an RSS button without an rss token"
it_behaves_like "an autodiscoverable RSS feed without an rss token"
end
end
Loading
Loading
@@ -12,15 +12,15 @@ feature 'Group issues page', feature: true do
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"
it_behaves_like "it has an RSS button with current_user's rss token"
it_behaves_like "an autodiscoverable RSS feed with current_user's rss 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"
it_behaves_like "it has an RSS button without an rss token"
it_behaves_like "an autodiscoverable RSS feed without an rss token"
end
end
 
Loading
Loading
Loading
Loading
@@ -11,7 +11,7 @@ feature 'Group show page', feature: true do
visit path
end
 
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
it_behaves_like "an autodiscoverable RSS feed with current_user's rss token"
end
 
context 'when signed out' do
Loading
Loading
@@ -19,6 +19,6 @@ feature 'Group show page', feature: true do
visit path
end
 
it_behaves_like "an autodiscoverable RSS feed without a private token"
it_behaves_like "an autodiscoverable RSS feed without an rss token"
end
end
Loading
Loading
@@ -810,10 +810,10 @@ describe 'Filter issues', js: true, feature: true do
auto_discovery_link = find('link[type="application/atom+xml"]', visible: false)
auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query)
 
expect(params).to include('private_token' => [user.private_token])
expect(params).to include('rss_token' => [user.rss_token])
expect(params).to include('milestone_title' => [milestone.title])
expect(params).to include('assignee_id' => [user.id.to_s])
expect(auto_discovery_params).to include('private_token' => [user.private_token])
expect(auto_discovery_params).to include('rss_token' => [user.rss_token])
expect(auto_discovery_params).to include('milestone_title' => [milestone.title])
expect(auto_discovery_params).to include('assignee_id' => [user.id.to_s])
end
Loading
Loading
@@ -825,10 +825,10 @@ describe 'Filter issues', js: true, feature: true do
auto_discovery_link = find('link[type="application/atom+xml"]', visible: false)
auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query)
 
expect(params).to include('private_token' => [user.private_token])
expect(params).to include('rss_token' => [user.rss_token])
expect(params).to include('milestone_title' => [milestone.title])
expect(params).to include('assignee_id' => [user.id.to_s])
expect(auto_discovery_params).to include('private_token' => [user.private_token])
expect(auto_discovery_params).to include('rss_token' => [user.rss_token])
expect(auto_discovery_params).to include('milestone_title' => [milestone.title])
expect(auto_discovery_params).to include('assignee_id' => [user.id.to_s])
end
Loading
Loading
Loading
Loading
@@ -16,7 +16,7 @@ feature 'Project Activity RSS' do
visit path
end
 
it_behaves_like "it has an RSS button with current_user's private token"
it_behaves_like "it has an RSS button with current_user's rss token"
end
 
context 'when signed out' do
Loading
Loading
@@ -24,6 +24,6 @@ feature 'Project Activity RSS' do
visit path
end
 
it_behaves_like "it has an RSS button without a private token"
it_behaves_like "it has an RSS button without an rss token"
end
end
Loading
Loading
@@ -12,8 +12,8 @@ feature 'Project Commits RSS' do
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"
it_behaves_like "it has an RSS button with current_user's rss token"
it_behaves_like "an autodiscoverable RSS feed with current_user's rss token"
end
 
context 'when signed out' do
Loading
Loading
@@ -21,7 +21,7 @@ feature 'Project Commits RSS' 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"
it_behaves_like "it has an RSS button without an rss token"
it_behaves_like "an autodiscoverable RSS feed without an rss token"
end
end
Loading
Loading
@@ -16,8 +16,8 @@ feature 'Project Issues RSS' do
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"
it_behaves_like "it has an RSS button with current_user's rss token"
it_behaves_like "an autodiscoverable RSS feed with current_user's rss token"
end
 
context 'when signed out' do
Loading
Loading
@@ -25,7 +25,7 @@ feature 'Project Issues RSS' 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"
it_behaves_like "it has an RSS button without an rss token"
it_behaves_like "an autodiscoverable RSS feed without an rss token"
end
end
Loading
Loading
@@ -12,7 +12,7 @@ feature 'Project RSS' do
visit path
end
 
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
it_behaves_like "an autodiscoverable RSS feed with current_user's rss token"
end
 
context 'when signed out' do
Loading
Loading
@@ -20,6 +20,6 @@ feature 'Project RSS' do
visit path
end
 
it_behaves_like "an autodiscoverable RSS feed without a private token"
it_behaves_like "an autodiscoverable RSS feed without an rss token"
end
end
Loading
Loading
@@ -12,7 +12,7 @@ feature 'Project Tree RSS' do
visit path
end
 
it_behaves_like "an autodiscoverable RSS feed with current_user's private token"
it_behaves_like "an autodiscoverable RSS feed with current_user's rss token"
end
 
context 'when signed out' do
Loading
Loading
@@ -20,6 +20,6 @@ feature 'Project Tree RSS' do
visit path
end
 
it_behaves_like "an autodiscoverable RSS feed without a private token"
it_behaves_like "an autodiscoverable RSS feed without an rss token"
end
end
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