From cc80fddb28ecba88822610e6a097cbc8c37feac0 Mon Sep 17 00:00:00 2001 From: Ricardo Hermida Ruiz Date: Wed, 12 Jul 2023 10:56:51 -0300 Subject: [PATCH] Provide a way to fetch all ticket attributes --- CHANGELOG.md | 4 ++ lib/cassette/authentication.rb | 18 +++++---- lib/cassette/authentication/user.rb | 5 +++ lib/cassette/http/ticket_response.rb | 7 ++-- spec/cassette/authentication/user_spec.rb | 46 ++++++++++++++++++++++ spec/cassette/authentication_spec.rb | 6 +++ spec/cassette/http/ticket_response_spec.rb | 18 +++++++++ spec/fixtures/cas/success.xml | 2 + 8 files changed, 96 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6bb72c..22a2764 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## UNRELEASED +### Added +- Provide `Cassette::Authentication::User#attribute` to fetch generic attributes + from the user in the ticket validation response + ## [1.6.0] - 2020-11-26 ### Changed - Make `cas_extra_attributes` accessible as strings or symbols when restoring diff --git a/lib/cassette/authentication.rb b/lib/cassette/authentication.rb index 3202e5c..1f7912c 100644 --- a/lib/cassette/authentication.rb +++ b/lib/cassette/authentication.rb @@ -36,13 +36,17 @@ def ticket_user(ticket, service = config.service) logger.info("Validation resut: #{response.inspect}") - Cassette::Authentication::User.new( - login: ticket_response.login, - name: ticket_response.name, - authorities: ticket_response.authorities, - ticket: ticket, - config: config - ) if ticket_response.login + if ticket_response.login + attributes = ticket_response.attributes.dup.merge( + login: ticket_response.login, + name: ticket_response.name, + authorities: ticket_response.authorities, + ticket: ticket, + config: config + ) + + Cassette::Authentication::User.new(attributes) + end rescue => exception logger.error "Error while authenticating ticket #{ticket}: #{exception.message}" raise Cassette::Errors::Forbidden, exception.message diff --git a/lib/cassette/authentication/user.rb b/lib/cassette/authentication/user.rb index 203c357..4676eae 100644 --- a/lib/cassette/authentication/user.rb +++ b/lib/cassette/authentication/user.rb @@ -19,10 +19,15 @@ def initialize(attrs = {}) @type = attrs[:type] @email = attrs[:email] @ticket = attrs[:ticket] + @attributes = attrs @authorities = Cassette::Authentication::Authorities .parse(attrs.fetch(:authorities, '[]'), config && config.base_authority) end + def attribute(key) + attributes[key] + end + %w(customer employee).each do |type| define_method :"#{type}?" do !@type.nil? && @type.to_s.downcase == type.to_s diff --git a/lib/cassette/http/ticket_response.rb b/lib/cassette/http/ticket_response.rb index 186d581..38199bb 100644 --- a/lib/cassette/http/ticket_response.rb +++ b/lib/cassette/http/ticket_response.rb @@ -4,7 +4,7 @@ module Cassette module Http class TicketResponse - attr_reader :login, :name, :authorities + attr_reader :login, :name, :authorities, :attributes def initialize(response) namespaces = { "cas" => "http://www.yale.edu/tp/cas" } @@ -22,8 +22,9 @@ def initialize(response) elements. map { |e| [e.name, e.text] }] - @name = attributes['cn'] - @authorities = attributes['authorities'] + @name = attributes.delete('cn') + @authorities = attributes.delete('authorities') + @attributes = attributes end end end diff --git a/spec/cassette/authentication/user_spec.rb b/spec/cassette/authentication/user_spec.rb index 299f22c..1d10789 100644 --- a/spec/cassette/authentication/user_spec.rb +++ b/spec/cassette/authentication/user_spec.rb @@ -24,6 +24,52 @@ authorities: '[CUSTOMERAPI, SAPI]', config: config) end end + + context 'attributes' do + it 'takes login from the attributes' do + user = described_class.new(login: 'john.doe') + + expect(user.login).to eql('john.doe') + end + + it 'takes name from the attributes' do + user = described_class.new(name: 'John Doe') + + expect(user.name).to eql('John Doe') + end + end + end + + describe '#attribute' do + it 'returns attributes given to the user' do + user = described_class.new( + login: 'john.doe', + name: 'John Doe', + attributes: { 'attribute' => 'something' } + ) + + expect(user.attribute('attribute')).to eql('something') + end + + it 'retuns nil for attributes not given to the user' do + user = described_class.new( + login: 'john.doe', + name: 'John Doe', + attributes: { 'attribute' => 'something' } + ) + + expect(user.attribute('other_attribute')).to be_nil + end + + it 'does not return attributes that are already extracted' do + user = described_class.new( + login: 'john.doe', + name: 'John Doe', + attributes: { 'attribute' => 'something' } + ) + + expect(user.attribute('login')).to be_nil + end end describe '#has_role?' do diff --git a/spec/cassette/authentication_spec.rb b/spec/cassette/authentication_spec.rb index 36db87a..8b58c31 100644 --- a/spec/cassette/authentication_spec.rb +++ b/spec/cassette/authentication_spec.rb @@ -69,6 +69,12 @@ it 'returns an User' do expect(ticket_user).to be_instance_of(Cassette::Authentication::User) end + + it 'sets attributes from the ticket response' do + expect(ticket_user.login).to eql('test-user') + expect(ticket_user.name).to eql('Test System') + expect(ticket_user.attribute('type')).to eql('system') + end end end end diff --git a/spec/cassette/http/ticket_response_spec.rb b/spec/cassette/http/ticket_response_spec.rb index 7ebf96e..385b733 100644 --- a/spec/cassette/http/ticket_response_spec.rb +++ b/spec/cassette/http/ticket_response_spec.rb @@ -38,4 +38,22 @@ it { is_expected.to be_nil } end end + + describe '#attributes' do + subject(:attributes) { ticket_response.attributes } + + context 'when response is successful' do + let(:xml_response) { fixture('cas/success.xml') } + + it 'returns the attributes not already extracted' do + expect(subject).to eq('type' => 'System', 'attribute' => 'something') + end + end + + context 'when response is not successful' do + let(:xml_response) { fixture('cas/fail.xml') } + + it { is_expected.to be_empty } + end + end end diff --git a/spec/fixtures/cas/success.xml b/spec/fixtures/cas/success.xml index bf620b3..8fdce79 100644 --- a/spec/fixtures/cas/success.xml +++ b/spec/fixtures/cas/success.xml @@ -6,6 +6,8 @@ [CUPOM, AUDITING,] Test System + System + something