require 'spec_helper' describe Oauth::GeoAuthController do let(:user) { create(:user) } let(:node) { create(:geo_node) } let(:oauth_app) { node.oauth_application } let(:access_token) { create(:doorkeeper_access_token, resource_owner_id: user.id, application: oauth_app) } let(:oauth_session) { Gitlab::Geo::OauthSession.new(access_token: access_token.token, return_to: projects_url) } let(:auth_state) { oauth_session.generate_oauth_state } let(:primary_node_url) { 'http://localhost:3001/' } before do allow_any_instance_of(Gitlab::Geo::OauthSession).to receive(:oauth_app) { oauth_app } allow_any_instance_of(Gitlab::Geo::OauthSession).to receive(:primary_node_url) { primary_node_url } end describe 'GET auth' do let(:primary_node_oauth_endpoint) { Gitlab::Geo::OauthSession.new.authorize_url(redirect_uri: oauth_geo_callback_url, state: auth_state) } it 'redirects to root_url when state is invalid' do allow_any_instance_of(Gitlab::Geo::OauthSession).to receive(:oauth_state_valid?) { false } get :auth, state: auth_state expect(response).to redirect_to(root_url) end it "redirects to primary node's oauth endpoint" do get :auth, state: auth_state expect(response).to redirect_to(primary_node_oauth_endpoint) end end describe 'GET callback' do let(:oauth_session) { Gitlab::Geo::OauthSession.new(access_token: access_token.token, return_to: projects_url) } let(:callback_state) { oauth_session.generate_oauth_state } let(:primary_node_oauth_endpoint) { Gitlab::Geo::OauthSession.new.authorize_url(redirect_uri: oauth_geo_callback_url, state: callback_state) } context 'redirection' do before do allow_any_instance_of(Gitlab::Geo::OauthSession).to receive(:get_token) { 'token' } allow_any_instance_of(Gitlab::Geo::OauthSession).to receive(:authenticate_with_gitlab) { user.attributes } end it 'redirects to login screen if state is invalid' do allow_any_instance_of(Gitlab::Geo::OauthSession).to receive(:oauth_state_valid?) { false } get :callback, state: callback_state expect(response).to redirect_to(new_user_session_path) end it 'redirects to redirect_url if state is valid' do get :callback, state: callback_state expect(response).to redirect_to(projects_url) end it 'does not display a flash message if state is valid' do get :callback, state: callback_state expect(controller).to set_flash[:alert].to(nil) end end context 'invalid credentials' do let(:fake_response) { double('Faraday::Response', headers: {}, body: '', status: 403) } let(:oauth_error) { OAuth2::Error.new(OAuth2::Response.new(fake_response)) } before do expect_any_instance_of(Gitlab::Geo::OauthSession).to receive(:get_token) { access_token.token } expect_any_instance_of(Gitlab::Geo::OauthSession).to receive(:authenticate_with_gitlab).and_raise(oauth_error) end it 'handles invalid credentials error' do get :callback, state: callback_state expect(response).to redirect_to(primary_node_oauth_endpoint) end end context 'inexistent local user' do render_views before do expect_any_instance_of(Gitlab::Geo::OauthSession).to receive(:get_token) { 'token' } expect_any_instance_of(Gitlab::Geo::OauthSession).to receive(:authenticate_with_gitlab) { User.new(id: 999999) } end it 'handles inexistent local user error' do get :callback, state: callback_state expect(response.code).to eq '200' expect(response.body).to include('Your account may have been deleted') end end end describe 'GET logout' do let(:oauth_session) { Gitlab::Geo::OauthSession.new(access_token: access_token.token) } let(:logout_state) { oauth_session.generate_logout_state } render_views before do sign_in(user) end context 'when access_token is valid' do it 'logs out and redirects to the root_url' do get :logout, state: logout_state expect(response).to redirect_to root_url end end context 'when access_token is invalid' do it 'handles access token problems' do allow_any_instance_of(Oauth2::LogoutTokenValidationService).to receive(:execute) { { status: :error, message: :expired } } get :logout, state: logout_state expect(response.body).to include("There is a problem with the OAuth access_token: expired") end end end end