saml_idp 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -98,7 +98,7 @@ CERT
98
98
  # config.attribute_service_location = "#{base}/saml/attributes"
99
99
  # config.single_service_post_location = "#{base}/saml/auth"
100
100
 
101
- # Principal is passed in when you `encode_response`
101
+ # Principal (e.g. User) is passed in when you `encode_response`
102
102
  #
103
103
  # config.name_id.formats # =>
104
104
  # { # All 2.0
@@ -118,6 +118,28 @@ CERT
118
118
  # },
119
119
  # }
120
120
 
121
+ # If Principal responds to a method called `asserted_attributes`
122
+ # the return value of that method will be used in lieu of the
123
+ # attributes defined here in the global space. This allows for
124
+ # per-user attribute definitions.
125
+ #
126
+ ## EXAMPLE **
127
+ # class User
128
+ # def asserted_attributes
129
+ # {
130
+ # phone: { getter: :phone },
131
+ # email: {
132
+ # getter: :email,
133
+ # name_format: Saml::XML::Namespaces::Formats::NameId::EMAIL_ADDRESS,
134
+ # name_id_format: Saml::XML::Namespaces::Formats::NameId::EMAIL_ADDRESS
135
+ # }
136
+ # }
137
+ # end
138
+ # end
139
+ #
140
+ # If you have a method called `asserted_attributes` in your Principal class,
141
+ # there is no need to define it here in the config.
142
+
121
143
  # config.attributes # =>
122
144
  # {
123
145
  # <friendly_name> => { # required (ex "eduPersonAffiliation")
@@ -52,9 +52,9 @@ module SamlIdp
52
52
  restriction.Audience audience_uri
53
53
  end
54
54
  end
55
- if !config.attributes.nil? && !config.attributes.empty?
55
+ if asserted_attributes
56
56
  assertion.AttributeStatement do |attr_statement|
57
- config.attributes.each do |friendly_name, attrs|
57
+ asserted_attributes.each do |friendly_name, attrs|
58
58
  attrs = (attrs || {}).with_indifferent_access
59
59
  attr_statement.Attribute Name: attrs[:name] || friendly_name,
60
60
  NameFormat: attrs[:name_format] || Saml::XML::Namespaces::Formats::Attr::URI,
@@ -85,6 +85,15 @@ module SamlIdp
85
85
  encryptor.encrypt(raw_xml)
86
86
  end
87
87
 
88
+ def asserted_attributes
89
+ if principal.respond_to?(:asserted_attributes)
90
+ principal.send(:asserted_attributes)
91
+ elsif !config.attributes.nil? && !config.attributes.empty?
92
+ config.attributes
93
+ end
94
+ end
95
+ private :asserted_attributes
96
+
88
97
  def get_values_for(friendly_name, getter)
89
98
  result = nil
90
99
  if getter.present?
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module SamlIdp
3
- VERSION = '0.3.2'
3
+ VERSION = '0.4.0'
4
4
  end
@@ -50,7 +50,7 @@ section of the README.
50
50
  s.add_development_dependency "rake"
51
51
  s.add_development_dependency "simplecov"
52
52
  s.add_development_dependency "rspec", "~> 2.5"
53
- s.add_development_dependency "ruby-saml", "~> 1.2"
53
+ s.add_development_dependency "ruby-saml", "~> 1.3"
54
54
  s.add_development_dependency("rails", "~> 3.2")
55
55
  s.add_development_dependency("capybara")
56
56
  s.add_development_dependency("timecop")
@@ -55,6 +55,27 @@ module SamlIdp
55
55
  end
56
56
  end
57
57
 
58
+ describe "with principal.asserted_attributes" do
59
+ it "delegates attributes to principal" do
60
+ Principal = Struct.new(:email, :asserted_attributes)
61
+ principal = Principal.new('foo@example.com', { emailAddress: { getter: :email } })
62
+ builder = described_class.new(
63
+ reference_id,
64
+ issuer_uri,
65
+ principal,
66
+ audience_uri,
67
+ saml_request_id,
68
+ saml_acs_url,
69
+ algorithm,
70
+ authn_context_classref,
71
+ expiry
72
+ )
73
+ Timecop.travel(Time.zone.local(2010, 6, 1, 13, 0, 0)) do
74
+ builder.raw.should == "<Assertion xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_abc\" IssueInstant=\"2010-06-01T13:00:00Z\" Version=\"2.0\"><Issuer>http://sportngin.com</Issuer><Subject><NameID Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\">foo@example.com</NameID><SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><SubjectConfirmationData InResponseTo=\"123\" NotOnOrAfter=\"2010-06-01T13:03:00Z\" Recipient=\"http://saml.acs.url\"></SubjectConfirmationData></SubjectConfirmation></Subject><Conditions NotBefore=\"2010-06-01T12:59:55Z\" NotOnOrAfter=\"2010-06-01T16:00:00Z\"><AudienceRestriction><Audience>http://example.com</Audience></AudienceRestriction></Conditions><AttributeStatement><Attribute Name=\"emailAddress\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"emailAddress\"><AttributeValue>foo@example.com</AttributeValue></Attribute></AttributeStatement><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement></Assertion>"
75
+ end
76
+ end
77
+ end
78
+
58
79
  it "builds encrypted XML" do
59
80
  builder = described_class.new(
60
81
  reference_id,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saml_idp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-06-08 00:00:00.000000000 Z
12
+ date: 2016-07-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -146,7 +146,7 @@ dependencies:
146
146
  requirements:
147
147
  - - ~>
148
148
  - !ruby/object:Gem::Version
149
- version: '1.2'
149
+ version: '1.3'
150
150
  type: :development
151
151
  prerelease: false
152
152
  version_requirements: !ruby/object:Gem::Requirement
@@ -154,7 +154,7 @@ dependencies:
154
154
  requirements:
155
155
  - - ~>
156
156
  - !ruby/object:Gem::Version
157
- version: '1.2'
157
+ version: '1.3'
158
158
  - !ruby/object:Gem::Dependency
159
159
  name: rails
160
160
  requirement: !ruby/object:Gem::Requirement
@@ -393,7 +393,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
393
393
  version: '0'
394
394
  segments:
395
395
  - 0
396
- hash: -2339269672469207321
396
+ hash: 3959281244219564156
397
397
  required_rubygems_version: !ruby/object:Gem::Requirement
398
398
  none: false
399
399
  requirements:
@@ -402,7 +402,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
402
402
  version: '0'
403
403
  segments:
404
404
  - 0
405
- hash: -2339269672469207321
405
+ hash: 3959281244219564156
406
406
  requirements: []
407
407
  rubyforge_project:
408
408
  rubygems_version: 1.8.23