Skip to content

Instantly share code, notes, and snippets.

@mcansky
Created July 25, 2014 12:58
Show Gist options
  • Save mcansky/e165aecf64d5c39e71cb to your computer and use it in GitHub Desktop.
Save mcansky/e165aecf64d5c39e71cb to your computer and use it in GitHub Desktop.
RMUnify logout
class SometController
def logout
authenticator = Service::RmUnify::Logout.new(params: params)
@user = authenticator.user
@user.reset_remember_token!
redirect_to authenticator.redirect_url
end
end
require 'uuid'
require 'zlib'
require 'base64'
module Service
module RmUnify
class Logout
include Virtus.model
attribute :params
def user
@user ||= ::User.where(rm_unify_uid: uid).first
end
def redirect_url
"#{::Settings.rm_unify.saml.base_url}#{logout_params}"
end
protected
def doc
@doc ||= Nokogiri::XML(
decode_raw_saml_response(params['SAMLRequest'])
).remove_namespaces!
end
def uid
doc.xpath('//NameID').first.text
end
def rid
doc.root.attr('ID')
end
def logout_params
"#{params[:RelayState]}#{logout_response}"
end
def xml_builder
Nokogiri::XML::Builder.new do |xml|
xml.send(:'samlp:LogoutResponse',
'xmlns:samlp' => 'urn:oasis:names:tc:SAML:2.0:protocol',
'xmlns:saml' => 'urn:oasis:names:tc:SAML:2.0:assertion',
'ID' => "_#{UUID.new.generate}",
'Version' => '2.0',
'IssueInstant' => Time.new.strftime("%Y-%m-%dT%H:%M:%S"),
'InResponseTo' => rid,
) do
xml.send(:'saml:Issuer', Settings.rm_unify.saml.issuer)
xml.send(:'samlp:Status') do
xml.send(:'samlp:StatusCode',
'Value' => 'urn:oasis:names:tc:SAML:2.0:status:Success')
xml.send(
:'samlp:StatusMessage',
'Successfully logged out from ShowMyHomework'
)
end
end
end.to_xml
end
def xml
Nokogiri::XML(xml_builder).root.to_xml
end
def logout_response
deflated = Zlib::Deflate.deflate(xml, 9)[2..-5]
base64 = Base64.encode64(deflated)
encoded = CGI.escape(base64)
"&SAMLResponse=#{encoded}"
end
def inflate(deflated)
zlib = Zlib::Inflate.new(-Zlib::MAX_WBITS)
zlib.inflate(deflated)
end
def decode_raw_saml_response(response)
if response =~ /^</
response
elsif (decoded = Base64.decode64(response)) =~ /^</
decoded
elsif (inflated = inflate(decoded)) =~ /^</
inflated
else
raise "Couldn't decode SAMLResponse"
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment