Class: DiscourseConnectProvider
- Inherits:
-
DiscourseConnectBase
- Object
- DiscourseConnectBase
- DiscourseConnectProvider
- Defined in:
- lib/discourse_connect_provider.rb
Defined Under Namespace
Classes: BlankReturnUrl, BlankSecret, InvalidParameterValueError
Constant Summary
Constants inherited from DiscourseConnectBase
DiscourseConnectBase::ACCESSORS, DiscourseConnectBase::BOOLS, DiscourseConnectBase::FIXNUMS
Instance Attribute Summary
Attributes inherited from DiscourseConnectBase
Class Method Summary collapse
- .lookup_return_sso_url(parsed_payload) ⇒ Object
- .lookup_sso_secret(return_sso_url, parsed_payload) ⇒ Object
- .parse(payload, sso_secret = nil, **init_kwargs) ⇒ Object
Methods inherited from DiscourseConnectBase
#custom_fields, #diagnostics, nonce_expiry_time, nonce_expiry_time=, #payload, #sign, sign, sso_secret, sso_url, #to_h, #to_json, #to_url, #unsigned_payload, used_nonce_expiry_time
Class Method Details
.lookup_return_sso_url(parsed_payload) ⇒ Object
54 55 56 57 58 |
# File 'lib/discourse_connect_provider.rb', line 54 def self.lookup_return_sso_url(parsed_payload) decoded = Base64.decode64(parsed_payload["sso"]) decoded_hash = Rack::Utils.parse_query(decoded) decoded_hash["return_sso_url"] end |
.lookup_sso_secret(return_sso_url, parsed_payload) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/discourse_connect_provider.rb', line 60 def self.lookup_sso_secret(return_sso_url, parsed_payload) return nil unless return_sso_url && SiteSetting.enable_discourse_connect_provider return_url_host = URI.parse(return_sso_url).host provider_secrets = SiteSetting .discourse_connect_provider_secrets .split("\n") .map { |row| row.split("|", 2) } .sort_by { |k, _| k } .reverse first_domain_match = nil pair = provider_secrets.find do |domain, configured_secret| if WildcardDomainChecker.check_domain(domain, return_url_host) first_domain_match ||= configured_secret sign(parsed_payload["sso"], configured_secret) == parsed_payload["sig"] end end # falls back to a secret which will fail to validate in DiscourseConnectBase # this ensures error flow is correct pair.present? ? pair[1] : first_domain_match end |
.parse(payload, sso_secret = nil, **init_kwargs) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/discourse_connect_provider.rb', line 18 def self.parse(payload, sso_secret = nil, **init_kwargs) # We extract the return_sso_url parameter early; we need the URL's host # in order to lookup the correct SSO secret in our site settings. parsed_payload = Rack::Utils.parse_query(payload) return_sso_url = lookup_return_sso_url(parsed_payload) raise ParseError if !return_sso_url sso_secret ||= lookup_sso_secret(return_sso_url, parsed_payload) if sso_secret.blank? begin host = URI.parse(return_sso_url).host Rails.logger.warn( "SSO failed; website #{host} is not in the `discourse_connect_provider_secrets` site settings", ) rescue StandardError => e # going for StandardError cause URI::Error may not be enough, eg it parses to something not # responding to host Discourse.warn_exception( e, message: "SSO failed; invalid or missing return_sso_url in SSO payload", ) end raise BlankSecret end sso = super(payload, sso_secret, **init_kwargs) # Do general parameter validation now, after signature-verification has succeeded. raise InvalidParameterValueError.new("prompt") if (sso.prompt != nil) && (sso.prompt != "none") sso end |