saml_idp 0.12.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73712903d3949f895e57a13b138c007e0ae74715d7d546b4415f278829e59054
4
- data.tar.gz: fbab7e28d01ea3fc7624e52e20a234f6f997a51643905170e6809cb3f7beeec7
3
+ metadata.gz: 847e2cafec28e67417685e6ba1173aa88ac489172e0e31fa51f2bbab37ef5d10
4
+ data.tar.gz: 8d9ace44b46770b3ca7481461bd16fce9dfc0e2b9925a4a2b5460a780cfddce3
5
5
  SHA512:
6
- metadata.gz: 80a4683963e04b8b7f68051d15b12a5f0a098300cbfba9b72c4ed3940338ab3505c47cda0b091a9a36c1605f4396b5f1732bed7d3356438dd944f83541573a47
7
- data.tar.gz: b01be29f645e31f9987afef74bb8b368ccfc86340b67e29524f582fe139e99b56cd827315d5a4e73d34b69e2c3c5b89d881c89f6d29b68c4b3cd2ff5499a39c3
6
+ metadata.gz: 6aa29d58babddddc81037fe220276241a355d81a15acb3639a9cc6df935f531bf1fe53e3c5599d49640080776c357ebf6348559ac034313ad64f82f80a7824a0
7
+ data.tar.gz: 9f5b83fd6459476d81c2dc2d3f0e79c401ba01474856f201c5a32615da8e22e4c416d220ef82985205f69f1d87a560a80c3bbae552a39ec4bdb49cc0a1baafa0
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ruby SAML Identity Provider (IdP)
2
2
 
3
- Forked from https://github.com/lawrencepit/ruby-saml-idp
3
+ Forked from <https://github.com/lawrencepit/ruby-saml-idp>
4
4
 
