Class: Maestrano::Saml::Response

Inherits:
Object
  • Object
show all
Includes:
Preset
Defined in:
lib/maestrano/saml/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#"

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Preset

included

Constructor Details

#initialize(response, options = {}) ⇒ Response

Returns a new instance of Response.

Raises:

  • (ArgumentError)


21
22
23
24
25
26
27
# File 'lib/maestrano/saml/response.rb', line 21

def initialize(response, options = {})
  raise ArgumentError.new("Response cannot be nil") if response.nil?
  @options  = options
  @response = (response =~ /^</) ? response : Base64.decode64(response)
  @document = Maestrano::XMLSecurity::SignedDocument.new(@response)
  @settings = Maestrano::SSO[self.class.preset].saml_settings
end

Instance Attribute Details

#documentObject (readonly)

Returns the value of attribute document.



19
20
21
# File 'lib/maestrano/saml/response.rb', line 19

def document
  @document
end

#optionsObject (readonly)

Returns the value of attribute options.



17
18
19
# File 'lib/maestrano/saml/response.rb', line 17

def options
  @options
end

#responseObject (readonly)

Returns the value of attribute response.



18
19
20
# File 'lib/maestrano/saml/response.rb', line 18

def response
  @response
end

#settingsObject

TODO: This should probably be ctor initialized too… WDYT?



15
16
17
# File 'lib/maestrano/saml/response.rb', line 15

def settings
  @settings
end

Instance Method Details

#attributesObject

A hash of all the attributes with the response. Multiple values will be returned in the AttributeValue#values array in reverse order, when compared to XML



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
# File 'lib/maestrano/saml/response.rb', line 55

def attributes
  @attr_statements ||= begin
    result = {}

    stmt_element = xpath_first_from_signed_assertion('/a:AttributeStatement')
    return {} if stmt_element.nil?

    stmt_element.elements.each do |attr_element|
      name  = attr_element.attributes["Name"]
      values = attr_element.elements.collect(&:text)

      # Set up a string-like wrapper for the values array
      attr_value = AttributeValue.new(values.first, values.reverse)
      # Merge values if the Attribute has already been seen
      if result[name]
        attr_value.values += result[name].values
      end

      result[name] = attr_value
    end

    result.keys.each do |key|
      result[key.intern] = result[key]
    end

    result
  end
end

#conditionsObject

Conditions (if any) for the assertion to run



101
102
103
# File 'lib/maestrano/saml/response.rb', line 101

def conditions
  @conditions ||= xpath_first_from_signed_assertion('/a:Conditions')
end

#is_valid?Boolean

Returns:

  • (Boolean)


29
30
31
# File 'lib/maestrano/saml/response.rb', line 29

def is_valid?
  validate
end

#issuerObject



113
114
115
116
117
118
119
# File 'lib/maestrano/saml/response.rb', line 113

def issuer
  @issuer ||= begin
    node = REXML::XPath.first(document, "/p:Response/a:Issuer", { "p" => PROTOCOL, "a" => ASSERTION })
    node ||= xpath_first_from_signed_assertion('/a:Issuer')
    node.nil? ? nil : node.text
  end
end

#name_idObject

The value of the user identifier as designated by the initialization request response



38
39
40
41
42
43
# File 'lib/maestrano/saml/response.rb', line 38

def name_id
  @name_id ||= begin
    node = xpath_first_from_signed_assertion('/a:Subject/a:NameID')
    node.nil? ? nil : node.text
  end
end

#not_beforeObject



105
106
107
# File 'lib/maestrano/saml/response.rb', line 105

def not_before
  @not_before ||= parse_time(conditions, "NotBefore")
end

#not_on_or_afterObject



109
110
111
# File 'lib/maestrano/saml/response.rb', line 109

def not_on_or_after
  @not_on_or_after ||= parse_time(conditions, "NotOnOrAfter")
end

#session_expires_atObject

When this user session should expire at latest



85
86
87
88
89
90
# File 'lib/maestrano/saml/response.rb', line 85

def session_expires_at
  @expires_at ||= begin
    node = xpath_first_from_signed_assertion('/a:AuthnStatement')
    parse_time(node, "SessionNotOnOrAfter")
  end
end

#sessionindexObject



45
46
47
48
49
50
# File 'lib/maestrano/saml/response.rb', line 45

def sessionindex
  @sessionindex ||= begin
    node = xpath_first_from_signed_assertion('/a:AuthnStatement')
    node.nil? ? nil : node.attributes['SessionIndex']
  end
end

#success?Boolean

Checks the status of the response for a “Success” code

Returns:

  • (Boolean)


93
94
95
96
97
98
# File 'lib/maestrano/saml/response.rb', line 93

def success?
  @status_code ||= begin
    node = REXML::XPath.first(document, "/p:Response/p:Status/p:StatusCode", { "p" => PROTOCOL, "a" => ASSERTION })
    node.attributes["Value"] == "urn:oasis:names:tc:SAML:2.0:status:Success"
  end
end

#validate!Object



33
34
35
# File 'lib/maestrano/saml/response.rb', line 33

def validate!
  validate(false)
end