-
-
Save mcansky/e165aecf64d5c39e71cb to your computer and use it in GitHub Desktop.
RMUnify logout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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