Commit 3e090e0c authored by Bogdan Denkovych's avatar Bogdan Denkovych Committed by GitLab Release Tools Bot

User with expired password can still access sensitive info

parent 5f50d33e
......@@ -20,7 +20,7 @@ module SessionlessAuthentication
end
def sessionless_sign_in(user)
if user && can?(user, :log_in)
if can?(user, :log_in) && !user.password_expired_if_applicable?
# 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
......
......@@ -8,10 +8,6 @@ RSpec.describe Dashboard::ProjectsController, :aggregate_failures do
let_it_be(:user) { create(:user) }
describe '#index' do
context 'user not logged in' do
it_behaves_like 'authenticates sessionless user', :index, :atom
end
context 'user logged in' do
let_it_be(:project) { create(:project, name: 'Project 1') }
let_it_be(:project2) { create(:project, name: 'Project Two') }
......
......@@ -72,9 +72,6 @@ RSpec.describe DashboardController do
end
end
it_behaves_like 'authenticates sessionless user', :issues, :atom, author_id: User.first
it_behaves_like 'authenticates sessionless user', :issues_calendar, :ics
describe "#check_filters_presence!" do
let(:user) { create(:user) }
......
......@@ -1209,26 +1209,6 @@ RSpec.describe GroupsController, factory_default: :keep do
end
end
context 'token authentication' do
it_behaves_like 'authenticates sessionless user', :show, :atom, public: true do
before do
default_params.merge!(id: group)
end
end
it_behaves_like 'authenticates sessionless user', :issues, :atom, public: true do
before do
default_params.merge!(id: group, author_id: user.id)
end
end
it_behaves_like 'authenticates sessionless user', :issues_calendar, :ics, public: true do
before do
default_params.merge!(id: group)
end
end
end
describe 'external authorization' do
before do
group.add_owner(user)
......
......@@ -162,27 +162,4 @@ RSpec.describe Projects::CommitsController do
end
end
end
context 'token authentication' do
context 'public project' do
it_behaves_like 'authenticates sessionless user', :show, :atom, { public: true, ignore_incrementing: true } do
before do
public_project = create(:project, :repository, :public)
default_params.merge!(namespace_id: public_project.namespace, project_id: public_project, id: "master.atom")
end
end
end
context 'private project' do
it_behaves_like 'authenticates sessionless user', :show, :atom, { public: false, ignore_incrementing: true } do
before do
private_project = create(:project, :repository, :private)
private_project.add_maintainer(user)
default_params.merge!(namespace_id: private_project.namespace, project_id: private_project, id: "master.atom")
end
end
end
end
end
......@@ -1948,40 +1948,4 @@ RSpec.describe Projects::IssuesController do
end
end
end
context 'private project with token authentication' do
let_it_be(:private_project) { create(:project, :private) }
it_behaves_like 'authenticates sessionless user', :index, :atom, ignore_incrementing: true do
before do
default_params.merge!(project_id: private_project, namespace_id: private_project.namespace)
private_project.add_maintainer(user)
end
end
it_behaves_like 'authenticates sessionless user', :calendar, :ics, ignore_incrementing: true do
before do
default_params.merge!(project_id: private_project, namespace_id: private_project.namespace)
private_project.add_maintainer(user)
end
end
end
context 'public project with token authentication' do
let_it_be(:public_project) { create(:project, :public) }
it_behaves_like 'authenticates sessionless user', :index, :atom, public: true do
before do
default_params.merge!(project_id: public_project, namespace_id: public_project.namespace)
end
end
it_behaves_like 'authenticates sessionless user', :calendar, :ics, public: true do
before do
default_params.merge!(project_id: public_project, namespace_id: public_project.namespace)
end
end
end
end
......@@ -128,6 +128,8 @@ RSpec.describe Projects::RawController do
let_it_be(:user) { create(:user, static_object_token: 'very-secure-token') }
let_it_be(:file_path) { 'master/README.md' }
let(:token) { user.static_object_token }
before do
project.add_developer(user)
end
......@@ -143,13 +145,36 @@ RSpec.describe Projects::RawController do
context 'when a token param is present' do
context 'when token is correct' do
let(:params) { { token: user.static_object_token } }
let(:params) { { token: token } }
it 'calls the action normally' do
get_show
expect(response).to have_gitlab_http_status(:ok)
end
context 'when user with expired password' do
let_it_be(:user) { create(:user, password_expires_at: 2.minutes.ago) }
it 'redirects to sign in page' do
get_show
expect(response).to have_gitlab_http_status(:found)
expect(response.location).to end_with('/users/sign_in')
end
end
context 'when password expiration is not applicable' do
context 'when ldap user' do
let_it_be(:user) { create(:omniauth_user, provider: 'ldap', password_expires_at: 2.minutes.ago) }
it 'calls the action normally' do
get_show
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end
context 'when token is incorrect' do
......@@ -165,18 +190,45 @@ RSpec.describe Projects::RawController do
end
context 'when a token header is present' do
before do
request.headers['X-Gitlab-Static-Object-Token'] = token
end
context 'when token is correct' do
it 'calls the action normally' do
request.headers['X-Gitlab-Static-Object-Token'] = user.static_object_token
get_show
expect(response).to have_gitlab_http_status(:ok)
end
context 'when user with expired password' do
let_it_be(:user) { create(:user, password_expires_at: 2.minutes.ago) }
it 'redirects to sign in page' do
get_show
expect(response).to have_gitlab_http_status(:found)
expect(response.location).to end_with('/users/sign_in')
end
end
context 'when password expiration is not applicable' do
context 'when ldap user' do
let_it_be(:user) { create(:omniauth_user, provider: 'ldap', password_expires_at: 2.minutes.ago) }
it 'calls the action normally' do
get_show
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end
context 'when token is incorrect' do
let(:token) { 'foobar' }
it 'redirects to sign in page' do
request.headers['X-Gitlab-Static-Object-Token'] = 'foobar'
get_show
expect(response).to have_gitlab_http_status(:found)
......
......@@ -178,6 +178,29 @@ RSpec.describe Projects::RepositoriesController do
expect(response).to have_gitlab_http_status(:ok)
end
context 'when user with expired password' do
let_it_be(:user) { create(:user, password_expires_at: 2.minutes.ago) }
it 'redirects to sign in page' do
get :archive, params: { namespace_id: project.namespace, project_id: project, id: 'master', token: user.static_object_token }, format: 'zip'
expect(response).to have_gitlab_http_status(:found)
expect(response.location).to end_with('/users/sign_in')
end
end
context 'when password expiration is not applicable' do
context 'when ldap user' do
let_it_be(:user) { create(:omniauth_user, provider: 'ldap', password_expires_at: 2.minutes.ago) }
it 'calls the action normally' do
get :archive, params: { namespace_id: project.namespace, project_id: project, id: 'master', token: user.static_object_token }, format: 'zip'
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end
context 'when token is incorrect' do
......@@ -197,6 +220,31 @@ RSpec.describe Projects::RepositoriesController do
expect(response).to have_gitlab_http_status(:ok)
end
context 'when user with expired password' do
let_it_be(:user) { create(:user, password_expires_at: 2.minutes.ago) }
it 'redirects to sign in page' do
request.headers['X-Gitlab-Static-Object-Token'] = user.static_object_token
get :archive, params: { namespace_id: project.namespace, project_id: project, id: 'master' }, format: 'zip'
expect(response).to have_gitlab_http_status(:found)
expect(response.location).to end_with('/users/sign_in')
end
end
context 'when password expiration is not applicable' do
context 'when ldap user' do
let_it_be(:user) { create(:omniauth_user, provider: 'ldap', password_expires_at: 2.minutes.ago) }
it 'calls the action normally' do
request.headers['X-Gitlab-Static-Object-Token'] = user.static_object_token
get :archive, params: { namespace_id: project.namespace, project_id: project, id: 'master' }, format: 'zip'
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end
context 'when token is incorrect' do
......
......@@ -117,28 +117,6 @@ RSpec.describe Projects::TagsController do
end
end
context 'private project with token authentication' do
let(:private_project) { create(:project, :repository, :private) }
it_behaves_like 'authenticates sessionless user', :index, :atom, ignore_incrementing: true do
before do
default_params.merge!(project_id: private_project, namespace_id: private_project.namespace)
private_project.add_maintainer(user)
end
end
end
context 'public project with token authentication' do
let(:public_project) { create(:project, :repository, :public) }
it_behaves_like 'authenticates sessionless user', :index, :atom, public: true do
before do
default_params.merge!(project_id: public_project, namespace_id: public_project.namespace)
end
end
end
describe 'POST #create' do
before do
project.add_developer(user)
......
......@@ -1568,28 +1568,6 @@ RSpec.describe ProjectsController do
end
end
context 'private project with token authentication' do
let_it_be(:private_project) { create(:project, :private) }
it_behaves_like 'authenticates sessionless user', :show, :atom, ignore_incrementing: true do
before do
default_params.merge!(id: private_project, namespace_id: private_project.namespace)
private_project.add_maintainer(user)
end
end
end
context 'public project with token authentication' do
let_it_be(:public_project) { create(:project, :public) }
it_behaves_like 'authenticates sessionless user', :show, :atom, public: true do
before do
default_params.merge!(id: public_project, namespace_id: public_project.namespace)
end
end
end
context 'GET show.atom' do
let_it_be(:public_project) { create(:project, :public) }
let_it_be(:event) { create(:event, :commented, project: public_project, target: create(:note, project: public_project)) }
......
......@@ -253,7 +253,7 @@ RSpec.describe 'GraphQL' do
end
context 'with token authentication' do
let(:token) { create(:personal_access_token) }
let(:token) { create(:personal_access_token, user: user) }
it 'authenticates users with a PAT' do
stub_authentication_activity_metrics(debug: false)
......@@ -276,6 +276,32 @@ RSpec.describe 'GraphQL' do
expect(graphql_errors).to include({ 'message' => /API not accessible/ })
end
context 'when user with expired password' do
let_it_be(:user) { create(:user, password_expires_at: 2.minutes.ago) }
it 'does not authenticate user' do
post_graphql(query, headers: { 'PRIVATE-TOKEN' => token.token })
expect(response).to have_gitlab_http_status(:ok)
expect(graphql_data['echo']).to eq('nil says: Hello world')
end
end
context 'when password expiration is not applicable' do
context 'when ldap user' do
let_it_be(:user) { create(:omniauth_user, provider: 'ldap', password_expires_at: 2.minutes.ago) }
it 'authenticates user' do
post_graphql(query, headers: { 'PRIVATE-TOKEN' => token.token })
expect(response).to have_gitlab_http_status(:ok)
expect(graphql_data['echo']).to eq("\"#{token.user.username}\" says: Hello world")
end
end
end
context 'when the personal access token has no api scope' do
it 'does not log the user in' do
token.update!(scopes: [:read_user])
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Dashboard::ProjectsController do
context 'token authentication' do
it_behaves_like 'authenticates sessionless user for the request spec', 'index atom', public_resource: false do
let(:url) { dashboard_projects_url(:atom) }
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe DashboardController do
context 'token authentication' do
it_behaves_like 'authenticates sessionless user for the request spec', 'issues atom', public_resource: false do
let(:url) { issues_dashboard_url(:atom, assignee_username: user.username) }
end
it_behaves_like 'authenticates sessionless user for the request spec', 'issues_calendar ics', public_resource: false do
let(:url) { issues_dashboard_url(:ics, assignee_username: user.username) }
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GroupsController do
context 'token authentication' do
context 'when public group' do
let_it_be(:public_group) { create(:group, :public) }
it_behaves_like 'authenticates sessionless user for the request spec', 'show atom', public_resource: true do
let(:url) { group_path(public_group, format: :atom) }
end
it_behaves_like 'authenticates sessionless user for the request spec', 'issues atom', public_resource: true do
let(:url) { issues_group_path(public_group, format: :atom) }
end
it_behaves_like 'authenticates sessionless user for the request spec', 'issues_calendar ics', public_resource: true do
let(:url) { issues_group_calendar_url(public_group, format: :ics) }
end
end
context 'when private project' do
let_it_be(:private_group) { create(:group, :private) }
it_behaves_like 'authenticates sessionless user for the request spec', 'show atom', public_resource: false, ignore_metrics: true do
let(:url) { group_path(private_group, format: :atom) }
before do
private_group.add_maintainer(user)
end
end
it_behaves_like 'authenticates sessionless user for the request spec', 'issues atom', public_resource: false, ignore_metrics: true do
let(:url) { issues_group_path(private_group, format: :atom) }
before do
private_group.add_maintainer(user)
end
end
it_behaves_like 'authenticates sessionless user for the request spec', 'issues_calendar ics', public_resource: false, ignore_metrics: true do
let(:url) { issues_group_calendar_url(private_group, format: :ics) }
before do
private_group.add_maintainer(user)
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::CommitsController do
context 'token authentication' do
context 'when public project' do
let_it_be(:public_project) { create(:project, :repository, :public) }
it_behaves_like 'authenticates sessionless user for the request spec', 'show atom', public_resource: true do
let(:url) { project_commits_url(public_project, public_project.default_branch, format: :atom) }
end
end
context 'when private project' do
let_it_be(:private_project) { create(:project, :repository, :private) }
it_behaves_like 'authenticates sessionless user for the request spec', 'show atom', public_resource: false, ignore_metrics: true do
let(:url) { project_commits_url(private_project, private_project.default_branch, format: :atom) }
before do
private_project.add_maintainer(user)
end
end
end
end
end
......@@ -8,11 +8,11 @@ RSpec.describe Projects::IssuesController do
let_it_be(:project) { issue.project }
let_it_be(:user) { issue.author }
before do
login_as(user)
end
describe 'GET #discussions' do
before do
login_as(user)
end
let_it_be(:discussion) { create(:discussion_note_on_issue, noteable: issue, project: issue.project) }
let_it_be(:discussion_reply) { create(:discussion_note_on_issue, noteable: issue, project: issue.project, in_reply_to: discussion) }
let_it_be(:state_event) { create(:resource_state_event, issue: issue) }
......@@ -68,4 +68,38 @@ RSpec.describe Projects::IssuesController do
end
end
end
context 'token authentication' do
context 'when public project' do
let_it_be(:public_project) { create(:project, :public) }
it_behaves_like 'authenticates sessionless user for the request spec', 'index atom', public_resource: true do
let(:url) { project_issues_url(public_project, format: :atom) }
end
it_behaves_like 'authenticates sessionless user for the request spec', 'calendar ics', public_resource: true do
let(:url) { project_issues_url(public_project, format: :ics) }
end
end
context 'when private project' do
let_it_be(:private_project) { create(:project, :private) }
it_behaves_like 'authenticates sessionless user for the request spec', 'index atom', public_resource: false, ignore_metrics: true do
let(:url) { project_issues_url(private_project, format: :atom) }
before do
private_project.add_maintainer(user)
end
end
it_behaves_like 'authenticates sessionless user for the request spec', 'calendar ics', public_resource: false, ignore_metrics: true do
let(:url) { project_issues_url(private_project, format: :ics) }
before do
private_project.add_maintainer(user)
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::MergeRequestsController do
context 'token authentication' do
context 'when public project' do
let_it_be(:public_project) { create(:project, :public) }
it_behaves_like 'authenticates sessionless user for the request spec', 'index atom', public_resource: true do
let(:url) { project_merge_requests_url(public_project, format: :atom) }
end
end
context 'when private project' do
let_it_be(:private_project) { create(:project, :private) }
it_behaves_like 'authenticates sessionless user for the request spec', 'index atom', public_resource: false, ignore_metrics: true do
let(:url) { project_merge_requests_url(private_project, format: :atom) }
before do
private_project.add_maintainer(user)
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::TagsController do
context 'token authentication' do
context 'when public project' do
let_it_be(:public_project) { create(:project, :repository, :public) }
it_behaves_like 'authenticates sessionless user for the request spec', 'index atom', public_resource: true do
let(:url) { project_tags_url(public_project, format: :atom) }
end
end
context 'when private project' do
let_it_be(:private_project) { create(:project, :repository, :private) }
it_behaves_like 'authenticates sessionless user for the request spec', 'index atom', public_resource: false, ignore_metrics: true do
let(:url) { project_tags_url(private_project, format: :atom) }
before do
private_project.add_maintainer(user)
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ProjectsController do
context 'token authentication' do
context 'when public project' do
let_it_be(:public_project) { create(:project, :public) }
it_behaves_like 'authenticates sessionless user for the request spec', 'show atom', public_resource: true do
let(:url) { project_url(public_project, format: :atom) }
end
end
context 'when private project' do
let_it_be(:private_project) { create(:project, :private) }
it_behaves_like 'authenticates sessionless user for the request spec', 'show atom', public_resource: false, ignore_metrics: true do
let(:url) { project_url(private_project, format: :atom) }
before do
private_project.add_maintainer(user)
end
end
end
end
end
......@@ -805,9 +805,9 @@ RSpec.describe UsersController do
end
context 'token authentication' do
let(:url) { user_url(user.username, format: :atom) }
it_behaves_like 'authenticates sessionless user for the request spec', public: true
it_behaves_like 'authenticates sessionless user for the request spec', 'show atom', public_resource: true do
let(:url) { user_url(user, format: :atom) }
end
end
def user_moved_message(redirect_route, user)
......
# frozen_string_literal: true
# This controller shared examples will be migrated to
# spec/support/shared_examples/requests/sessionless_auth_request_shared_examples.rb
# See also https://gitlab.com/groups/gitlab-org/-/epics/5076
RSpec.shared_examples 'authenticates sessionless user' do |path, format, params|
params ||= {}
before do
stub_authentication_activity_metrics(debug: false)
end
let(:user) { create(:user) }
let(:personal_access_token) { create(:personal_access_token, user: user) }
let(:default_params) { { format: format }.merge(params.except(:public) || {}) }
context "when the 'personal_access_token' param is populated with the personal access token" do
it 'logs the user in' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
.and increment(:user_session_override_counter)
.and increment(:user_sessionless_authentication_counter)
get path, params: default_params.merge(private_token: personal_access_token.token)
expect(response).to have_gitlab_http_status(:ok)
expect(controller.current_user).to eq(user)
end
it 'does not log the user in if page is public', if: params[:public] do
get path, params: default_params
expect(response).to have_gitlab_http_status(:ok)
expect(controller.current_user).to be_nil
end
end
context 'when the personal access token has no api scope', unless: params[:public] do
it 'does not log the user in' do
# Several instances of where these specs are shared route the request
# through ApplicationController#route_not_found which does not involve
# the usual auth code from Devise, so does not increment the
# :user_unauthenticated_counter
#
unless params[:ignore_incrementing]
expect(authentication_metrics)
.to increment(:user_unauthenticated_counter)
end
personal_access_token.update!(scopes: [:read_user])
get path, params: default_params.merge(private_token: personal_access_token.token)
expect(response).not_to have_gitlab_http_status(:ok)
end
end
context "when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do
it 'logs the user in' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
.and increment(:user_session_override_counter)
.and increment(:user_sessionless_authentication_counter)
@request.headers['PRIVATE-TOKEN'] = personal_access_token.token
get path, params: default_params
expect(response).to have_gitlab_http_status(:ok)
end
end
context "when the 'feed_token' param is populated with the feed token", if: format == :rss do
it "logs the user in" do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
.and increment(:user_session_override_counter)
.and increment(:user_sessionless_authentication_counter)
get path, params: default_params.merge(feed_token: user.feed_token)
expect(response).to have_gitlab_http_status(:ok)
end
end
context "when the 'feed_token' param is populated with an invalid feed token", if: format == :rss, unless: params[:public] do
it "logs the user" do
expect(authentication_metrics)
.to increment(:user_unauthenticated_counter)
get path, params: default_params.merge(feed_token: 'token')
expect(response).not_to have_gitlab_http_status(:ok)
end
end
it "doesn't log the user in otherwise", unless: params[:public] do
# Several instances of where these specs are shared route the request
# through ApplicationController#route_not_found which does not involve
# the usual auth code from Devise, so does not increment the
# :user_unauthenticated_counter
#
unless params[:ignore_incrementing]
expect(authentication_metrics)
.to increment(:user_unauthenticated_counter)
end
get path, params: default_params.merge(private_token: 'token')
expect(response).not_to have_gitlab_http_status(:ok)
end
end
# frozen_string_literal: true
RSpec.shared_examples 'authenticates sessionless user for the request spec' do |params|
params ||= {}
RSpec.shared_examples 'authenticates sessionless user for the request spec' do |name, public_resource:, ignore_metrics: false, params: {}|
before do
stub_authentication_activity_metrics(debug: false)
end
let(:user) { create(:user) }
let_it_be(:user) { create(:user) }
let(:personal_access_token) { create(:personal_access_token, user: user) }
let(:default_params) { params.except(:public) || {} }
context "when the 'personal_access_token' param is populated with the personal access token" do
it 'logs the user in' do
shared_examples 'authenticates user and returns response with ok status' do
it 'authenticates user and returns response with ok status' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
.and increment(:user_session_override_counter)
.and increment(:user_sessionless_authentication_counter)
.and increment(:user_session_override_counter)
.and increment(:user_sessionless_authentication_counter)
get url, params: default_params.merge(private_token: personal_access_token.token)
subject
expect(response).to have_gitlab_http_status(:ok)
expect(controller.current_user).to eq(user)
expect(response).to have_gitlab_http_status(:ok)
end
end
it 'does not log the user in if page is public', if: params[:public] do
get url, params: default_params
shared_examples 'does not authenticate user and returns response with ok status' do
it 'does not authenticate user and returns response with ok status' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(controller.current_user).to be_nil
expect(response).to have_gitlab_http_status(:ok)
end
end
context 'when the personal access token has no api scope', unless: params[:public] do
it 'does not log the user in' do
shared_examples 'does not return response with ok status' do
it 'does not return response with ok status' do
# Several instances of where these specs are shared route the request
# through ApplicationController#route_not_found which does not involve
# the usual auth code from Devise, so does not increment the
# :user_unauthenticated_counter
#
unless params[:ignore_incrementing]
unless ignore_metrics
expect(authentication_metrics)
.to increment(:user_unauthenticated_counter)
end
personal_access_token.update!(scopes: [:read_user])
get url, params: default_params.merge(private_token: personal_access_token.token)
subject
expect(response).not_to have_gitlab_http_status(:ok)
end
end
context "when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do
it 'logs the user in' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
.and increment(:user_session_override_counter)
.and increment(:user_sessionless_authentication_counter)
shared_examples 'using valid token' do
context 'when resource is private', unless: public_resource do
include_examples 'authenticates user and returns response with ok status'
headers = { 'PRIVATE-TOKEN': personal_access_token.token }
get url, params: default_params, headers: headers
context 'when user with expired password' do
let_it_be(:user) { create(:user, password_expires_at: 2.minutes.ago) }
expect(response).to have_gitlab_http_status(:ok)
include_examples 'does not return response with ok status'
end
context 'when password expiration is not applicable' do
context 'when ldap user' do
let_it_be(:user) { create(:omniauth_user, provider: 'ldap', password_expires_at: 2.minutes.ago) }
include_examples 'authenticates user and returns response with ok status'
end
end
end
context 'when resource is public', if: public_resource do
include_examples 'authenticates user and returns response with ok status'
context 'when user with expired password' do
let_it_be(:user) { create(:user, password_expires_at: 2.minutes.ago) }
include_examples 'does not authenticate user and returns response with ok status'
end
end
end
it "doesn't log the user in otherwise", unless: params[:public] do
# Several instances of where these specs are shared route the request
# through ApplicationController#route_not_found which does not involve
# the usual auth code from Devise, so does not increment the
# :user_unauthenticated_counter
#
unless params[:ignore_incrementing]
expect(authentication_metrics)
.to increment(:user_unauthenticated_counter)
shared_examples 'using invalid token' do
context 'when resource is private', unless: public_resource do
include_examples 'does not return response with ok status'
end
context 'when resource is public', if: public_resource do
include_examples 'does not authenticate user and returns response with ok status'
end
end
shared_examples 'personal access token has no api scope' do
context 'when the personal access token has no api scope' do
before do
personal_access_token.update!(scopes: [:read_user])
end
context 'when resource is private', unless: public_resource do
include_examples 'does not return response with ok status'
end
context 'when resource is public', if: public_resource do
include_examples 'does not authenticate user and returns response with ok status'
end
end
end
describe name do
context "when the 'private_token' param is populated with the personal access token" do
context 'when valid token' do
subject { get url, params: params.merge(private_token: personal_access_token.token) }
include_examples 'using valid token'
include_examples 'personal access token has no api scope'
end
context 'when invalid token' do
subject { get url, params: params.merge(private_token: 'invalid token') }
include_examples 'using invalid token'
end
end
get url, params: default_params.merge(private_token: 'token')
context "when the 'PRIVATE-TOKEN' header is populated with the personal access token" do
context 'when valid token' do
subject do
headers = { 'PRIVATE-TOKEN': personal_access_token.token }
get url, params: params, headers: headers
end
expect(response).not_to have_gitlab_http_status(:ok)
include_examples 'using valid token'
include_examples 'personal access token has no api scope'
end
context 'when invalid token' do
subject do
headers = { 'PRIVATE-TOKEN': 'invalid token' }
get url, params: params, headers: headers
end
include_examples 'using invalid token'
end
end
context "when the 'feed_token' param is populated with the feed token" do
context 'when valid token' do
subject { get url, params: params.merge(feed_token: user.feed_token) }
include_examples 'using valid token'
end
context 'when invalid token' do
subject { get url, params: params.merge(feed_token: 'invalid token') }
include_examples 'using invalid token'
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment