Class: Ciam::Saml::LogoutResponse

Inherits:
Object
  • Object
show all
Includes:
Coding, Request
Defined in:
lib/ciam/ruby-saml/logout_response.rb

Constant Summary collapse

ASSERTION =
"urn:oasis:names:tc:SAML:2.0:assertion"
PROTOCOL =
"urn:oasis:names:tc:SAML:2.0:protocol"
DSIG =
"http://www.w3.org/2000/09/xmldsig#"

Constants included from Request

Request::HTTP_GET, Request::HTTP_POST

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Request

#binding_select, #content_get, #content_post

Methods included from Coding

#decode, #deflate, #encode, #escape, #inflate, #unescape

Constructor Details

#initialize(options = { }) ⇒ LogoutResponse

Returns a new instance of LogoutResponse.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/ciam/ruby-saml/logout_response.rb', line 16

def initialize( options = { } )
	opt = { :response => nil, :settings => nil }.merge(options)
	# We've recieved a LogoutResponse from the IdP 
	if opt[:response]
		begin
			@response = Ciam::XMLSecurity::SignedDocument.new(decode( opt[:response] ))
			# Check to see if we have a root tag using the "protocol" namespace.
			# If not, it means this is deflated text and we need to raise to 
			# the rescue below
				raise if @response.nil?
				raise if @response.root.nil?
				raise if @response.root.namespace != PROTOCOL
			document
		rescue
			@response = Ciam::XMLSecurity::SignedDocument.new( inflate(decode( opt[:response] ) ) )
		end
	end
	# We plan to create() a new LogoutResponse
	if opt[:settings]
		@settings = opt[:settings]
	end
end

Instance Attribute Details

#settingsObject

Returns the value of attribute settings.



14
15
16
# File 'lib/ciam/ruby-saml/logout_response.rb', line 14

def settings
  @settings
end

Instance Method Details

#create(options) ⇒ Object

Create a LogoutResponse to to the IdP’s LogoutRequest

(For IdP initiated SLO)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
87
88
89
90
91
# File 'lib/ciam/ruby-saml/logout_response.rb', line 41

def create( options )
	opt = { :transaction_id => nil, 
		:in_response_to => nil,
		:status => "urn:oasis:names:tc:SAML:2.0:status:Success", 
		:extra_parameters => nil }.merge(options)
	return nil if opt[:transaction_id].nil?
	response_doc = Ciam::XMLSecurityNew::Document.new
	response_doc.context[:attribute_quote] = :quote

	uuid = "_" + UUID.new.generate
	time = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
	root = response_doc.add_element "saml2p:LogoutResponse", { "xmlns:saml2p" => PROTOCOL }
	root.attributes['ID'] = uuid
	root.attributes['IssueInstant'] = time
	root.attributes['Version'] = "2.0"
	root.attributes['Destination'] = @settings.single_logout_destination
	# Just convenient naming to accept both names as InResponseTo
	if opt[:transaction_id] 
		root.attributes['InResponseTo'] = opt[:transaction_id]
	elsif opt[:in_response_to]
		root.attributes['InResponseTo'] = opt[:in_response_to]
	end
	if @settings && @settings.issuer
		issuer = root.add_element "saml:Issuer", {
			"xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion"
		}
		issuer.text = @settings.issuer
	end

	response_doc << REXML::XMLDecl.new("1.0", "UTF-8")
    		#sign logout_response
    		cert = @settings.get_cert(@settings.sp_cert)

	# embed signature
	if @settings. && @settings.sp_private_key && @settings.sp_cert
		private_key = @settings.get_sp_key
		response_doc.sign_document(private_key, cert)
	end
	
	if opt[:status]
		status = root.add_element "saml2p:Status"
		status_code = status.add_element "saml2p:StatusCode", {
				"Value" => opt[:status]
		}
	end

	Logging.debug "Created LogoutResponse:\n #{response_doc}"
	
	return response_doc.to_s

end

#in_response_toObject



111
112
113
114
115
116
# File 'lib/ciam/ruby-saml/logout_response.rb', line 111

def in_response_to
			element = REXML::XPath.first(@response, "/p:LogoutResponse", {
					 "p" => PROTOCOL })
			return nil if element.nil?
 	element.attributes["InResponseTo"]
end

#is_valid?Boolean

Returns:

  • (Boolean)


126
127
128
# File 'lib/ciam/ruby-saml/logout_response.rb', line 126

def is_valid?
	validate(soft = true)
end

#issuerObject



104
105
106
107
108
109
# File 'lib/ciam/ruby-saml/logout_response.rb', line 104

def issuer
		element = REXML::XPath.first(@response, "/p:LogoutResponse/a:Issuer", { 
					"p" => PROTOCOL, "a" => ASSERTION} )
		return nil if element.nil?
		element.text
end

#success?Boolean

Returns:

  • (Boolean)


118
119
120
121
122
123
124
# File 'lib/ciam/ruby-saml/logout_response.rb', line 118

def success?
	element = REXML::XPath.first(@response, "/p:LogoutResponse/p:Status/p:StatusCode", {
			"p" => PROTOCOL })
	return false if element.nil?
	element.attributes["Value"] == "urn:oasis:names:tc:SAML:2.0:status:Success"
	
end

#to_sObject



100
101
102
# File 'lib/ciam/ruby-saml/logout_response.rb', line 100

def to_s
	@response.to_s
end

#to_xmlObject

function to return the created request as an XML document



94
95
96
97
98
# File 'lib/ciam/ruby-saml/logout_response.rb', line 94

def to_xml
	text = ""
	@response.write(text, 1)
	return text
end

#validate(soft = true) ⇒ Object



134
135
136
137
138
139
140
141
142
# File 'lib/ciam/ruby-saml/logout_response.rb', line 134

def validate( soft = true )
	return false if @response.nil?
	# Skip validation with a failed response if we don't have settings
	return false if @settings.nil?
	return false if @response.validate(@settings, soft) == false
	
	return true
	
end

#validate!Object



130
131
132
# File 'lib/ciam/ruby-saml/logout_response.rb', line 130

def validate!
	validate( soft = false )
end