Skip to content

Commit

Permalink
Add support for CDDO SSO
Browse files Browse the repository at this point in the history
  • Loading branch information
lfdebrux committed Jun 30, 2023
1 parent f22c7a9 commit a818fdd
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 0 deletions.
8 changes: 8 additions & 0 deletions app/controllers/authentication_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ def auth0_sign_out_url
URI::HTTPS.build(host: Settings.auth0.domain, path: "/v2/logout", query: request_params.to_query).to_s
end

def cddo_sso_sign_out_url
request_params = {
from_app: Settings.cddo_sso.identifier,
}

URI::HTTPS.build(host: "sso.service.security.gov.uk", path: "/sign-out", query: request_params.to_query).to_s
end

def mock_gds_sso_sign_out_url
"https://signon.integration.publishing.service.gov.uk/users/sign_out"
end
Expand Down
4 changes: 4 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ def header_component_options(user:, can_manage_users:)
user_profile_link: nil,
signout_link: sign_out_path,
},
cddo_sso: {
user_profile_link: "https://sso.service.security.gov.uk/profile",
signout_link: sign_out_path,
},
gds: {
user_profile_link: GDS::SSO::Config.oauth_root_url,
signout_link: gds_sign_out_path,
Expand Down
15 changes: 15 additions & 0 deletions config/initializers/authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@
},
)

# add CDDO SSO provider
Rails.application.config.app_middleware.use(
OmniAuth::Strategies::OpenIDConnect,
name: :cddo_sso,
issuer: "https://sso.service.security.gov.uk",
discovery: true,
require_state: true,

scope: %i[openid email profile],
client_options: {
identifier: Settings.cddo_sso.identifier,
secret: Settings.cddo_sso.secret,
},
)

# Configure Warden session management middleware
# swap out the Warden::Manager installed by `gds-sso` gem
Rails.application.config.app_middleware.swap Warden::Manager, Warden::Manager do |warden|
Expand Down
16 changes: 16 additions & 0 deletions config/initializers/warden/strategies/cddo_sso.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require "warden/strategies/omniauth"

Warden::Strategies.add(:cddo_sso) do
include Warden::Strategies::OmniAuth

private

def prep_user(auth_hash)
User.find_for_auth(
provider: auth_hash[:provider],
uid: auth_hash[:uid],
email: auth_hash[:info][:email],
name: auth_hash[:info][:name],
)
end
end
5 changes: 5 additions & 0 deletions config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,9 @@ basic_auth:
slug: gds-user-research
govuk_content_id: "00000000-0000-0000-0000-000000000000"

# CDDO SSO at sso.service.security.gov.uk via OpenID Connect
cddo_sso:
identifier: changeme
secret:

forms_env: local
1 change: 1 addition & 0 deletions spec/controller/application_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def index
%w[
auth0
basic_auth
cddo_sso
gds_sso
].each do |provider|
context "when #{provider} auth is enabled" do
Expand Down
84 changes: 84 additions & 0 deletions spec/integration/cddo_sso_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
require "rails_helper"

RSpec.describe "usage of cddo_sso auth provider" do
let(:omniauth_hash) do
OmniAuth::AuthHash.new({
provider: "cddo_sso",
uid: "123456",
info: {
email: "[email protected]",
name: "Test User",
},
})
end

before do
allow(Settings).to receive(:auth_provider).and_return("cddo_sso")

OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:cddo_sso] = nil
end

after do
OmniAuth.config.test_mode = false
end

describe "authentication" do
it "redirects to OmniAuth when no user is logged in" do
logout

get root_path

expect(response).to redirect_to("/auth/cddo_sso")
end

it "authenticates with OmniAuth and Warden" do
OmniAuth.config.mock_auth[:cddo_sso] = omniauth_hash

get "/auth/cddo_sso"

expect(response).to redirect_to("/auth/cddo_sso/callback")

get "/auth/cddo_sso/callback"

expect(request.env["warden"].authenticated?).to be true
end
end

describe "signing out" do
before do
OmniAuth.config.mock_auth[:cddo_sso] = omniauth_hash
get "/auth/cddo_sso"
get "/auth/cddo_sso/callback"
end

it "signs the user out of sso.service.security.gov.uk" do
allow(Settings.cddo_sso).to receive(:identifier).and_return("baz")

get sign_out_path

expect(response).to redirect_to("https://sso.service.security.gov.uk/sign-out?from_app=baz")
end
end

describe User do
describe ".find_for_auth" do
it "is called by the cddo_sso Warden strategy" do
allow(described_class).to receive(:find_for_auth).and_call_original

OmniAuth.config.mock_auth[:cddo_sso] = omniauth_hash
get "/auth/cddo_sso"
get "/auth/cddo_sso/callback"

expect(described_class).to have_received(:find_for_auth).with(
provider: "cddo_sso",
uid: "123456",
email: "[email protected]",
name: "Test User",
)

expect(request.env["warden"].winning_strategy.successful?).to be true
end
end
end
end

0 comments on commit a818fdd

Please sign in to comment.