discourse-openid-connect/spec/requests/rp_initiated_logout_spec.rb

103 lines
3.9 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
describe "OIDC RP-Initiated Logout" do
let(:document_url) { SiteSetting.openid_connect_discovery_document = "https://id.example.com/.well-known/openid-configuration" }
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",
"end_session_endpoint": "https://id.example.com/endsession",
}
end
let(:user) { Fabricate(:user) }
before do
SiteSetting.openid_connect_enabled = true
SiteSetting.openid_connect_rp_initiated_logout = true
stub_request(:get, document_url).to_return(body: lambda { |r| document.to_json })
end
after do
Discourse.cache.delete("openid-connect-discovery-#{document_url}")
end
it "does nothing for a user with no oidc record" do
sign_in(user)
delete "/session/#{user.username}", xhr: true
expect(response.status).to eq(200)
expect(response.parsed_body["redirect_url"]).to eq("/")
end
it "does nothing for a user with no token in their oidc record" do
sign_in(user)
UserAssociatedAccount.create!(provider_name: "oidc", user: user, provider_uid: "myuid")
delete "/session/#{user.username}", xhr: true
expect(response.status).to eq(200)
expect(response.parsed_body["redirect_url"]).to eq("/")
end
context "with user and token" do
before do
sign_in(user)
UserAssociatedAccount.create!(provider_name: "oidc", user: user, provider_uid: "myuid", extra: { id_token: "myoidctoken" })
end
it "redirects the user to the logout endpoint" do
delete "/session/#{user.username}", xhr: true
expect(response.status).to eq(200)
expect(response.parsed_body["redirect_url"]).to eq("https://id.example.com/endsession?id_token_hint=myoidctoken")
end
it "correctly handles logout urls with existing query params" do
document[:end_session_endpoint] += "?param=true"
delete "/session/#{user.username}", xhr: true
expect(response.status).to eq(200)
expect(response.parsed_body["redirect_url"]).to eq("https://id.example.com/endsession?param=true&id_token_hint=myoidctoken")
end
it "includes the redirect URI if set" do
SiteSetting.openid_connect_rp_initiated_logout_redirect = "https://example.com"
delete "/session/#{user.username}", xhr: true
expect(response.status).to eq(200)
expect(response.parsed_body["redirect_url"]).to eq("https://id.example.com/endsession?id_token_hint=myoidctoken&post_logout_redirect_uri=https%3A%2F%2Fexample.com")
end
it "does not redirect if plugin disabled" do
SiteSetting.openid_connect_enabled = false
delete "/session/#{user.username}", xhr: true
expect(response.status).to eq(200)
expect(response.parsed_body["redirect_url"]).to eq("/")
end
it "does not redirect if rp initiated logout disabled" do
SiteSetting.openid_connect_rp_initiated_logout = false
delete "/session/#{user.username}", xhr: true
expect(response.status).to eq(200)
expect(response.parsed_body["redirect_url"]).to eq("/")
end
it "does not redirect if the discovery document is missing the endpoint" do
stub_request(:get, document_url).to_return(body: "{}")
SiteSetting.openid_connect_rp_initiated_logout = false
delete "/session/#{user.username}", xhr: true
expect(response.status).to eq(200)
expect(response.parsed_body["redirect_url"]).to eq("/")
end
it "does not redirect if the discovery document has a network error" do
stub_request(:get, document_url).to_timeout
SiteSetting.openid_connect_rp_initiated_logout = false
delete "/session/#{user.username}", xhr: true
expect(response.status).to eq(200)
expect(response.parsed_body["redirect_url"]).to eq("/")
end
end
end