133 lines
4.0 KiB
Ruby
133 lines
4.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "rails_helper"
|
|
require_relative "../../lib/omniauth_open_id_connect"
|
|
|
|
describe OpenIDConnectAuthenticator do
|
|
let(:authenticator) { described_class.new }
|
|
fab!(:user)
|
|
let(:hash) do
|
|
OmniAuth::AuthHash.new(
|
|
provider: "oidc",
|
|
uid: "123456789",
|
|
info: {
|
|
name: "John Doe",
|
|
email: user.email,
|
|
},
|
|
extra: {
|
|
raw_info: {
|
|
email: user.email,
|
|
name: "John Doe",
|
|
},
|
|
},
|
|
)
|
|
end
|
|
|
|
context "when email_verified is not supplied" do
|
|
# Some IDPs do not supply this information
|
|
# In this case we trust that they have verified the address
|
|
it "matches the user" do
|
|
result = authenticator.after_authenticate(hash)
|
|
|
|
expect(result.user).to eq(user)
|
|
end
|
|
end
|
|
|
|
context "when email_verified is true" do
|
|
it "matches the user" do
|
|
hash[:extra][:raw_info][:email_verified] = true
|
|
result = authenticator.after_authenticate(hash)
|
|
expect(result.user).to eq(user)
|
|
end
|
|
|
|
it "matches the user as a true string" do
|
|
hash[:extra][:raw_info][:email_verified] = "true"
|
|
result = authenticator.after_authenticate(hash)
|
|
expect(result.user).to eq(user)
|
|
end
|
|
|
|
it "matches the user as a titlecase true string" do
|
|
hash[:extra][:raw_info][:email_verified] = "True"
|
|
result = authenticator.after_authenticate(hash)
|
|
expect(result.user).to eq(user)
|
|
end
|
|
end
|
|
|
|
context "when email_verified is false" do
|
|
it "does not match the user" do
|
|
hash[:extra][:raw_info][:email_verified] = false
|
|
result = authenticator.after_authenticate(hash)
|
|
expect(result.user).to eq(nil)
|
|
end
|
|
|
|
it "does not match the user as a false string" do
|
|
hash[:extra][:raw_info][:email_verified] = "false"
|
|
result = authenticator.after_authenticate(hash)
|
|
expect(result.user).to eq(nil)
|
|
end
|
|
end
|
|
|
|
context "when match_by_email is false" do
|
|
it "does not match the user" do
|
|
SiteSetting.openid_connect_match_by_email = false
|
|
result = authenticator.after_authenticate(hash)
|
|
expect(result.user).to eq(nil)
|
|
end
|
|
end
|
|
|
|
describe "discovery document fetching" do
|
|
let(:document_url) do
|
|
SiteSetting.openid_connect_discovery_document =
|
|
"https://id.example.com/.well-known/openid-configuration"
|
|
end
|
|
let(:document) do
|
|
{
|
|
issuer: "https://id.example.com/",
|
|
authorization_endpoint: "https://id.example.com/authorize",
|
|
token_endpoint: "https://id.example.com/token",
|
|
userinfo_endpoint: "https://id.example.com/userinfo",
|
|
}.to_json
|
|
end
|
|
after { Discourse.cache.delete("openid-connect-discovery-#{document_url}") }
|
|
|
|
it "loads the document correctly" do
|
|
stub_request(:get, document_url).to_return(body: document)
|
|
expect(authenticator.discovery_document.keys).to contain_exactly(
|
|
"issuer",
|
|
"authorization_endpoint",
|
|
"token_endpoint",
|
|
"userinfo_endpoint",
|
|
)
|
|
end
|
|
|
|
it "handles a non-200 response" do
|
|
stub_request(:get, document_url).to_return(status: 404)
|
|
expect(authenticator.discovery_document).to eq(nil)
|
|
end
|
|
|
|
it "handles a network error" do
|
|
stub_request(:get, document_url).to_timeout
|
|
expect(authenticator.discovery_document).to eq(nil)
|
|
end
|
|
|
|
it "handles invalid json" do
|
|
stub_request(:get, document_url).to_return(body: "this is not the json you're looking for")
|
|
expect(authenticator.discovery_document).to eq(nil)
|
|
end
|
|
|
|
it "caches a success response" do
|
|
stub = stub_request(:get, document_url).to_return(body: document)
|
|
expect(authenticator.discovery_document).not_to eq(nil)
|
|
expect(authenticator.discovery_document).not_to eq(nil)
|
|
expect(stub).to have_been_requested.once
|
|
end
|
|
|
|
it "caches a failed response" do
|
|
stub = stub_request(:get, document_url).to_return(status: 404)
|
|
expect(authenticator.discovery_document).to eq(nil)
|
|
expect(authenticator.discovery_document).to eq(nil)
|
|
expect(stub).to have_been_requested.once
|
|
end
|
|
end
|
|
end
|