Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LG-226 Fix Double Render Error with Bad Saml Packet on Logout #2125

Merged
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
1 change: 0 additions & 1 deletion app/controllers/concerns/saml_idp_logout_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ def prepare_saml_logout_response
end

def prepare_saml_logout_request
validate_saml_request
return if slo_session[:logout_response]
# store originating SP's logout response in the user session
# for final step in SLO
Expand Down
24 changes: 21 additions & 3 deletions app/controllers/saml_idp_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class SamlIdpController < ApplicationController
include VerifySPAttributesConcern

skip_before_action :verify_authenticity_token
before_action :validate_saml_logout_request, only: :logout

def auth
return confirm_two_factor_authenticated(request_id) unless user_fully_authenticated?
Expand All @@ -26,7 +27,6 @@ def metadata
end

def logout
track_logout_event
prepare_saml_logout_response_and_request

return handle_saml_logout_response if slo.successful_saml_response?
Expand All @@ -38,6 +38,21 @@ def logout

private

def validate_saml_logout_request(raw_saml_request = params[:SAMLRequest])
request_valid = saml_request_valid?(raw_saml_request)

track_logout_event(request_valid)
return unless raw_saml_request

head :bad_request unless request_valid
end

def saml_request_valid?(saml_request)
return false unless saml_request
decode_request(saml_request)
valid_saml_request?
end

def saml_metadata
if SamlCertRotationManager.use_new_secrets_for_request?(request)
cert_rotation_saml_metadata
Expand Down Expand Up @@ -96,11 +111,14 @@ def render_template_for(message, action_url, type)
)
end

def track_logout_event
def track_logout_event(saml_request_valid)
saml_request = params[:SAMLRequest]
result = {
sp_initiated: params[:SAMLRequest].present?,
sp_initiated: saml_request.present?,
oidc: false,
}
result[:saml_request_valid] = saml_request_valid

analytics.track_event(Analytics::LOGOUT_INITIATED, result)
end
end
23 changes: 21 additions & 2 deletions spec/controllers/saml_idp_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

it 'tracks the event when idp-initiated' do
stub_analytics
result = { sp_initiated: false, oidc: false }
result = { sp_initiated: false, oidc: false, saml_request_valid: false }

expect(@analytics).to receive(:track_event).with(Analytics::LOGOUT_INITIATED, result)

Expand All @@ -29,7 +29,16 @@
it 'tracks the event when sp-initiated' do
allow(controller).to receive(:saml_request).and_return(FakeSamlRequest.new)
stub_analytics
result = { sp_initiated: true, oidc: false }
result = { sp_initiated: true, oidc: false, saml_request_valid: true }

expect(@analytics).to receive(:track_event).with(Analytics::LOGOUT_INITIATED, result)

delete :logout, params: { SAMLRequest: 'foo' }
end

it 'tracks the event when sp-initiated and the saml request is not valid' do
stub_analytics
result = { sp_initiated: true, oidc: false, saml_request_valid: false }

expect(@analytics).to receive(:track_event).with(Analytics::LOGOUT_INITIATED, result)

Expand All @@ -38,6 +47,16 @@
end

describe 'POST /api/saml/logout' do
context 'when there is an invalid SAML packet' do
let(:user) { create(:user, :signed_up) }

it 'responds with "400 Bad Request"' do
sign_in user

post :logout, params: { SAMLRequest: 'foo' }
expect(response.status).to eq(400)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also add a test for analytics to make sure it reports saml_request_valid: false and sp_initiated: true?

Copy link
Contributor

@monfresh monfresh May 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed that the new one you added above is basically the same as this one. Can we combine the two, i.e. add expect(response.status).to eq(400) to the one above?

end
end
context 'when SAML response is not successful' do
let(:user) { create(:user, :signed_up) }

Expand Down