Skip to content

Commit 308b152

Browse files
Merge pull request opf#18402 from opf/deindent-specs
Deindent OIDC authentication request specs
2 parents e0bd03f + fb82c3c commit 308b152

File tree

1 file changed

+60
-86
lines changed

1 file changed

+60
-86
lines changed

spec/requests/api/v3/authentication_spec.rb

+60-86
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,11 @@ def set_basic_auth_header(user, password)
416416
let(:token_aud) { ["https://openproject.local", "master-realm", "account"] }
417417
let(:token_issuer) { "https://keycloak.local/realms/master" }
418418
let(:expected_message) { "You did not provide the correct credentials." }
419-
let(:keys_request_stub) { nil }
419+
let(:keys_request_stub) do
420+
stub_request(:get, "https://keycloak.local/realms/master/protocol/openid-connect/certs")
421+
.to_return(status: 200, body: JWT::JWK::Set.new(jwk_response).export.to_json, headers: {})
422+
end
423+
let(:jwk_response) { jwk }
420424

421425
before do
422426
create(:oidc_provider, slug: "keycloak")
@@ -426,10 +430,17 @@ def set_basic_auth_header(user, password)
426430
header "Authorization", "Bearer #{token}"
427431
end
428432

433+
it "succeeds" do
434+
get resource
435+
436+
expect(last_response).to have_http_status :ok
437+
expect(last_response.header["WWW-Authenticate"]).to be_blank
438+
end
439+
429440
context "when token is issued by provider not configured in OP" do
430441
let(:token_issuer) { "https://eve.example.com" }
431442

432-
it do
443+
it "fails with HTTP 401 Unauthorized" do
433444
get resource
434445
expect(last_response).to have_http_status :unauthorized
435446
expect(last_response.header["WWW-Authenticate"])
@@ -438,103 +449,66 @@ def set_basic_auth_header(user, password)
438449
end
439450
end
440451

441-
context "when token is issued by provider configured in OP" do
442-
context "when token signature algorithm is not supported" do
443-
let(:token) { JWT.encode(payload, "secret", "HS256", { kid: "97AmyvoS8BFFRfm585GPgA16G1H2V22EdxxuAYUuoKk" }) }
444-
445-
it do
446-
get resource
447-
expect(last_response).to have_http_status :unauthorized
448-
error = "Token signature algorithm HS256 is not supported"
449-
expect(last_response.header["WWW-Authenticate"])
450-
.to eq(%{Bearer realm="OpenProject API", error="invalid_token", error_description="#{error}"})
451-
expect(JSON.parse(last_response.body)).to eq(error_response_body)
452-
end
453-
end
452+
context "when token signature algorithm is not supported" do
453+
let(:token) { JWT.encode(payload, "secret", "HS256", { kid: "97AmyvoS8BFFRfm585GPgA16G1H2V22EdxxuAYUuoKk" }) }
454454

455-
context "when kid is present" do
456-
let(:keys_request_stub) do
457-
stub_request(:get, "https://keycloak.local/realms/master/protocol/openid-connect/certs")
458-
.with(
459-
headers: {
460-
"Accept" => "*/*",
461-
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
462-
"User-Agent" => /JSON::JWK::Set::Fetcher \d+\.\d+\.\d+/
463-
}
464-
)
465-
.to_return(status: 200, body: JWT::JWK::Set.new(jwk).export.to_json, headers: {})
466-
end
467-
468-
context "when access token has not expired yet" do
469-
context "when aud does not contain client_id" do
470-
let(:token_aud) { ["Lisa", "Bart"] }
471-
472-
it do
473-
get resource
455+
it "fails with HTTP 401 Unauthorized" do
456+
get resource
457+
expect(last_response).to have_http_status :unauthorized
458+
error = "Token signature algorithm HS256 is not supported"
459+
expect(last_response.header["WWW-Authenticate"])
460+
.to eq(%{Bearer realm="OpenProject API", error="invalid_token", error_description="#{error}"})
461+
expect(JSON.parse(last_response.body)).to eq(error_response_body)
462+
end
463+
end
474464

475-
expect(last_response).to have_http_status :unauthorized
476-
error = 'Invalid audience. Expected https://openproject.local, received ["Lisa", "Bart"]'
477-
expect(last_response.header["WWW-Authenticate"])
478-
.to eq(%{Bearer realm="OpenProject API", error="invalid_token", error_description="#{error}"})
479-
expect(JSON.parse(last_response.body)).to eq(error_response_body)
480-
end
481-
end
465+
context "when aud does not contain client_id" do
466+
let(:token_aud) { ["Lisa", "Bart"] }
482467

