Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
### 3.0.9
* Added `Scoping` element to an `AuthnRequest`

### 3.0.8
* Backward compatibility fix. (#147)

### 3.0.7
* Added signature config and response location

### 3.0.6
* Fix the encryption of an EncryptedID element with multiple recipients.

Expand Down
3 changes: 3 additions & 0 deletions lib/saml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ module Elements
require 'saml/elements/entities_descriptor'
require 'saml/elements/attribute_query'
require 'saml/elements/evidence'
require 'saml/elements/idp_entry'
require 'saml/elements/idp_list'
require 'saml/elements/scoping'
end

module Rails
Expand Down
1 change: 1 addition & 0 deletions lib/saml/authn_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class AuthnRequest
attribute :provider_name, String, :tag => "ProviderName"

has_one :requested_authn_context, Saml::Elements::RequestedAuthnContext
has_one :scoping, Saml::Elements::Scoping

validates :force_authn, :inclusion => [true, false, nil]
validates :assertion_consumer_service_index, :numericality => true, :if => lambda { |val|
Expand Down
16 changes: 16 additions & 0 deletions lib/saml/elements/idp_entry.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Saml
module Elements
class IdpEntry
include Saml::Base

tag 'IDPEntry'
namespace 'samlp'

attribute :provider_id, String, :tag => 'ProviderID'
attribute :name, String, :tag => 'Name'
attribute :loc, String, :tag => 'Loc'

validates :provider_id, :presence => true
end
end
end
19 changes: 19 additions & 0 deletions lib/saml/elements/idp_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Saml
module Elements
class IdpList
include Saml::Base

tag 'IDPList'
namespace 'samlp'

has_many :idp_entries, Saml::Elements::IdpEntry

validates :idp_entries, :presence => true

def initialize(*args)
super(*args)
self.idp_entries ||= []
end
end
end
end
12 changes: 12 additions & 0 deletions lib/saml/elements/scoping.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Saml
module Elements
class Scoping
include Saml::Base

tag 'Scoping'
namespace 'samlp'

has_one :idp_list, Saml::Elements::IdpList
end
end
end
2 changes: 1 addition & 1 deletion lib/saml/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Saml
VERSION = '3.0.8'
VERSION = '3.0.9'
end
11 changes: 11 additions & 0 deletions spec/factories/all.rb
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,15 @@ class StatementDummy
factory :session_index, class: Saml::Elements::SessionIndex do
value 'SessionIndex'
end

factory :scoping, :class => Saml::Elements::Scoping do
end

factory :idp_list, :class => Saml::Elements::IdpList do
end

factory :idp_entry, :class => Saml::Elements::IdpEntry do
provider_id 'ProviderID'
end

end
6 changes: 6 additions & 0 deletions spec/fixtures/authn_request.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,10 @@
<samlp:RequestedAuthnContext Comparison="minimum">
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>
<samlp:Scoping>
<samlp:IDPList>
<samlp:IDPEntry ProviderID="provider-id-1" Name="Provider name 1" Loc="https://idp1.example.com"/>
<samlp:IDPEntry ProviderID="provider-id-2" Name="Provider name 2" Loc="https://idp2.example.com"/>
</samlp:IDPList>
</samlp:Scoping>
</samlp:AuthnRequest>
6 changes: 5 additions & 1 deletion spec/lib/saml/authn_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
Saml::AuthnRequest.tag_name.should == "AuthnRequest"
end

[:force_authn, :assertion_consumer_service_index, :assertion_consumer_service_url, :protocol_binding, :provider_name, :requested_authn_context, :is_passive].each do |attribute|
[:force_authn, :assertion_consumer_service_index, :assertion_consumer_service_url, :protocol_binding, :provider_name, :requested_authn_context, :is_passive, :scoping].each do |attribute|
it "should accept the #{attribute} attribute" do
authn_request.should respond_to(attribute)
end
Expand Down Expand Up @@ -78,6 +78,10 @@
authn_request.requested_authn_context.should be_a(Saml::Elements::RequestedAuthnContext)
end

it 'should create a Saml::Elements::Scoping' do
expect(authn_request.scoping).to be_a(Saml::Elements::Scoping)
end

context "with two requested_authn_context_class_refs" do
let(:authn_request_xml) { File.read(File.join('spec', 'fixtures', 'authn_request_with_two_authn_contexts.xml'))}

Expand Down
27 changes: 27 additions & 0 deletions spec/lib/saml/elements/idp_entry_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'spec_helper'

describe Saml::Elements::IdpEntry do
let(:idp_entry) { FactoryGirl.build :idp_entry }

describe 'optional fields' do
[:name, :loc].each do |field|
it "should respond to the '#{field}' field" do
expect(subject).to respond_to(field)
end
end
end

describe 'required fields' do
[:provider_id].each do |field|
it "should have the #{field} field" do
subject.should respond_to(field)
end

it "should check the presence of #{field}" do
subject.send("#{field}=", nil)
subject.should_not be_valid
end
end
end

end
50 changes: 50 additions & 0 deletions spec/lib/saml/elements/idp_list_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require 'spec_helper'

describe Saml::Elements::IdpList do
let(:idp_list) { FactoryGirl.build :idp_list }

describe 'required fields' do
[:idp_entries].each do |field|
it "should have the #{field} field" do
subject.should respond_to(field)
end

it "should check the presence of #{field}" do
subject.send("#{field}=", nil)
subject.should_not be_valid
end
end
end

describe '#idp_entries' do
it 'returns an empty array if no IDP entries have been registered' do
expect(subject.idp_entries).to eq []
end
end

describe '#parse_xml' do
let(:authn_request_xml) { File.read(File.join('spec', 'fixtures', 'authn_request.xml')) }
let(:idp_list) { Saml::Elements::IdpList.parse(authn_request_xml, single: true) }

it 'should create a new Saml::Elements::IdpList' do
expect(idp_list).to be_a(Saml::Elements::IdpList)
end

it 'should parse the IDP entries' do
aggregate_failures do
expect(idp_list.idp_entries.count).to eq 2

expect(idp_list.idp_entries.first).to be_a(Saml::Elements::IdpEntry)
expect(idp_list.idp_entries.first.provider_id).to eq 'provider-id-1'
expect(idp_list.idp_entries.first.name).to eq 'Provider name 1'
expect(idp_list.idp_entries.first.loc).to eq 'https://idp1.example.com'

expect(idp_list.idp_entries.second).to be_a(Saml::Elements::IdpEntry)
expect(idp_list.idp_entries.second.provider_id).to eq 'provider-id-2'
expect(idp_list.idp_entries.second.name).to eq 'Provider name 2'
expect(idp_list.idp_entries.second.loc).to eq 'https://idp2.example.com'
end
end
end

end
27 changes: 27 additions & 0 deletions spec/lib/saml/elements/scoping_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'spec_helper'

describe Saml::Elements::Scoping do
let(:idp_entry) { FactoryGirl.build :scoping }

describe 'optional fields' do
[:idp_list].each do |field|
it "should respond to the '#{field}' field" do
expect(subject).to respond_to(field)
end
end
end

describe '#parse_xml' do
let(:authn_request_xml) { File.read(File.join('spec', 'fixtures', 'authn_request.xml')) }
let(:scoping) { Saml::Elements::Scoping.parse(authn_request_xml, single: true) }

it 'should create a new Saml::Elements::Scoping' do
expect(scoping).to be_a(Saml::Elements::Scoping)
end

it 'should parse the IDP list' do
expect(scoping.idp_list).to be_a(Saml::Elements::IdpList)
end
end

end