Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions app/controllers/openid_connect/authorization_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,31 @@ def set_devise_failure_redirect_for_concurrent_session_logout
end

def link_identity_to_service_provider
@authorize_form.link_identity_to_service_provider(current_user, session.id)
@authorize_form.link_identity_to_service_provider(
current_user: current_user,
ial: resolved_authn_context_int_ial,
rails_session_id: session.id,
)
end

def ial_context
IalContext.new(
ial: @authorize_form.ial,
ial: resolved_authn_context_int_ial,
service_provider: @authorize_form.service_provider,
user: current_user,
)
end

def resolved_authn_context_int_ial
if resolved_authn_context_result.ialmax?
0
elsif resolved_authn_context_result.identity_proofing?
2
else
1
end
end

def handle_successful_handoff
track_events
SpHandoffBounce::AddHandoffTimeToSession.call(sp_session)
Expand Down
35 changes: 11 additions & 24 deletions app/forms/openid_connect_authorize_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,16 @@ def service_provider
@service_provider = ServiceProvider.find_by(issuer: client_id)
end

def link_identity_to_service_provider(current_user, rails_session_id)
def link_identity_to_service_provider(
current_user:,
ial:,
rails_session_id:
)
identity_linker = IdentityLinker.new(current_user, service_provider)
@identity = identity_linker.link_identity(
nonce: nonce,
rails_session_id: rails_session_id,
ial: ial,
aal: aal,
acr_values: acr_values&.join(' '),
vtr: vtr,
requested_aal_value: requested_aal_value,
Expand All @@ -117,30 +120,10 @@ def ial_values
acr_values.filter { |acr| acr.include?('ial') || acr.include?('loa') }
end

def ial
if parsed_vector_of_trust&.identity_proofing?
2
elsif parsed_vector_of_trust.present?
1
else
Saml::Idp::Constants::AUTHN_CONTEXT_CLASSREF_TO_IAL[ial_values.sort.max]
end
end

def aal_values
acr_values.filter { |acr| acr.include?('aal') }
end

def aal
if parsed_vector_of_trust&.aal2?
2
elsif parsed_vector_of_trust.present?
1
else
Saml::Idp::Constants::AUTHN_CONTEXT_CLASSREF_TO_AAL[requested_aal_value]
end
end

def requested_aal_value
highest_level_aal(aal_values) ||
Saml::Idp::Constants::DEFAULT_AAL_AUTHN_CONTEXT_CLASSREF
Expand Down Expand Up @@ -336,7 +319,11 @@ def sp_defaults_to_identity_proofing?
end

def identity_proofing_requested?
ial == 2
if parsed_vector_of_trust.present?
parsed_vector_of_trust.identity_proofing?
else
Saml::Idp::Constants::AUTHN_CONTEXT_CLASSREF_TO_IAL[ial_values.sort.max] == 2
end
end

def identity_proofing_service_provider?
Expand All @@ -348,7 +335,7 @@ def ialmax_allowed_for_sp?
end

def ialmax_requested?
ial == 0
Saml::Idp::Constants::AUTHN_CONTEXT_CLASSREF_TO_IAL[ial_values.sort.max] == 0
end

def highest_level_aal(aal_values)
Expand Down
166 changes: 10 additions & 156 deletions spec/forms/openid_connect_authorize_form_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -416,160 +416,6 @@
end
end

describe '#ial' do
context 'with vtr param' do
let(:acr_values) { nil }

context 'when proofing is requested' do
let(:vtr) { ['C1.P1'].to_json }

it { expect(form.ial).to eq(2) }
end

context 'when proofing is not requested' do
let(:vtr) { ['C1'].to_json }

it { expect(form.ial).to eq(1) }
end
end

context 'with acr_values param' do
let(:vtr) { nil }

context 'when IAL1 passed' do
let(:acr_values) { Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF }

it 'returns 1' do
expect(form.ial).to eq(1)
end
end

context 'when IAL2 passed' do
let(:acr_values) { Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF }

it 'returns 2' do
expect(form.ial).to eq(2)
end
end

context 'when IALMAX passed' do
let(:acr_values) { Saml::Idp::Constants::IALMAX_AUTHN_CONTEXT_CLASSREF }

it 'returns 0' do
expect(form.ial).to eq(0)
end
end

context 'when LOA1 passed' do
let(:acr_values) { Saml::Idp::Constants::LOA1_AUTHN_CONTEXT_CLASSREF }

it 'returns 1' do
expect(form.ial).to eq(1)
end
end

context 'when LOA3 passed' do
let(:acr_values) { Saml::Idp::Constants::LOA3_AUTHN_CONTEXT_CLASSREF }

it 'returns 2' do
expect(form.ial).to eq(2)
end
end
end
end

describe '#aal' do
context 'with vtr param' do
let(:acr_values) { nil }

context 'when AAL2 is requested' do
let(:vtr) { ['C2'].to_json }

it { expect(form.aal).to eq(2) }
end

context 'when AAL2 is not requested' do
let(:vtr) { ['C1'].to_json }

it { expect(form.aal).to eq(1) }
end
end

context 'with acr_values param' do
let(:vtr) { nil }

context 'when no AAL passed' do
let(:acr_values) { Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF }

it 'returns 0' do
expect(form.aal).to eq(0)
end
end

context 'when DEFAULT_AAL passed' do
let(:acr_values) { Saml::Idp::Constants::DEFAULT_AAL_AUTHN_CONTEXT_CLASSREF }

it 'returns 0' do
expect(form.aal).to eq(0)
end
end

context 'when AAL2 passed' do
let(:acr_values) { Saml::Idp::Constants::AAL2_AUTHN_CONTEXT_CLASSREF }

it 'returns 2' do
expect(form.aal).to eq(2)
end
end

context 'when AAL2_PHISHING_RESISTANT passed' do
let(:acr_values) { Saml::Idp::Constants::AAL2_PHISHING_RESISTANT_AUTHN_CONTEXT_CLASSREF }

it 'returns 2' do
expect(form.aal).to eq(2)
end
end

context 'when AAL2_HSPD12 passed' do
let(:acr_values) { Saml::Idp::Constants::AAL2_HSPD12_AUTHN_CONTEXT_CLASSREF }

it 'returns 2' do
expect(form.aal).to eq(2)
end
end

context 'when AAL3 passed' do
let(:acr_values) { Saml::Idp::Constants::AAL3_AUTHN_CONTEXT_CLASSREF }

it 'returns 3' do
expect(form.aal).to eq(3)
end
end

context 'when AAL3_HSPD12 passed' do
let(:acr_values) { Saml::Idp::Constants::AAL3_HSPD12_AUTHN_CONTEXT_CLASSREF }

it 'returns 3' do
expect(form.aal).to eq(3)
end
end

context 'when IAL and AAL passed' do
aal2 = Saml::Idp::Constants::AAL2_AUTHN_CONTEXT_CLASSREF
ial2 = Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF

let(:acr_values) do
"#{aal2} #{ial2}"
end

it 'returns ial and aal' do
expect(form.aal).to eq(2)
expect(form.ial).to eq(2)
end
end
end
end

describe '#requested_aal_value' do
context 'with ACR values' do
let(:vtr) { nil }
Expand Down Expand Up @@ -775,7 +621,11 @@
let(:code_challenge_method) { 'S256' }

it 'records the code_challenge on the identity' do
form.link_identity_to_service_provider(user, rails_session_id)
form.link_identity_to_service_provider(
current_user: user,
ial: 1,
rails_session_id: rails_session_id,
)

identity = user.identities.where(service_provider: client_id).first

Expand All @@ -794,7 +644,11 @@

context 'when the identity has been linked' do
before do
form.link_identity_to_service_provider(user, rails_session_id)
form.link_identity_to_service_provider(
current_user: user,
ial: 1,
rails_session_id: rails_session_id,
)
end

it 'returns a redirect URI with the code from the identity session_uuid' do
Expand Down