class DiscourseApi::SingleSignOn
Constants
- ACCESSORS
- ARRAYS
- BOOLS
- FIXNUMS
Attributes
custom_fields[W]
sso_secret[W]
sso_url[W]
Public Class Methods
parse(payload, sso_secret = nil)
click to toggle source
# File lib/discourse_api/single_sign_on.rb, line 96 def self.parse(payload, sso_secret = nil) sso = new sso.sso_secret = sso_secret if sso_secret parsed = Rack::Utils.parse_query(payload) if 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 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 raise ParseError, "Bad signature for payload #{diags}" end end decoded = Base64.decode64(parsed["sso"]) decoded_hash = Rack::Utils.parse_query(decoded) ACCESSORS.each do |k| val = decoded_hash[k.to_s] val = val.to_i if FIXNUMS.include? k val = %w[true false].include?(val) ? val == "true" : nil if BOOLS.include? k val = val.split(",") if ARRAYS.include?(k) && !val.nil? sso.send("#{k}=", val) end decoded_hash.each do |k, v| if field = k[/^custom\.(.+)$/, 1] sso.custom_fields[field] = v end end sso end
parse_hash(payload)
click to toggle source
# File lib/discourse_api/single_sign_on.rb, line 67 def self.parse_hash(payload) sso = new sso.sso_secret = payload.delete(:sso_secret) sso.sso_url = payload.delete(:sso_url) ACCESSORS.each do |k| val = payload[k] val = val.to_i if FIXNUMS.include? k val = %w[true false].include?(val) ? val == "true" : nil if BOOLS.include? k val = val.split(",") if ARRAYS.include?(k) && !val.nil? sso.send("#{k}=", val) end # Set custom_fields sso.custom_fields = payload[:custom_fields] # Add custom_fields (old format) payload.each do |k, v| if field = k[/^custom\.(.+)$/, 1] # Maintain adding of .custom bug sso.custom_fields["custom.#{field}"] = v end end sso end
sso_secret()
click to toggle source
# File lib/discourse_api/single_sign_on.rb, line 59 def self.sso_secret raise MissingConfigError, "sso_secret not implemented on class, be sure to set it on instance" end
sso_url()
click to toggle source
# File lib/discourse_api/single_sign_on.rb, line 63 def self.sso_url raise MissingConfigError, "sso_url not implemented on class, be sure to set it on instance" end
Public Instance Methods
custom_fields()
click to toggle source
# File lib/discourse_api/single_sign_on.rb, line 144 def custom_fields @custom_fields ||= {} end
diagnostics()
click to toggle source
# File lib/discourse_api/single_sign_on.rb, line 132 def diagnostics DiscourseApi::SingleSignOn::ACCESSORS.map { |a| "#{a}: #{send(a)}" }.join("\n") end
payload()
click to toggle source
# File lib/discourse_api/single_sign_on.rb, line 157 def payload payload = Base64.strict_encode64(unsigned_payload) "sso=#{CGI.escape(payload)}&sig=#{sign(payload)}" end
sign(payload)
click to toggle source
# File lib/discourse_api/single_sign_on.rb, line 148 def sign(payload) OpenSSL::HMAC.hexdigest("sha256", sso_secret, payload) end
sso_secret()
click to toggle source
# File lib/discourse_api/single_sign_on.rb, line 136 def sso_secret @sso_secret || self.class.sso_secret end
sso_url()
click to toggle source
# File lib/discourse_api/single_sign_on.rb, line 140 def sso_url @sso_url || self.class.sso_url end
to_url(base_url = nil)
click to toggle source
# File lib/discourse_api/single_sign_on.rb, line 152 def to_url(base_url = nil) base = "#{base_url || sso_url}" "#{base}#{base.include?("?") ? "&" : "?"}#{payload}" end
unsigned_payload()
click to toggle source
# File lib/discourse_api/single_sign_on.rb, line 162 def unsigned_payload payload = {} ACCESSORS.each do |k| next if (val = send k) == nil payload[k] = val end @custom_fields.each { |k, v| payload["custom.#{k}"] = v.to_s } if @custom_fields Rack::Utils.build_query(payload) end