5
5
  [![Build Status](https://travis-ci.org/saml-idp/saml_idp.svg)](https://travis-ci.org/saml-idp/saml_idp)
6
6
  [![Gem Version](https://badge.fury.io/rb/saml_idp.svg)](http://badge.fury.io/rb/saml_idp)
@@ -13,13 +13,15 @@ protocol. It provides a means for managing authentication requests and confirmat
13
13
  This was originally setup by @lawrencepit to test SAML Clients. I took it closer to a real
14
14
  SAML IDP implementation.
15
15
 
16
- # Installation and Usage
16
+ ## Installation and Usage
17
17
 
18
18
  Add this to your Gemfile:
19
19
 
20
+ ```ruby
20
21
  gem 'saml_idp'
22
+ ```
21
23
 
22
- ## Not using rails?
24
+ ### Not using rails?
23
25
 
24
26
  Include `SamlIdp::Controller` and see the examples that use rails. It should be straightforward for you.
25
27
 
@@ -27,50 +29,16 @@ Basically you call `decode_request(params[:SAMLRequest])` on an incoming request
27
29
  `saml_acs_url` to determine the source for which you need to authenticate a user. How you authenticate
28
30
  a user is entirely up to you.
29
31
 
30
- Once a user has successfully authenticated on your system send the Service Provider a SAMLReponse by
32
+ Once a user has successfully authenticated on your system send the Service Provider a SAMLResponse by
31
33
  posting to `saml_acs_url` the parameter `SAMLResponse` with the return value from a call to
32
34
  `encode_response(user_email)`.
33
35
 
34
- ## Using rails?
36
+ ### Using rails?
35
37
 
36
- Add to your `routes.rb` file, for example:
37
-
38
- ```ruby
39
- get '/saml/auth' => 'saml_idp#new'
40
- get '/saml/metadata' => 'saml_idp#show'
41
- post '/saml/auth' => 'saml_idp#create'
42
- match '/saml/logout' => 'saml_idp#logout', via: [:get, :post, :delete]
43
- ```
38
+ Check out our Wiki page for Rails integration
39
+ [Rails Integration guide](https://github.com/saml-idp/saml_idp/wiki/Rails_Integration)
44
40
 
45
- Create a controller that looks like this, customize to your own situation:
46
-
47
- ```ruby
48
- class SamlIdpController < SamlIdp::IdpController
49
- def idp_authenticate(email, password) # not using params intentionally
50
- user = User.by_email(email).first
51
- user && user.valid_password?(password) ? user : nil
52
- end
53
- private :idp_authenticate
54
-
55
- def idp_make_saml_response(found_user) # not using params intentionally
56
- # NOTE encryption is optional
57
- encode_response found_user, encryption: {
58
- cert: saml_request.service_provider.cert,
59
- block_encryption: 'aes256-cbc',
60
- key_transport: 'rsa-oaep-mgf1p'
61
- }
62
- end
63
- private :idp_make_saml_response
64
-
65
- def idp_logout
66
- user = User.by_email(saml_request.name_id)
67
- user.logout
68
- end
69
- private :idp_logout
70
- end
71
- ```
72
-
73
- ## Configuration
41
+ ### Configuration
74
42
 
75
43
  #### Signed assertions and Signed Response
76
44
 
@@ -230,7 +198,7 @@ CERT
230
198
  end
231
199
  ```
232
200
 
233
- # Keys and Secrets
201
+ ## Keys and Secrets
234
202
 
235
203
  To generate the SAML Response it uses a default X.509 certificate and secret key... which isn't so secret.
236
204
  You can find them in `SamlIdp::Default`. The X.509 certificate is valid until year 2032.
@@ -241,31 +209,31 @@ and `SamlIdp.config.secret_key` properties.
241
209
 
242
210
  The fingerprint to use, if you use the default X.509 certificate of this gem, is:
243
211
 
244
- ```
245
- 9E:65:2E:03:06:8D:80:F2:86:C7:6C:77:A1:D9:14:97:0A:4D:F4:4D
212
+ ```bash
213
+ 9E:65:2E:03:06:8D:80:F2:86:C7:6C:77:A1:D9:14:97:0A:4D:F4:4D
246
214
  ```
247
215
 
248
- # Fingerprint
216
+ ## Fingerprint
249
217
 
250
218
  The gem provides an helper to generate a fingerprint for a X.509 certificate.
251
219
  The second parameter is optional and default to your configuration `SamlIdp.config.algorithm`
252
220
 
253
221
  ```ruby
254
- Fingerprint.certificate_digest(x509_cert, :sha512)
222
+ Fingerprint.certificate_digest(x509_cert, :sha512)
255
223
  ```
256
224
 
257
- # Service Providers
225
+ ## Service Providers
258
226
 
259
227
  To act as a Service Provider which generates SAML Requests and can react to SAML Responses use the
260
228
  excellent [ruby-saml](https://github.com/onelogin/ruby-saml) gem.
261
229
 
262
- # Author
230
+ ## Author
263
231
 
264
232
  Jon Phenow, jon@jphenow.com, jphenow.com, @jphenow
265
233
 
266
234
  Lawrence Pit, lawrence.pit@gmail.com, lawrencepit.com, @lawrencepit
267
235
 
268
- # Copyright
236
+ ## Copyright
269
237
 
270
238
  Copyright (c) 2012 Sport Ngin.
271
239
  Portions Copyright (c) 2010 OneLogin, LLC
data/lib/saml_idp.rb CHANGED
@@ -9,7 +9,7 @@ module SamlIdp
9
9
  require 'saml_idp/metadata_builder'
10
10
  require 'saml_idp/version'
11
11
  require 'saml_idp/fingerprint'
12
- require 'saml_idp/engine' if defined?(::Rails) && Rails::VERSION::MAJOR > 2
12
+ require 'saml_idp/engine' if defined?(::Rails)
13
13
 
14
14
  def self.config
15
15
  @config ||= SamlIdp::Configurator.new
@@ -16,10 +16,26 @@ module SamlIdp
16
16
  attr_accessor :expiry
17
17
  attr_accessor :encryption_opts
18
18
  attr_accessor :session_expiry
19
+ attr_accessor :name_id_formats_opts
20
+ attr_accessor :asserted_attributes_opts
19
21
 
20
22
  delegate :config, to: :SamlIdp
21
23
 
22
- def initialize(reference_id, issuer_uri, principal, audience_uri, saml_request_id, saml_acs_url, raw_algorithm, authn_context_classref, expiry=60*60, encryption_opts=nil, session_expiry=nil)
24
+ def initialize(
25
+ reference_id,
26
+ issuer_uri,
27
+ principal,
28
+ audience_uri,
29
+ saml_request_id,
30
+ saml_acs_url,
31
+ raw_algorithm,
32
+ authn_context_classref,
33
+ expiry=60*60,
34
+ encryption_opts=nil,
35
+ session_expiry=nil,
36
+ name_id_formats_opts = nil,
37
+ asserted_attributes_opts = nil
38
+ )
23
39
  self.reference_id = reference_id
24
40
  self.issuer_uri = issuer_uri
25
41
  self.principal = principal
@@ -31,6 +47,8 @@ module SamlIdp
31
47
  self.expiry = expiry
32
48
  self.encryption_opts = encryption_opts
33
49
  self.session_expiry = session_expiry.nil? ? config.session_expiry : session_expiry
50
+ self.name_id_formats_opts = name_id_formats_opts
51
+ self.asserted_attributes_opts = asserted_attributes_opts
34
52
  end
35
53
 
36
54
  def fresh
@@ -98,7 +116,9 @@ module SamlIdp
98
116
  end
99
117
 
100
118
  def asserted_attributes
101
- if principal.respond_to?(:asserted_attributes)
119
+ if asserted_attributes_opts.present? && !asserted_attributes_opts.empty?
120
+ asserted_attributes_opts
121
+ elsif principal.respond_to?(:asserted_attributes)
102
122
  principal.send(:asserted_attributes)
103
123
  elsif !config.attributes.nil? && !config.attributes.empty?
104
124
  config.attributes
@@ -139,10 +159,15 @@ module SamlIdp
139
159
  private :name_id_getter
140
160
 
141
161
  def name_id_format
142
- @name_id_format ||= NameIdFormatter.new(config.name_id.formats).chosen
162
+ @name_id_format ||= NameIdFormatter.new(name_id_formats).chosen
143
163
  end
144
164
  private :name_id_format
145
165
 
166
+ def name_id_formats
167
+ @name_id_formats ||= (name_id_formats_opts || config.name_id.formats)
168
+ end
169
+ private :name_id_formats
170
+
146
171
  def reference_string
147
172
  "_#{reference_id}"
148
173
  end
@@ -37,11 +37,7 @@ module SamlIdp
37
37
  decode_request(raw_saml_request)
38
38
  return true if valid_saml_request?
39
39
  if defined?(::Rails)
40
- if Rails::VERSION::MAJOR >= 4
41
- head :forbidden
42
- else
43
- render nothing: true, status: :forbidden
44
- end
40
+ head :forbidden
45
41
  end
46
42
  false
47
43
  end
@@ -65,6 +61,8 @@ module SamlIdp
65
61
  session_expiry = opts[:session_expiry]
66
62
  encryption_opts = opts[:encryption] || nil
67
63
  signed_message_opts = opts[:signed_message] || false
64
+ name_id_formats_opts = opts[:name_id_formats] || nil
65
+ asserted_attributes_opts = opts[:attributes] || nil
68
66
 
69
67
  SamlResponse.new(
70
68
  reference_id,
@@ -79,7 +77,9 @@ module SamlIdp
79
77
  expiry,
80
78
  encryption_opts,
81
79
  session_expiry,
82
- signed_message_opts
80
+ signed_message_opts,
81
+ name_id_formats_opts,
82
+ asserted_attributes_opts
83
83
  ).build
84
84
  end
85
85
 
@@ -61,7 +61,6 @@ module SamlIdp
61
61
  key_info.EncryptedKey Id: 'EK', xmlns: 'http://www.w3.org/2001/04/xmlenc#' do |enc_key|
62
62
  enc_key.EncryptionMethod Algorithm: key_transport_ns
63
63
  enc_key.tag! 'ds:KeyInfo', 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#' do |key_info2|
64
- key_info2.tag! 'ds:KeyName'
65
64
  key_info2.tag! 'ds:X509Data' do |x509_data|
66
65
  x509_data.tag! 'ds:X509Certificate' do |x509_cert|
67
66
  x509_cert << cert.to_s.gsub(/-+(BEGIN|END) CERTIFICATE-+/, '')
@@ -18,21 +18,26 @@ module SamlIdp
18
18
  attr_accessor :encryption_opts
19
19
  attr_accessor :session_expiry
20
20
  attr_accessor :signed_message_opts
21
+ attr_accessor :name_id_formats_opts
22
+ attr_accessor :asserted_attributes_opts
21
23
 
22
- def initialize(reference_id,
23
- response_id,
24
- issuer_uri,
25
- principal,
26
- audience_uri,
27
- saml_request_id,
28
- saml_acs_url,
29
- algorithm,
30
- authn_context_classref,
31
- expiry=60*60,
32
- encryption_opts=nil,
33
- session_expiry=0,
34
- signed_message_opts
35
- )
24
+ def initialize(
25
+ reference_id,
26
+ response_id,
27
+ issuer_uri,
28
+ principal,
29
+ audience_uri,
30
+ saml_request_id,
31
+ saml_acs_url,
32
+ algorithm,
33
+ authn_context_classref,
34
+ expiry=60*60,
35
+ encryption_opts=nil,
36
+ session_expiry=0,
37
+ signed_message_opts=false,
38
+ name_id_formats_opts = nil,
39
+ asserted_attributes_opts = nil
40
+ )
36
41
  self.reference_id = reference_id
37
42
  self.response_id = response_id
38
43
  self.issuer_uri = issuer_uri
@@ -48,6 +53,8 @@ module SamlIdp
48
53
  self.encryption_opts = encryption_opts
49
54
  self.session_expiry = session_expiry
50
55
  self.signed_message_opts = signed_message_opts
56
+ self.name_id_formats_opts = name_id_formats_opts
57
+ self.asserted_attributes_opts = asserted_attributes_opts
51
58
  end
52
59
 
53
60
  def build
@@ -88,7 +95,9 @@ module SamlIdp
88
95
  authn_context_classref,
89
96
  expiry,
90
97
  encryption_opts,
91
- session_expiry
98
+ session_expiry,
99
+ name_id_formats_opts,
100
+ asserted_attributes_opts
92
101
  end
93
102
  private :assertion_builder
94
103
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module SamlIdp
3
- VERSION = '0.12.0'
3
+ VERSION = '0.14.0'
4
4
  end
data/saml_idp.gemspec CHANGED
@@ -12,8 +12,8 @@ Gem::Specification.new do |s|
12
12
  s.summary = 'SAML Indentity Provider for Ruby'
13
13
  s.description = 'SAML IdP (Identity Provider) Library for Ruby'
14
14
  s.date = Time.now.utc.strftime("%Y-%m-%d")
15
- s.files = Dir['app/**/*', 'lib/**/*', 'LICENSE', 'README.md', 'Gemfile', 'saml_idp.gemspec']
16
- s.required_ruby_version = '>= 2.2'
15
+ s.files = Dir['lib/**/*', 'LICENSE', 'README.md', 'Gemfile', 'saml_idp.gemspec']
16
+ s.required_ruby_version = '>= 2.5'
17
17
  s.license = 'MIT'
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -43,19 +43,20 @@ Encrypted Assertions require the xmlenc gem. See the example in the Controller
43
43
  section of the README.
44
44
  INST
45
45
 
46
- s.add_dependency('activesupport', '>= 3.2')
46
+ s.add_dependency('activesupport', '>= 5.2')
47
47
  s.add_dependency('builder', '>= 3.0')
48
48
  s.add_dependency('nokogiri', '>= 1.6.2')
49
+ s.add_dependency('xmlenc', '>= 0.7.1')
50
+ s.add_dependency('rexml')
49
51
 
50
52
  s.add_development_dependency('rake')
51
53
  s.add_development_dependency('simplecov')
52
54
  s.add_development_dependency('rspec', '>= 3.7.0')
53
55
  s.add_development_dependency('ruby-saml', '>= 1.7.2')
54
- s.add_development_dependency('rails', '>= 3.2')
55
- s.add_development_dependency('activeresource', '>= 3.2')
56
+ s.add_development_dependency('rails', '>= 5.2')
57
+ s.add_development_dependency('activeresource', '>= 5.1')
56
58
  s.add_development_dependency('capybara', '>= 2.16')
57
59
  s.add_development_dependency('timecop', '>= 0.8')
58
- s.add_development_dependency('xmlenc', '>= 0.6.4')
59
60
  s.add_development_dependency('appraisal')
60
61
  s.add_development_dependency('byebug')
61
62
  end
@@ -19,6 +19,9 @@ module SamlIdp
19
19
  key_transport: 'rsa-oaep-mgf1p',
20
20
  }
21
21
  end
22
+ let(:session_expiry) { nil }
23
+ let(:name_id_formats_opt) { nil }
24
+ let(:asserted_attributes_opt) { nil }
22
25
  subject { described_class.new(
23
26
  reference_id,
24
27
  issuer_uri,
@@ -103,6 +106,76 @@ module SamlIdp
103
106
  expect(encrypted_xml).to_not match(audience_uri)
104
107
  end
105
108
 
109
+ describe "with name_id_formats_opt" do
110
+ let(:name_id_formats_opt) {
111
+ {
112
+ persistent: -> (principal) {
113
+ principal.unique_identifier
114
+ }
115
+ }
116
+ }
117
+ it "delegates name_id_formats to opts" do
118
+ UserWithUniqueId = Struct.new(:unique_identifier, :email, :asserted_attributes)
119
+ principal = UserWithUniqueId.new('unique_identifier_123456', 'foo@example.com', { emailAddress: { getter: :email } })
120
+ builder = described_class.new(
121
+ reference_id,
122
+ issuer_uri,
123
+ principal,
124
+ audience_uri,
125
+ saml_request_id,
126
+ saml_acs_url,
127
+ algorithm,
128
+ authn_context_classref,
129
+ expiry,
130
+ encryption_opts,
131
+ session_expiry,
132
+ name_id_formats_opt,
133
+ asserted_attributes_opt
134
+ )
135
+ Timecop.travel(Time.zone.local(2010, 6, 1, 13, 0, 0)) do
136
+ expect(builder.raw).to eq("<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:2.0:nameid-format:persistent\">unique_identifier_123456</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><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement><AttributeStatement><Attribute Name=\"emailAddress\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"emailAddress\"><AttributeValue>foo@example.com</AttributeValue></Attribute></AttributeStatement></Assertion>")
137
+ end
138
+ end
139
+ end
140
+
141
+ describe "with asserted_attributes_opt" do
142
+ let(:asserted_attributes_opt) {
143
+ {
144
+ 'GivenName' => {
145
+ getter: :first_name
146
+ },
147
+ 'SurName' => {
148
+ getter: -> (principal) {
149
+ principal.last_name
150
+ }
151
+ }
152
+ }
153
+ }
154
+
155
+ it "delegates asserted_attributes to opts" do
156
+ UserWithName = Struct.new(:email, :first_name, :last_name)
157
+ principal = UserWithName.new('foo@example.com', 'George', 'Washington')
158
+ builder = described_class.new(
159
+ reference_id,
160
+ issuer_uri,
161
+ principal,
162
+ audience_uri,
163
+ saml_request_id,
164
+ saml_acs_url,
165
+ algorithm,
166
+ authn_context_classref,
167
+ expiry,
168
+ encryption_opts,
169
+ session_expiry,
170
+ name_id_formats_opt,
171
+ asserted_attributes_opt
172
+ )
173
+ Timecop.travel(Time.zone.local(2010, 6, 1, 13, 0, 0)) do
174
+ expect(builder.raw).to eq("<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><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement><AttributeStatement><Attribute Name=\"GivenName\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"GivenName\"><AttributeValue>George</AttributeValue></Attribute><Attribute Name=\"SurName\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"SurName\"><AttributeValue>Washington</AttributeValue></Attribute></AttributeStatement></Assertion>")
175
+ end
176
+ end
177
+ end
178
+
106
179
  describe "with custom session_expiry configuration" do
107
180
  let(:config) { SamlIdp::Configurator.new }
108
181
  before do
@@ -2,11 +2,7 @@ class SamlController < ApplicationController
2
2
 
3
3
  def consume
4
4
  response = OneLogin::RubySaml::Response.new(params[:SAMLResponse])
5
- if Gem::Requirement.new('< 4.1') =~ Gem::Version.new(Rails.version)
6
- render :text => response.name_id
7
- else
8
- render :plain => response.name_id
9
- end
5
+ render :plain => response.name_id
10
6
  end
11
7
 
12
8
  end
@@ -1,9 +1,48 @@
1
- class SamlIdpController < SamlIdp::IdpController
2
- def idp_authenticate(email, password)
3
- { :email => email }
4
- end
5
-
6
- def idp_make_saml_response(user)
7
- encode_response(user[:email])
8
- end
1
+ class SamlIdpController < ApplicationController
2
+ include SamlIdp::Controller
3
+
4
+ before_action :validate_saml_request, only: [:new, :create, :logout]
5
+
6
+ def new
7
+ render template: "saml_idp/idp/new"
8
+ end
9
+
10
+ def show
11
+ render xml: SamlIdp.metadata.signed
12
+ end
13
+
14
+ def create
15
+ unless params[:email].blank? && params[:password].blank?
16
+ person = idp_authenticate(params[:email], params[:password])
17
+ if person.nil?
18
+ @saml_idp_fail_msg = "Incorrect email or password."
19
+ else
20
+ @saml_response = idp_make_saml_response(person)
21
+ render :template => "saml_idp/idp/saml_post", :layout => false
22
+ return
23
+ end
24
+ end
25
+ render :template => "saml_idp/idp/new"
26
+ end
27
+
28
+ def logout
29
+ idp_logout
30
+ @saml_response = idp_make_saml_response(nil)
31
+ render :template => "saml_idp/idp/saml_post", :layout => false
32
+ end
33
+
34
+ def idp_logout
35
+ raise NotImplementedError
36
+ end
37
+ private :idp_logout
38
+
39
+ def idp_authenticate(email, password)
40
+ { :email => email }
41
+ end
42
+ protected :idp_authenticate
43
+
44
+ def idp_make_saml_response(person)
45
+ encode_response(person[:email])
46
+ end
47
+ protected :idp_make_saml_response
9
48
  end
@@ -1,22 +1,18 @@
1
1
  <% if @saml_idp_fail_msg %>
2
2
  <div id="saml_idp_fail_msg" class="flash error"><%= @saml_idp_fail_msg %></div>
3
3
  <% end %>
4
-
5
4
  <%= form_tag do %>
6
5
  <%= hidden_field_tag("SAMLRequest", params[:SAMLRequest]) %>
7
6
  <%= hidden_field_tag("RelayState", params[:RelayState]) %>
8
-
9
7
  <p>
10
8
  <%= label_tag :email %>
11
9
  <%= email_field_tag :email, params[:email], :autocapitalize => "off", :autocorrect => "off", :autofocus => "autofocus", :spellcheck => "false", :size => 30, :class => "email_pwd txt" %>
12
10
  </p>
13
-
14
11
  <p>
15
12
  <%= label_tag :password %>
16
13
  <%= password_field_tag :password, params[:password], :autocapitalize => "off", :autocorrect => "off", :spellcheck => "false", :size => 30, :class => "email_pwd txt" %>
17
14
  </p>
18
-
19
15
  <p>
20
16
  <%= submit_tag "Sign in", :class => "button big blueish" %>
21
17
  </p>
22
- <% end %>
18
+ <% end %>
@@ -11,4 +11,4 @@
11
11
  <%= submit_tag "Submit" %>
12
12
  <% end %>
13
13
  </body>
14
- </html>
14
+ </html>
@@ -29,4 +29,6 @@ RailsApp::Application.configure do
29
29
  # Log the query plan for queries taking more than this (works
30
30
  # with SQLite, MySQL, and PostgreSQL)
31
31
  #config.active_record.auto_explain_threshold_in_seconds = 0.5
32
+
33
+ config.hosts << "foo.example.com" if config.respond_to?(:hosts)
32
34
  end
data/spec/spec_helper.rb CHANGED
@@ -67,4 +67,4 @@ end
67
67
  SamlIdp::Default::SERVICE_PROVIDER[:metadata_url] = 'https://example.com/meta'
68
68
  SamlIdp::Default::SERVICE_PROVIDER[:response_hosts] = ['foo.example.com']
69
69
  SamlIdp::Default::SERVICE_PROVIDER[:assertion_consumer_logout_service_url] = 'https://foo.example.com/saml/logout'
70
- Capybara.default_host = "https://app.example.com"
70
+ Capybara.default_host = "https://foo.example.com"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saml_idp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Phenow
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-20 00:00:00.000000000 Z
11
+ date: 2021-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.2'
19
+ version: '5.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '3.2'
26
+ version: '5.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: builder
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.6.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: xmlenc
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 0.7.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 0.7.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: rexml
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: rake
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -114,28 +142,28 @@ dependencies:
114
142
  requirements:
115
143
  - - ">="
116
144
  - !ruby/object:Gem::Version
117
- version: '3.2'
145
+ version: '5.2'
118
146
  type: :development
119
147
  prerelease: false
120
148
  version_requirements: !ruby/object:Gem::Requirement
121
149
  requirements:
122
150
  - - ">="
123
151
  - !ruby/object:Gem::Version
124
- version: '3.2'
152
+ version: '5.2'
125
153
  - !ruby/object:Gem::Dependency
126
154
  name: activeresource
127
155
  requirement: !ruby/object:Gem::Requirement
128
156
  requirements:
129
157
  - - ">="
130
158
  - !ruby/object:Gem::Version
131
- version: '3.2'
159
+ version: '5.1'
132
160
  type: :development
133
161
  prerelease: false
134
162
  version_requirements: !ruby/object:Gem::Requirement
135
163
  requirements:
136
164
  - - ">="
137
165
  - !ruby/object:Gem::Version
138
- version: '3.2'
166
+ version: '5.1'
139
167
  - !ruby/object:Gem::Dependency
140
168
  name: capybara
141
169
  requirement: !ruby/object:Gem::Requirement
@@ -164,20 +192,6 @@ dependencies:
164
192
  - - ">="
165
193
  - !ruby/object:Gem::Version
166
194
  version: '0.8'
167
- - !ruby/object:Gem::Dependency
168
- name: xmlenc
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - ">="
172
- - !ruby/object:Gem::Version
173
- version: 0.6.4
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - ">="
179
- - !ruby/object:Gem::Version
180
- version: 0.6.4
181
195
  - !ruby/object:Gem::Dependency
182
196
  name: appraisal
183
197
  requirement: !ruby/object:Gem::Requirement
@@ -215,9 +229,6 @@ files:
215
229
  - Gemfile
216
230
  - LICENSE
217
231
  - README.md
218
- - app/controllers/saml_idp/idp_controller.rb
219
- - app/views/saml_idp/idp/new.html.erb
220
- - app/views/saml_idp/idp/saml_post.html.erb
221
232
  - lib/saml_idp.rb
222
233
  - lib/saml_idp/algorithmable.rb
223
234
  - lib/saml_idp/assertion_builder.rb
@@ -281,6 +292,8 @@ files:
281
292
  - spec/rails_app/app/mailers/.gitkeep
282
293
  - spec/rails_app/app/models/.gitkeep
283
294
  - spec/rails_app/app/views/layouts/application.html.erb
295
+ - spec/rails_app/app/views/saml_idp/idp/new.html.erb
296
+ - spec/rails_app/app/views/saml_idp/idp/saml_post.html.erb
284
297
  - spec/rails_app/config.ru
285
298
  - spec/rails_app/config/application.rb
286
299
  - spec/rails_app/config/boot.rb
@@ -352,7 +365,7 @@ metadata:
352
365
  homepage_uri: https://github.com/saml-idp/saml_idp
353
366
  source_code_uri: https://github.com/saml-idp/saml_idp
354
367
  bug_tracker_uri: https://github.com/saml-idp/saml_idp/issues
355
- documentation_uri: http://rdoc.info/gems/saml_idp/0.12.0
368
+ documentation_uri: http://rdoc.info/gems/saml_idp/0.14.0
356
369
  post_install_message: |
357
370
  If you're just recently updating saml_idp - please be aware we've changed the default
358
371
  certificate. See the PR and a description of why we've done this here:
@@ -376,7 +389,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
376
389
  requirements:
377
390
  - - ">="
378
391
  - !ruby/object:Gem::Version
379
- version: '2.2'
392
+ version: '2.5'
380
393
  required_rubygems_version: !ruby/object:Gem::Requirement
381
394
  requirements:
382
395
  - - ">="
@@ -422,6 +435,8 @@ test_files:
422
435
  - spec/rails_app/app/mailers/.gitkeep
423
436
  - spec/rails_app/app/models/.gitkeep
424
437
  - spec/rails_app/app/views/layouts/application.html.erb
438
+ - spec/rails_app/app/views/saml_idp/idp/new.html.erb
439
+ - spec/rails_app/app/views/saml_idp/idp/saml_post.html.erb
425
440
  - spec/rails_app/config.ru
426
441
  - spec/rails_app/config/application.rb
427
442
  - spec/rails_app/config/boot.rb
@@ -1,59 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module SamlIdp
4
- class IdpController < ActionController::Base
5
- include SamlIdp::Controller
6
-
7
- unloadable unless Rails::VERSION::MAJOR >= 4
8
- protect_from_forgery
9
-
10
- if Rails::VERSION::MAJOR >= 4
11
- before_action :validate_saml_request, only: [:new, :create]
12
- else
13
- before_filter :validate_saml_request, only: [:new, :create]
14
- end
15
-
16
- def new
17
- render template: "saml_idp/idp/new"
18
- end
19
-
20
- def show
21
- render xml: SamlIdp.metadata.signed
22
- end
23
-
24
- def create
25
- unless params[:email].blank? && params[:password].blank?
26
- person = idp_authenticate(params[:email], params[:password])
27
- if person.nil?
28
- @saml_idp_fail_msg = "Incorrect email or password."
29
- else
30
- @saml_response = idp_make_saml_response(person)
31
- render :template => "saml_idp/idp/saml_post", :layout => false
32
- return
33
- end
34
- end
35
- render :template => "saml_idp/idp/new"
36
- end
37
-
38
- def logout
39
- idp_logout
40
- @saml_response = idp_make_saml_response(nil)
41
- render :template => "saml_idp/idp/saml_post", :layout => false
42
- end
43
-
44
- def idp_logout
45
- raise NotImplementedError
46
- end
47
- private :idp_logout
48
-
49
- def idp_authenticate(email, password)
50
- raise NotImplementedError
51
- end
52
- protected :idp_authenticate
53
-
54
- def idp_make_saml_response(person)
55
- raise NotImplementedError
56
- end
57
- protected :idp_make_saml_response
58
- end
59
- end