1# frozen_string_literal: true 2 3require "spec_helper" 4 5RSpec.describe AuthHelper do 6 describe "button_based_providers" do 7 it 'returns all enabled providers from devise' do 8 allow(helper).to receive(:auth_providers) { [:twitter, :github] } 9 expect(helper.button_based_providers).to include(*[:twitter, :github]) 10 end 11 12 it 'does not return ldap provider' do 13 allow(helper).to receive(:auth_providers) { [:twitter, :ldapmain] } 14 expect(helper.button_based_providers).to include(:twitter) 15 end 16 17 it 'returns empty array' do 18 allow(helper).to receive(:auth_providers) { [] } 19 expect(helper.button_based_providers).to eq([]) 20 end 21 end 22 23 describe "providers_for_base_controller" do 24 it 'returns all enabled providers from devise' do 25 allow(helper).to receive(:auth_providers) { [:twitter, :github] } 26 expect(helper.providers_for_base_controller).to include(*[:twitter, :github]) 27 end 28 29 it 'excludes ldap providers' do 30 allow(helper).to receive(:auth_providers) { [:twitter, :ldapmain] } 31 expect(helper.providers_for_base_controller).not_to include(:ldapmain) 32 end 33 end 34 35 describe "form_based_providers" do 36 it 'includes LDAP providers' do 37 allow(helper).to receive(:auth_providers) { [:twitter, :ldapmain] } 38 expect(helper.form_based_providers).to eq %i(ldapmain) 39 end 40 41 it 'includes crowd provider' do 42 allow(helper).to receive(:auth_providers) { [:twitter, :crowd] } 43 expect(helper.form_based_providers).to eq %i(crowd) 44 end 45 end 46 47 describe 'form_based_auth_provider_has_active_class?' do 48 it 'selects main LDAP server' do 49 allow(helper).to receive(:auth_providers) { [:twitter, :ldapprimary, :ldapsecondary, :kerberos] } 50 expect(helper.form_based_auth_provider_has_active_class?(:twitter)).to be(false) 51 expect(helper.form_based_auth_provider_has_active_class?(:ldapprimary)).to be(true) 52 expect(helper.form_based_auth_provider_has_active_class?(:ldapsecondary)).to be(false) 53 expect(helper.form_based_auth_provider_has_active_class?(:kerberos)).to be(false) 54 end 55 end 56 57 describe 'any_form_based_providers_enabled?' do 58 before do 59 allow(Gitlab::Auth::Ldap::Config).to receive(:enabled?).and_return(true) 60 end 61 62 it 'detects form-based providers' do 63 allow(helper).to receive(:auth_providers) { [:twitter, :ldapmain] } 64 expect(helper.any_form_based_providers_enabled?).to be(true) 65 end 66 67 it 'ignores ldap providers when ldap web sign in is disabled' do 68 allow(helper).to receive(:auth_providers) { [:twitter, :ldapmain] } 69 allow(helper).to receive(:ldap_sign_in_enabled?).and_return(false) 70 expect(helper.any_form_based_providers_enabled?).to be(false) 71 end 72 end 73 74 describe 'enabled_button_based_providers' do 75 before do 76 allow(helper).to receive(:auth_providers) { [:twitter, :github, :google_oauth2, :openid_connect] } 77 end 78 79 context 'all providers are enabled to sign in' do 80 it 'returns all the enabled providers from settings in expected order' do 81 expect(helper.enabled_button_based_providers).to match(%w[google_oauth2 github twitter openid_connect]) 82 end 83 84 it 'puts google and github in the beginning' do 85 expect(helper.enabled_button_based_providers.first).to eq('google_oauth2') 86 expect(helper.enabled_button_based_providers.second).to eq('github') 87 end 88 end 89 90 context 'GitHub OAuth sign in is disabled from application setting' do 91 it "doesn't return github as provider" do 92 stub_application_setting( 93 disabled_oauth_sign_in_sources: ['github'] 94 ) 95 96 expect(helper.enabled_button_based_providers).to include('twitter') 97 expect(helper.enabled_button_based_providers).not_to include('github') 98 end 99 end 100 end 101 102 describe 'popular_enabled_button_based_providers' do 103 it 'returns the intersection set of popular & enabled providers', :aggregate_failures do 104 allow(helper).to receive(:enabled_button_based_providers) { %w(twitter github google_oauth2) } 105 106 expect(helper.popular_enabled_button_based_providers).to eq(%w(github google_oauth2)) 107 108 allow(helper).to receive(:enabled_button_based_providers) { %w(google_oauth2 bitbucket) } 109 110 expect(helper.popular_enabled_button_based_providers).to eq(%w(google_oauth2)) 111 112 allow(helper).to receive(:enabled_button_based_providers) { %w(bitbucket) } 113 114 expect(helper.popular_enabled_button_based_providers).to be_empty 115 end 116 end 117 118 describe 'button_based_providers_enabled?' do 119 before do 120 allow(helper).to receive(:auth_providers) { [:twitter, :github] } 121 end 122 123 context 'button based providers enabled' do 124 it 'returns true' do 125 expect(helper.button_based_providers_enabled?).to be true 126 end 127 end 128 129 context 'all the button based providers are disabled via application_setting' do 130 it 'returns false' do 131 stub_application_setting( 132 disabled_oauth_sign_in_sources: %w(github twitter) 133 ) 134 135 expect(helper.button_based_providers_enabled?).to be false 136 end 137 end 138 end 139 140 describe '#link_provider_allowed?' do 141 let(:policy) { instance_double('IdentityProviderPolicy') } 142 let(:current_user) { instance_double('User') } 143 let(:provider) { double } 144 145 before do 146 allow(helper).to receive(:current_user).and_return(current_user) 147 allow(IdentityProviderPolicy).to receive(:new).with(current_user, provider).and_return(policy) 148 end 149 150 it 'delegates to identity provider policy' do 151 allow(policy).to receive(:can?).with(:link).and_return('policy_link_result') 152 153 expect(helper.link_provider_allowed?(provider)).to eq 'policy_link_result' 154 end 155 end 156 157 describe '#unlink_provider_allowed?' do 158 let(:policy) { instance_double('IdentityProviderPolicy') } 159 let(:current_user) { instance_double('User') } 160 let(:provider) { double } 161 162 before do 163 allow(helper).to receive(:current_user).and_return(current_user) 164 allow(IdentityProviderPolicy).to receive(:new).with(current_user, provider).and_return(policy) 165 end 166 167 it 'delegates to identity provider policy' do 168 allow(policy).to receive(:can?).with(:unlink).and_return('policy_unlink_result') 169 170 expect(helper.unlink_provider_allowed?(provider)).to eq 'policy_unlink_result' 171 end 172 end 173 174 describe '#provider_has_icon?' do 175 it 'returns true for defined providers' do 176 expect(helper.provider_has_icon?(described_class::PROVIDERS_WITH_ICONS.sample)).to eq true 177 end 178 179 it 'returns false for undefined providers' do 180 expect(helper.provider_has_icon?('test')).to be_falsey 181 end 182 183 context 'when provider is defined by config' do 184 before do 185 allow(Gitlab::Auth::OAuth::Provider).to receive(:icon_for).with('test').and_return('icon') 186 end 187 188 it 'returns true' do 189 expect(helper.provider_has_icon?('test')).to be_truthy 190 end 191 end 192 193 context 'when provider is not defined by config' do 194 before do 195 allow(Gitlab::Auth::OAuth::Provider).to receive(:icon_for).with('test').and_return(nil) 196 end 197 198 it 'returns true' do 199 expect(helper.provider_has_icon?('test')).to be_falsey 200 end 201 end 202 end 203 204 describe '#allow_admin_mode_password_authentication_for_web?' do 205 let(:user) { create(:user) } 206 207 subject { helper.allow_admin_mode_password_authentication_for_web? } 208 209 before do 210 allow(helper).to receive(:current_user).and_return(user) 211 end 212 213 it { is_expected.to be(true) } 214 215 context 'when password authentication for web is disabled' do 216 before do 217 stub_application_setting(password_authentication_enabled_for_web: false) 218 end 219 220 it { is_expected.to be(false) } 221 end 222 223 context 'when current_user is an ldap user' do 224 before do 225 allow(user).to receive(:ldap_user?).and_return(true) 226 end 227 228 it { is_expected.to be(false) } 229 end 230 231 context 'when user got password automatically set' do 232 before do 233 user.update_attribute(:password_automatically_set, true) 234 end 235 236 it { is_expected.to be(false) } 237 end 238 end 239 240 describe '#auth_active?' do 241 let(:user) { create(:user) } 242 243 def auth_active? 244 helper.auth_active?(provider) 245 end 246 247 before do 248 allow(helper).to receive(:current_user).and_return(user) 249 end 250 251 context 'for atlassian_oauth2 provider' do 252 let_it_be(:provider) { :atlassian_oauth2 } 253 254 it 'returns true when present' do 255 create(:atlassian_identity, user: user) 256 257 expect(auth_active?).to be true 258 end 259 260 it 'returns false when not present' do 261 expect(auth_active?).to be false 262 end 263 end 264 265 context 'for other omniauth providers' do 266 let_it_be(:provider) { 'google_oauth2' } 267 268 it 'returns true when present' do 269 create(:identity, provider: provider, user: user) 270 271 expect(auth_active?).to be true 272 end 273 274 it 'returns false when not present' do 275 expect(auth_active?).to be false 276 end 277 end 278 end 279 280 describe '#google_tag_manager_enabled?' do 281 let(:is_gitlab_com) { true } 282 let(:user) { nil } 283 284 before do 285 allow(Gitlab).to receive(:com?).and_return(is_gitlab_com) 286 allow(helper).to receive(:current_user).and_return(user) 287 end 288 289 subject(:google_tag_manager_enabled) { helper.google_tag_manager_enabled? } 290 291 context 'when not on gitlab.com' do 292 let(:is_gitlab_com) { false } 293 294 it { is_expected.to eq(false) } 295 end 296 297 context 'regular and nonce versions' do 298 using RSpec::Parameterized::TableSyntax 299 300 where(:gtm_nonce_enabled, :gtm_key) do 301 false | 'google_tag_manager_id' 302 true | 'google_tag_manager_nonce_id' 303 end 304 305 with_them do 306 before do 307 stub_feature_flags(gtm_nonce: gtm_nonce_enabled) 308 stub_config(extra: { gtm_key => 'key' }) 309 end 310 311 context 'on gitlab.com and a key set without a current user' do 312 it { is_expected.to be_truthy } 313 end 314 315 context 'when current user is set' do 316 let(:user) { instance_double('User') } 317 318 it { is_expected.to eq(false) } 319 end 320 321 context 'when no key is set' do 322 before do 323 stub_config(extra: {}) 324 end 325 326 it { is_expected.to eq(false) } 327 end 328 end 329 end 330 end 331 332 describe '#google_tag_manager_id' do 333 subject(:google_tag_manager_id) { helper.google_tag_manager_id } 334 335 before do 336 stub_config(extra: { 'google_tag_manager_nonce_id': 'nonce', 'google_tag_manager_id': 'gtm' }) 337 end 338 339 context 'when google tag manager is disabled' do 340 before do 341 allow(helper).to receive(:google_tag_manager_enabled?).and_return(false) 342 end 343 344 it { is_expected.to be_falsey } 345 end 346 347 context 'when google tag manager is enabled' do 348 before do 349 allow(helper).to receive(:google_tag_manager_enabled?).and_return(true) 350 end 351 352 context 'when nonce feature flag is enabled' do 353 it { is_expected.to eq('nonce') } 354 end 355 356 context 'when nonce feature flag is disabled' do 357 before do 358 stub_feature_flags(gtm_nonce: false) 359 end 360 361 it { is_expected.to eq('gtm') } 362 end 363 end 364 end 365 366 describe '#auth_app_owner_text' do 367 shared_examples 'generates text with the correct info' do 368 it 'includes the name of the application owner' do 369 auth_app_owner_text = helper.auth_app_owner_text(owner) 370 371 expect(auth_app_owner_text).to include(owner.name) 372 expect(auth_app_owner_text).to include(path_to_owner) 373 end 374 end 375 376 context 'when owner is a user' do 377 let_it_be(:owner) { create(:user) } 378 379 let(:path_to_owner) { user_path(owner) } 380 381 it_behaves_like 'generates text with the correct info' 382 end 383 384 context 'when owner is a group' do 385 let_it_be(:owner) { create(:group) } 386 387 let(:path_to_owner) { user_path(owner) } 388 389 it_behaves_like 'generates text with the correct info' 390 end 391 392 context 'when the user is missing' do 393 it 'returns nil' do 394 expect(helper.auth_app_owner_text(nil)).to be(nil) 395 end 396 end 397 end 398 399 describe '#auth_strategy_class' do 400 subject(:auth_strategy_class) { helper.auth_strategy_class(name) } 401 402 context 'when configuration specifies no provider' do 403 let(:name) { 'does_not_exist' } 404 405 before do 406 allow(Gitlab.config.omniauth).to receive(:providers).and_return([]) 407 end 408 409 it 'returns false' do 410 expect(auth_strategy_class).to be_falsey 411 end 412 end 413 414 context 'when configuration specifies a provider with args but without strategy_class' do 415 let(:name) { 'google_oauth2' } 416 let(:provider) do 417 Struct.new(:name, :args).new( 418 name, 419 'app_id' => 'YOUR_APP_ID' 420 ) 421 end 422 423 before do 424 allow(Gitlab.config.omniauth).to receive(:providers).and_return([provider]) 425 end 426 427 it 'returns false' do 428 expect(auth_strategy_class).to be_falsey 429 end 430 end 431 432 context 'when configuration specifies a provider with args and strategy_class' do 433 let(:name) { 'provider1' } 434 let(:strategy) { 'OmniAuth::Strategies::LDAP' } 435 let(:provider) do 436 Struct.new(:name, :args).new( 437 name, 438 'strategy_class' => strategy 439 ) 440 end 441 442 before do 443 allow(Gitlab.config.omniauth).to receive(:providers).and_return([provider]) 444 end 445 446 it 'returns the class' do 447 expect(auth_strategy_class).to eq(strategy) 448 end 449 end 450 451 context 'when configuration specifies another provider with args and another strategy_class' do 452 let(:name) { 'provider1' } 453 let(:strategy) { 'OmniAuth::Strategies::LDAP' } 454 let(:provider) do 455 Struct.new(:name, :args).new( 456 'another_name', 457 'strategy_class' => strategy 458 ) 459 end 460 461 before do 462 allow(Gitlab.config.omniauth).to receive(:providers).and_return([provider]) 463 end 464 465 it 'returns false' do 466 expect(auth_strategy_class).to be_falsey 467 end 468 end 469 end 470 471 describe '#saml_providers' do 472 subject(:saml_providers) { helper.saml_providers } 473 474 let(:saml_strategy) { 'OmniAuth::Strategies::SAML' } 475 476 let(:saml_provider_1_name) { 'saml_provider_1' } 477 let(:saml_provider_1) do 478 Struct.new(:name, :args).new( 479 saml_provider_1_name, 480 'strategy_class' => saml_strategy 481 ) 482 end 483 484 let(:saml_provider_2_name) { 'saml_provider_2' } 485 let(:saml_provider_2) do 486 Struct.new(:name, :args).new( 487 saml_provider_2_name, 488 'strategy_class' => saml_strategy 489 ) 490 end 491 492 let(:ldap_provider_name) { 'ldap_provider' } 493 let(:ldap_strategy) { 'OmniAuth::Strategies::LDAP' } 494 let(:ldap_provider) do 495 Struct.new(:name, :args).new( 496 ldap_provider_name, 497 'strategy_class' => ldap_strategy 498 ) 499 end 500 501 let(:google_oauth2_provider_name) { 'google_oauth2' } 502 let(:google_oauth2_provider) do 503 Struct.new(:name, :args).new( 504 google_oauth2_provider_name, 505 'app_id' => 'YOUR_APP_ID' 506 ) 507 end 508 509 context 'when configuration specifies no provider' do 510 before do 511 allow(Devise).to receive(:omniauth_providers).and_return([]) 512 allow(Gitlab.config.omniauth).to receive(:providers).and_return([]) 513 end 514 515 it 'returns an empty list' do 516 expect(saml_providers).to be_empty 517 end 518 end 519 520 context 'when configuration specifies a provider with a SAML strategy_class' do 521 before do 522 allow(Devise).to receive(:omniauth_providers).and_return([saml_provider_1_name]) 523 allow(Gitlab.config.omniauth).to receive(:providers).and_return([saml_provider_1]) 524 end 525 526 it 'returns the provider' do 527 expect(saml_providers).to match_array([saml_provider_1_name]) 528 end 529 end 530 531 context 'when configuration specifies two providers with a SAML strategy_class' do 532 before do 533 allow(Devise).to receive(:omniauth_providers).and_return([saml_provider_1_name, saml_provider_2_name]) 534 allow(Gitlab.config.omniauth).to receive(:providers).and_return([saml_provider_1, saml_provider_2]) 535 end 536 537 it 'returns the provider' do 538 expect(saml_providers).to match_array([saml_provider_1_name, saml_provider_2_name]) 539 end 540 end 541 542 context 'when configuration specifies a provider with a non-SAML strategy_class' do 543 before do 544 allow(Devise).to receive(:omniauth_providers).and_return([ldap_provider_name]) 545 allow(Gitlab.config.omniauth).to receive(:providers).and_return([ldap_provider]) 546 end 547 548 it 'returns an empty list' do 549 expect(saml_providers).to be_empty 550 end 551 end 552 553 context 'when configuration specifies four providers but only two with SAML strategy_class' do 554 before do 555 allow(Devise).to receive(:omniauth_providers).and_return([saml_provider_1_name, ldap_provider_name, saml_provider_2_name, google_oauth2_provider_name]) 556 allow(Gitlab.config.omniauth).to receive(:providers).and_return([saml_provider_1, ldap_provider, saml_provider_2, google_oauth2_provider]) 557 end 558 559 it 'returns the provider' do 560 expect(saml_providers).to match_array([saml_provider_1_name, saml_provider_2_name]) 561 end 562 end 563 end 564end 565