Commit d543c41
Changed files (3)
lib
saml
spec
lib/saml/kit/logout_request.rb
@@ -0,0 +1,45 @@
+module Saml
+ module Kit
+ class LogoutRequest
+ class Builder
+ attr_accessor :id, :destination, :issuer, :name_id_format, :now
+ attr_reader :user
+
+ def initialize(user, configuration: Saml::Kit.configuration)
+ @user = user
+ @id = SecureRandom.uuid
+ @issuer = configuration.issuer
+ @name_id_format = Saml::Kit::Namespaces::PERSISTENT
+ @now = Time.now.utc
+ end
+
+ def to_xml
+ xml = ::Builder::XmlMarkup.new
+ xml.instruct!
+ xml.LogoutRequest logout_request_options do
+ xml.Issuer issuer
+ xml.NameID name_id_options, user.name_id_for(self)
+ end
+ xml.target!
+ end
+
+ private
+
+ def logout_request_options
+ {
+ ID: id,
+ Version: "2.0",
+ IssueInstant: now.utc.iso8601,
+ Destination: destination,
+ }
+ end
+
+ def name_id_options
+ {
+ Format: name_id_format,
+ }
+ end
+ end
+ end
+ end
+end
lib/saml/kit.rb
@@ -17,6 +17,7 @@ require "saml/kit/configuration"
require "saml/kit/content"
require "saml/kit/default_registry"
require "saml/kit/fingerprint"
+require "saml/kit/logout_request"
require "saml/kit/namespaces"
require "saml/kit/metadata"
require "saml/kit/request"
spec/saml/logout_request_spec.rb
@@ -0,0 +1,30 @@
+require 'spec_helper'
+
+RSpec.describe Saml::Kit::LogoutRequest do
+ describe described_class::Builder do
+ subject { described_class.new(user) }
+ let(:user) { double(:user, name_id_for: name_id) }
+ let(:name_id) { SecureRandom.uuid }
+
+ it 'produces the expected xml' do
+ travel_to 1.second.from_now
+ subject.id = SecureRandom.uuid
+ subject.destination = FFaker::Internet.http_url
+ subject.issuer = FFaker::Internet.http_url
+ subject.name_id_format = Saml::Kit::Namespaces::TRANSIENT
+
+ result = subject.to_xml
+ xml_hash = Hash.from_xml(result)
+
+ expect(xml_hash['LogoutRequest']['ID']).to eql(subject.id)
+ expect(xml_hash['LogoutRequest']['Version']).to eql("2.0")
+ expect(xml_hash['LogoutRequest']['IssueInstant']).to eql(Time.now.utc.iso8601)
+ expect(xml_hash['LogoutRequest']['Destination']).to eql(subject.destination)
+
+ expect(xml_hash['LogoutRequest']['Issuer']).to eql(subject.issuer)
+ expect(xml_hash['LogoutRequest']['NameID']).to eql(name_id)
+ doc = Nokogiri::XML(result)
+ expect(doc.xpath("//LogoutRequest//NameID[@Format=\"#{subject.name_id_format}\"]")).to be_present
+ end
+ end
+end