class ADAL::MexResponse

Relevant fields from a Mex response.

Constants

ADDRESS_XPATH
BINDING_XPATH
POLICY_ID_XPATH
PORT_XPATH

Attributes

action[R]
wstrust_url[R]

Public Class Methods

new(wstrust_url, binding) click to toggle source

Constructs a new MexResponse.

@param String|URI wstrust_url @param String action

# File lib/adal/mex_response.rb, line 134
def initialize(wstrust_url, binding)
  @action = BINDING_TO_ACTION[binding]
  @wstrust_url = URI.parse(wstrust_url.to_s)
  return if @wstrust_url.instance_of? URI::HTTPS
  fail ArgumentError, 'Mex is only done over HTTPS.'
end
parse(response) click to toggle source

Parses the XML string response from the Metadata Exchange endpoint into a MexResponse object.

@param String response @return MexResponse

# File lib/adal/mex_response.rb, line 56
def self.parse(response)
  xml = Nokogiri::XML(response)
  policy_ids = parse_policy_ids(xml)
  bindings = parse_bindings(xml, policy_ids)
  endpoint, binding = parse_endpoint_and_binding(xml, bindings)
  MexResponse.new(endpoint, binding)
end

Private Class Methods

parse_all_endpoints(xml, bindings) click to toggle source

@param Nokogiri::XML::Document xml @param Array bindings @return Array[[String, String]]

# File lib/adal/mex_response.rb, line 80
def self.parse_all_endpoints(xml, bindings)
  endpoints = xml.xpath(PORT_XPATH, NAMESPACES).map do |node|
    binding = node.attr('binding').split(':').last
    if bindings.include? binding
      [node.xpath(ADDRESS_XPATH, NAMESPACES).to_s, binding]
    end
  end.compact
  endpoints
end
parse_bindings(xml, policy_ids) click to toggle source

@param Nokogiri::XML::Document xml @param Array policy_ids @return Array

# File lib/adal/mex_response.rb, line 67
def self.parse_bindings(xml, policy_ids)
  matching_bindings = xml.xpath(BINDING_XPATH, NAMESPACES).map do |node|
    reference_uri = node.xpath('./wsp:PolicyReference/@URI', NAMESPACES)
    node.xpath('./@name').to_s if policy_ids.include? reference_uri.to_s
  end.compact
  fail MexError, 'No matching bindings found.' if matching_bindings.empty?
  matching_bindings
end
parse_endpoint_and_binding(xml, bindings) click to toggle source

@param Nokogiri::XML::Document xml @param Array bindings @return [String, String]

# File lib/adal/mex_response.rb, line 94
def self.parse_endpoint_and_binding(xml, bindings)
  endpoints = parse_all_endpoints(xml, bindings)
  case endpoints.size
  when 0
    fail MexError, 'No valid WS-Trust endpoints found.'
  when 1
  else
    logger.info('Multiple WS-Trust endpoints were found in the mex ' \
                'response. Only one was used.')
  end
  prefer_13(endpoints).first
end
parse_policy_ids(xml) click to toggle source

@param Nokogiri::XML::Document xml @return Array

# File lib/adal/mex_response.rb, line 110
def self.parse_policy_ids(xml)
  policy_ids = xml.xpath(POLICY_ID_XPATH, NAMESPACES)
               .map { |attr| "\##{attr.value}" }
  fail MexError, 'No username token policy nodes.' if policy_ids.empty?
  policy_ids
end
prefer_13(endpoints) click to toggle source

@param Array[String, String] endpoints @return Array[String, String] endpoints

# File lib/adal/mex_response.rb, line 120
def self.prefer_13(endpoints)
  only13 = endpoints.select { |_, b| BINDING_TO_ACTION[b] == WSTRUST_13 }
  only13.empty? ? endpoints : only13
end