diff --git a/lib/discourse_api/single_sign_on.rb b/lib/discourse_api/single_sign_on.rb index f7a805a..19bc8b4 100644 --- a/lib/discourse_api/single_sign_on.rb +++ b/lib/discourse_api/single_sign_on.rb @@ -98,10 +98,10 @@ def self.parse(payload, sso_secret = nil) sso.sso_secret = sso_secret if sso_secret parsed = Rack::Utils.parse_query(payload) - if sso.sign(parsed["sso"]) != parsed["sig"] + if parsed["sso"].nil? || sso.sign(parsed["sso"]) != parsed["sig"] diags = - "\n\nsso: #{parsed["sso"]}\n\nsig: #{parsed["sig"]}\n\nexpected sig: #{sso.sign(parsed["sso"])}" - if parsed["sso"] =~ %r{[^a-zA-Z0-9=\r\n/+]}m + "\n\nsso: #{parsed["sso"].inspect}\n\nsig: #{parsed["sig"].inspect}\n\nexpected sig: #{sso.sign(parsed.fetch("sso", ""))}" + if parsed["sso"].nil? || parsed["sso"] =~ %r{[^a-zA-Z0-9=\r\n/+]}m raise ParseError, "The SSO field should be Base64 encoded, using only A-Z, a-z, 0-9, +, /, and = characters. Your input contains characters we don't understand as Base64, see http://en.wikipedia.org/wiki/Base64 #{diags}" else diff --git a/spec/discourse_api/single_sign_on_spec.rb b/spec/discourse_api/single_sign_on_spec.rb index 183d0d5..3451735 100644 --- a/spec/discourse_api/single_sign_on_spec.rb +++ b/spec/discourse_api/single_sign_on_spec.rb @@ -32,12 +32,29 @@ end describe ".parse" do - it "raises ParseError when there's a signature mismatch" do - sso = described_class.new - sso.sso_secret = "abcd" - expect { described_class.parse(sso.payload, "dcba") }.to raise_error( - DiscourseApi::SingleSignOn::ParseError, - ) + context "when sso is present" do + it "raises ParseError when there's a signature mismatch" do + sso = described_class.new + sso.sso_secret = "abcd" + expect { described_class.parse(sso.payload, "dcba") }.to raise_error( + DiscourseApi::SingleSignOn::ParseError, + ) + end + end + + context "when sso is missing" do + it "raises ParseError when there's a signature mismatch" do + sso = described_class.new + sso.sso_secret = "abcd" + missing_sso = Rack::Utils.parse_query(sso.payload) + missing_sso.delete("sso") + malformed_query = Rack::Utils.build_query(missing_sso) + + expect { described_class.parse(malformed_query, "dcba") }.to raise_error( + DiscourseApi::SingleSignOn::ParseError, + /The SSO field should/i, + ) + end end end end