483-
context "when aud contains client_id" do
484-
it do
485-
get resource
468+
it "fails with HTTP 401 Unauthorized" do
469+
get resource
486470

487-
expect(last_response).to have_http_status :ok
488-
end
489-
end
490-
end
471+
expect(last_response).to have_http_status :unauthorized
472+
error = 'Invalid audience. Expected https://openproject.local, received ["Lisa", "Bart"]'
473+
expect(last_response.header["WWW-Authenticate"])
474+
.to eq(%{Bearer realm="OpenProject API", error="invalid_token", error_description="#{error}"})
475+
expect(JSON.parse(last_response.body)).to eq(error_response_body)
476+
end
477+
end
491478

492-
context "when access token has expired already" do
493-
let(:token_exp) { 5.minutes.ago }
479+
context "when access token has expired already" do
480+
let(:token_exp) { 5.minutes.ago }
494481

495-
it do
496-
get resource
482+
it "fails with HTTP 401 Unauthorized" do
483+
get resource
497484

498-
expect(last_response).to have_http_status :unauthorized
499-
expect(last_response.header["WWW-Authenticate"])
500-
.to eq(%{Bearer realm="OpenProject API", error="invalid_token", error_description="Signature has expired"})
501-
expect(JSON.parse(last_response.body)).to eq(error_response_body)
502-
end
485+
expect(last_response).to have_http_status :unauthorized
486+
expect(last_response.header["WWW-Authenticate"])
487+
.to eq(%{Bearer realm="OpenProject API", error="invalid_token", error_description="Signature has expired"})
488+
expect(JSON.parse(last_response.body)).to eq(error_response_body)
489+
end
503490

504-
it "caches keys request to keycloak" do
505-
get resource
506-
expect(last_response).to have_http_status :unauthorized
491+
it "caches keys request to keycloak" do
492+
get resource
493+
expect(last_response).to have_http_status :unauthorized
507494

508-
get resource
509-
expect(last_response).to have_http_status :unauthorized
495+
get resource
496+
expect(last_response).to have_http_status :unauthorized
510497

511-
expect(keys_request_stub).to have_been_made.once
512-
end
513-
end
498+
expect(keys_request_stub).to have_been_made.once
514499
end
500+
end
515501

516-
context "when kid is absent in keycloak keys response" do
517-
let(:keys_request_stub) do
518-
wrong_key = JWT::JWK.new(OpenSSL::PKey::RSA.new(2048), kid: "your-kid", use: "sig", alg: "RS256")
519-
stub_request(:get, "https://keycloak.local/realms/master/protocol/openid-connect/certs")
520-
.with(
521-
headers: {
522-
"Accept" => "*/*",
523-
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
524-
"User-Agent" => /JSON::JWK::Set::Fetcher \d+\.\d+\.\d+/
525-
}
526-
)
527-
.to_return(status: 200, body: JWT::JWK::Set.new(wrong_key).export.to_json, headers: {})
528-
end
502+
context "when kid is absent in keycloak keys response" do
503+
let(:jwk_response) { JWT::JWK.new(OpenSSL::PKey::RSA.new(2048), kid: "your-kid", use: "sig", alg: "RS256") }
529504

530-
it do
531-
get resource
532-
expect(last_response).to have_http_status :unauthorized
533-
expect(JSON.parse(last_response.body)).to eq(error_response_body)
534-
error = "The signature key ID is unknown"
535-
expect(last_response.header["WWW-Authenticate"])
536-
.to eq(%{Bearer realm="OpenProject API", error="invalid_token", error_description="#{error}"})
537-
end
505+
it "fails with HTTP 401 Unauthorized" do
506+
get resource
507+
expect(last_response).to have_http_status :unauthorized
508+
expect(JSON.parse(last_response.body)).to eq(error_response_body)
509+
error = "The signature key ID is unknown"
510+
expect(last_response.header["WWW-Authenticate"])
511+
.to eq(%{Bearer realm="OpenProject API", error="invalid_token", error_description="#{error}"})
538512
end
539513
end
540514
end

0 commit comments

Comments
 (0)