Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Faulty XML parsing #47

Closed
davidmilo opened this issue Nov 8, 2016 · 2 comments
Closed

Faulty XML parsing #47

davidmilo opened this issue Nov 8, 2016 · 2 comments

Comments

@davidmilo
Copy link

davidmilo commented Nov 8, 2016

Hi, first of all thanks for maintaining this gem.

I had some problem when info parsed from xml was not entirely correct. Here is the example:

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
  <cas:authenticationSuccess>
  <cas:user>A</cas:user>
  <cas:attributes>
    <cas:attraStyle>Jasig</cas:attraStyle>
    <cas:mail>B</cas:mail>
    <cas:sc>C</cas:sc>
    <cas:first>D</cas:first>
    <cas:last>F</cas:last>
    <cas:nationality>G</cas:nationality>
    <cas:roles>F</cas:roles>
    <cas:roles>D</cas:roles>
    <cas:roles>R</cas:roles>
    <cas:roles>K</cas:roles>
    <cas:roles>L</cas:roles>
    <cas:roles>P</cas:roles>
    <cas:roles>I</cas:roles>
    <cas:roles>O</cas:roles>
    <cas:picture>N</cas:picture>
    <cas:birthdate>M</cas:birthdate>
    <cas:gender>M</cas:gender>
    <cas:telephone>N</cas:telephone>
    <cas:address>D</cas:address>
    <cas:section>F</cas:section>
    <cas:country>R</cas:country>
  </cas:attributes>
  </cas:authenticationSuccess>
</cas:serviceResponse>

As you can see, nodes cas:roles nodes are repeated several times (not sure if this is because cas server is implemented wrong or it is common way to do it.) but anyways. Your current parsing algorithm would only return last of those roles nodes:
{ "roles" => "O"} which is wrong. It should return all as an array: { "roles" => ["F" , "D" , "R" , "K" , "L", "P", "I", "O" ]}.

I would suggest to use Hash.from_xml - i think it comes from rails tho, it is more bulletproof for this kind of cases you haven't though about in your parsing algorithm.

@danschmidt5189
Copy link
Collaborator

danschmidt5189 commented Jul 13, 2018

We're dealing with this same bug at UC Berkeley libraries. The trouble is that this behavior is intended, tested (context, fixture, assertion), and hard-coded.

@davidmilo suggested a breaking change, as clients may depend on the faulty "last value-only" behavior. And since any attribute could be (or become) multivalued, it may make sense to always return them as a list. (I'm not sure what the CAS spec has to say about this.)

An easy, non-breaking solution would be to simply forward ServiceTicketValidator@success_body to the fetch_raw_info callback, giving developers full access to the response object. Developers would then have the option of walking the Nokogiri document as they saw fit. For example:

fetch_raw_info: lambda { |v, opts, ticket, info, raw|
  {
    :roles => raw.xpath('//cas:roles').map(&:text),
  }
}

Here's the CAS v3 spec: https://apereo.github.io/cas/5.0.x/protocol/CAS-Protocol-Specification.html#4251-saml-cas-response-attributes).

danschmidt5189 added a commit to danschmidt5189/omniauth-cas that referenced this issue Jul 13, 2018
danschmidt5189 added a commit to danschmidt5189/omniauth-cas that referenced this issue Jul 13, 2018
danschmidt5189 added a commit to danschmidt5189/omniauth-cas that referenced this issue Jul 15, 2018
danschmidt5189 added a commit to danschmidt5189/omniauth-cas that referenced this issue Jul 15, 2018
danschmidt5189 added a commit to danschmidt5189/omniauth-cas that referenced this issue Jul 18, 2018
Forwards the XML response received from CASAuth to the fetch_raw_info
callback, which now accepts five arguments (cas, options, ticket, user
info, and the raw response). Developers who override fetch_raw_info with
a Proc are unaffected -- the new argument is silently discarded -- but
developers who use a Lambda will need to update their code.
danschmidt5189 added a commit that referenced this issue Feb 14, 2019
…ields

Forward success response to fetch_raw_info callback (#47)
@danschmidt5189
Copy link
Collaborator

danschmidt5189 commented Feb 15, 2019

@davidmilo I merged a workaround in #51. If you're using the latest branch, try something like:

provider :cas,
  name: :calnet,
  host: "auth#{'-test' unless Rails.env.production?}.berkeley.edu",
  login_url: '/cas/login',
  service_validate_url: '/cas/p3/serviceValidate',
  fetch_raw_info: Proc.new { |strategy, opts, ticket, user_info, doc|
    doc.empty? ? {} : { "roles" => doc.xpath('//cas:roles').map(&:text) }
  }

I'm not sure that we know in advance what fields may be multivalued in a given CAS setup, so it seems safest to me to let the user handle it (as in my example). I really don't like the idea of using multi-valued fields only when we detect multiple values, as that could lead to the role appearing as a string for users with one role and as an array for users with multiple roles.

Closing for now. Feel free to comment with feedback and we can consider better designs.

Expect the fix in the upcoming v2.0.0 release.

dezande pushed a commit to jobteaser/omniauth-cas that referenced this issue Apr 23, 2020
Forwards the XML response received from CASAuth to the fetch_raw_info
callback, which now accepts five arguments (cas, options, ticket, user
info, and the raw response). Developers who override fetch_raw_info with
a Proc are unaffected -- the new argument is silently discarded -- but
developers who use a Lambda will need to update their code.
dezande pushed a commit to jobteaser/omniauth-cas that referenced this issue Apr 24, 2020
Forwards the XML response received from CASAuth to the fetch_raw_info
callback, which now accepts five arguments (cas, options, ticket, user
info, and the raw response). Developers who override fetch_raw_info with
a Proc are unaffected -- the new argument is silently discarded -- but
developers who use a Lambda will need to update their code.
redconfetti pushed a commit to sis-berkeley-edu/omniauth-cas that referenced this issue Sep 19, 2023
Forwards the XML response received from CASAuth to the fetch_raw_info
callback, which now accepts five arguments (cas, options, ticket, user
info, and the raw response). Developers who override fetch_raw_info with
a Proc are unaffected -- the new argument is silently discarded -- but
developers who use a Lambda will need to update their code.
redconfetti pushed a commit to sis-berkeley-edu/omniauth-cas that referenced this issue Nov 18, 2023
Forwards the XML response received from CASAuth to the fetch_raw_info
callback, which now accepts five arguments (cas, options, ticket, user
info, and the raw response). Developers who override fetch_raw_info with
a Proc are unaffected -- the new argument is silently discarded -- but
developers who use a Lambda will need to update their code.
redconfetti pushed a commit to sis-berkeley-edu/omniauth-cas that referenced this issue Nov 18, 2023
Forwards the XML response received from CASAuth to the fetch_raw_info
callback, which now accepts five arguments (cas, options, ticket, user
info, and the raw response). Developers who override fetch_raw_info with
a Proc are unaffected -- the new argument is silently discarded -- but
developers who use a Lambda will need to update their code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants