gds-sso 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,161 @@
1
+ require_relative '../spec_helper'
2
+
3
+ include Rack::Test
4
+
5
+ describe "authenticating with sign-on-o-tron" do
6
+
7
+ describe "when not signed in" do
8
+
9
+ describe "a protected page" do
10
+ it "redirects to /auth/gds" do
11
+ get "/"
12
+
13
+ response.code.should == "302"
14
+ response.location.should == "http://www.example.com/auth/gds"
15
+ end
16
+ end
17
+
18
+ describe "/auth/gds" do
19
+ it "redirects to signonotron2" do
20
+ get "/auth/gds"
21
+
22
+ response.code.should == "302"
23
+ response.location.should =~ /^http:\/\/localhost:3000\/oauth\/authorize/
24
+ end
25
+
26
+ it "authenticates with a username and password and redirects back to the app" do
27
+ get "/auth/gds"
28
+
29
+ uri = URI.parse(response.location)
30
+ auth_path = uri.path + '?' + uri.query
31
+
32
+ client_cookies = response.headers['Set-Cookie'].split('; ')[0]
33
+
34
+ @signonotron = Faraday.new(:url => "#{uri.scheme}://#{uri.host}:#{uri.port}") do |builder|
35
+ builder.request :url_encoded
36
+ builder.adapter :net_http
37
+ end
38
+
39
+ authz_return_location = do_auth_request(auth_path)
40
+
41
+ return_path = authz_return_location.path + '?' + (authz_return_location.query || '')
42
+
43
+ get return_path, { }, { 'Cookie' => client_cookies }
44
+
45
+ puts "HANDLE AUTH RESULT\n====================\n"
46
+ puts response.headers
47
+
48
+ # resp = Net::HTTP.get_response( URI::parse(response.location) )
49
+ # location = resp["location"]
50
+
51
+ # visit location
52
+ # puts page.current_uri
53
+
54
+ # fill_in "user_email", :with => "foo@example.com"
55
+ # fill_in "user_password", :with => "this is an example for the test"
56
+ # click_button "Sign in"
57
+ end
58
+
59
+ def do_auth_request(auth_path)
60
+ auth_request = @signonotron.get(auth_path)
61
+
62
+ debug_request('Auth Request', 'GET', auth_path, auth_request, '')
63
+
64
+ sign_in_location = URI.parse(auth_request.headers['location']).path
65
+ cookie = auth_request.headers['Set-Cookie'].split('; ')[0]
66
+
67
+ return do_sign_in_request(sign_in_location, cookie)
68
+ end
69
+
70
+ def do_sign_in_request(sign_in_location, cookie)
71
+ sign_in_request = @signonotron.get do |req|
72
+ req.url sign_in_location
73
+ req.headers['Cookie'] = cookie
74
+ end
75
+
76
+ debug_request('Sign In', 'GET', sign_in_location, sign_in_request, cookie)
77
+
78
+ cookie = sign_in_request.headers['Set-Cookie'].split('; ')[0]
79
+ sign_in_location = Nokogiri.parse(sign_in_request.body).xpath("//form").first.attributes['action'].text
80
+ authenticity_token = Nokogiri.parse(sign_in_request.body).xpath("//input[@name='authenticity_token']").first.attributes['value'].text
81
+
82
+ return do_sign_in_post(sign_in_location, cookie, authenticity_token)
83
+ end
84
+
85
+ def do_sign_in_post(sign_in_location, cookie, authenticity_token)
86
+
87
+ sign_in_post = @signonotron.post do |req|
88
+ req.url sign_in_location
89
+ req.body = { :user => { :email => 'foo@example.com', :password => 'this is an example for the test' }, :authenticity_token => authenticity_token }
90
+ req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
91
+ req.headers['Cookie'] = cookie
92
+ end
93
+
94
+ debug_request('Sign In', 'POST', sign_in_location, sign_in_post, cookie)
95
+
96
+ cookie = sign_in_post.headers['Set-Cookie'].split('; ')[0]
97
+ authz_location = URI.parse(sign_in_post.headers['location'])
98
+
99
+ return do_authz_request(authz_location, cookie)
100
+ end
101
+
102
+ def do_authz_request(authz_location, cookie)
103
+ authz_request = @signonotron.get do |req|
104
+ req.url authz_location
105
+ req.headers['Content-Type'] = 'text/html'
106
+ req.headers['Cookie'] = cookie
107
+ end
108
+
109
+ debug_request('Authz', 'GET', authz_location, authz_request, cookie)
110
+
111
+ cookie = authz_request.headers['Set-Cookie'].split('; ')[0]
112
+
113
+ if authz_request.headers['location']
114
+ puts "RETURNING #{authz_request.headers['location']}"
115
+ return URI.parse(authz_request.headers['location'])
116
+ else
117
+ authz_confirm_location = Nokogiri.parse(authz_request.body).xpath("//form").first.attributes['action'].text
118
+ authenticity_token = Nokogiri.parse(authz_request.body).xpath("//input[@name='authenticity_token']").first.attributes['value'].text
119
+
120
+ return do_authz_confirm_post(authz_confirm_location, cookie, authenticity_token)
121
+ end
122
+ end
123
+
124
+ def do_authz_confirm_post(authz_confirm_location, cookie, authenticity_token)
125
+ authz_confirm_request = @signonotron.post do |req|
126
+ req.url authz_confirm_location
127
+ req.body = { :commit => 'Authorize', :authenticity_token => authenticity_token,
128
+ :authorization => {
129
+ :client_id => '1acd5e4e34a0e15225383bbbdf88cf95f8efd82664f3811b917869cc51c8f449',
130
+ :redirect_uri => 'http://www.example.com/auth/gds/callback',
131
+ :response_type => 'code',
132
+ :state => '',
133
+ :scope => ''
134
+ }
135
+ }
136
+ req.headers['Cookie'] = cookie
137
+ end
138
+
139
+ debug_request('Authz Confirm', 'POST', authz_confirm_location, authz_confirm_request, cookie)
140
+
141
+ cookie = authz_confirm_request.headers['Set-Cookie'].split('; ')[0]
142
+
143
+ puts "RETURNING #{authz_confirm_request.headers['location']}"
144
+ return URI.parse(authz_confirm_request.headers['location'])
145
+ end
146
+
147
+ def debug_request(name, method, path, response, cookie)
148
+ puts "#{name} REQUEST RESULT:\n=========================\n"
149
+ puts "#{method} #{path}"
150
+ puts "#{cookie}"
151
+
152
+ puts "\n\n"
153
+
154
+ puts response.headers.inspect
155
+ puts response.body
156
+ end
157
+ end
158
+
159
+ end
160
+
161
+ end
@@ -28,10 +28,10 @@ describe "Integration of client using GDS-SSO with signonotron" do
28
28
  visit "http://#{@client_host}/restricted"
29
29
  page.should have_content("Sign in")
30
30
  fill_in "Email", :with => "test@example-client.com"
31
- fill_in "Password", :with => "q1w2e3r4t5y6u7i8o9p0"
31
+ fill_in "Passphrase", :with => "q1w2e3r4t5y6u7i8o9p0"
32
32
  click_on "Sign in"
33
33
 
34
- click_on "Authorize"
34
+ click_authorize
35
35
 
36
36
  page.should have_content('restricted kablooie')
37
37
  end
@@ -40,9 +40,10 @@ describe "Integration of client using GDS-SSO with signonotron" do
40
40
  # First we login to authorise the app
41
41
  visit "http://#{@client_host}/restricted"
42
42
  fill_in "Email", :with => "test@example-client.com"
43
- fill_in "Password", :with => "q1w2e3r4t5y6u7i8o9p0"
43
+ fill_in "Passphrase", :with => "q1w2e3r4t5y6u7i8o9p0"
44
44
  click_on "Sign in"
45
- click_on "Authorize"
45
+
46
+ click_authorize
46
47
 
47
48
  # At this point the app should be authorised, we reset the session to simulate a new browser visit.
48
49
  reset_session!
@@ -51,7 +52,7 @@ describe "Integration of client using GDS-SSO with signonotron" do
51
52
  visit "http://#{@client_host}/restricted"
52
53
  page.should have_content("Sign in")
53
54
  fill_in "Email", :with => "test@example-client.com"
54
- fill_in "Password", :with => "q1w2e3r4t5y6u7i8o9p0"
55
+ fill_in "Passphrase", :with => "q1w2e3r4t5y6u7i8o9p0"
55
56
  click_on "Sign in"
56
57
 
57
58
  page.should have_content('restricted kablooie')
@@ -74,4 +75,8 @@ describe "Integration of client using GDS-SSO with signonotron" do
74
75
  page.should have_content('restricted kablooie')
75
76
  end
76
77
  end
78
+
79
+ def click_authorize
80
+ click_on( page.has_button?("Authorize") ? "Authorize" : "Yes" )
81
+ end
77
82
  end
@@ -7,7 +7,7 @@ module Signonotron2IntegrationHelpers
7
7
  puts "Waiting for signonotron to start at #{url}"
8
8
  while ! signonotron_started?(url)
9
9
  print '.'
10
- if retries > 10
10
+ if retries > 20
11
11
  raise "Signonotron is not running at #{url}. Please start with 'bundle exec rake signonotron:start'. Under jenkins this should have been run automatically"
12
12
  end
13
13
  retries += 1
@@ -28,8 +28,11 @@ module Signonotron2IntegrationHelpers
28
28
 
29
29
  def load_signonotron_fixture
30
30
  fixtures_path = Pathname.new(File.join(File.dirname(__FILE__), '../fixtures/integration'))
31
- db = YAML.load_file(fixtures_path + 'signonotron2_database.yml')['test']
32
- cmd = "mysql -u#{db['username']} -p#{db['password']} #{db['database']} < #{fixtures_path + 'signonotron2.sql'}"
31
+ app = ENV['SIGNONOTRON_VERSION'] == "1" ? "sign-on-o-tron" : "signonotron2"
32
+ path_to_app = Rails.root.join('..','..','tmp',app)
33
+
34
+ db = YAML.load_file(fixtures_path + "#{app}_database.yml")['test']
35
+ cmd = "sqlite3 #{path_to_app + db['database']} < #{fixtures_path + "#{app}.sql"}"
33
36
  system cmd or raise "Error loading signonotron fixture"
34
37
  end
35
38
  end
@@ -1,24 +1,30 @@
1
1
  namespace :signonotron do
2
2
  desc "Start signonotron (for integration tests)"
3
3
  task :start => :stop do
4
+
5
+ @app_to_launch = ENV['SIGNONOTRON_VERSION'] == "1" ? "sign-on-o-tron" : "signonotron2"
6
+
7
+ puts "ENV version: #{ENV['SIGNONOTRON_VERSION']}"
8
+ puts "Launching: #{@app_to_launch}"
9
+
4
10
  gem_root = Pathname.new(File.dirname(__FILE__)) + '..' + '..'
5
11
  FileUtils.mkdir_p(gem_root + 'tmp')
6
12
  Dir.chdir gem_root + 'tmp' do
7
- if File.exist? "signonotron2"
8
- Dir.chdir "signonotron2" do
13
+ if File.exist? @app_to_launch
14
+ Dir.chdir @app_to_launch do
9
15
  puts `git clean -fdx`
10
16
  puts `git fetch origin`
11
17
  puts `git reset --hard origin/master`
12
18
  end
13
19
  else
14
- puts `git clone git@github.com:alphagov/signonotron2`
20
+ puts `git clone git@github.com:alphagov/#{@app_to_launch}`
15
21
  end
16
22
  end
17
23
 
18
- Dir.chdir gem_root + 'tmp' + 'signonotron2' do
24
+ Dir.chdir gem_root + 'tmp' + @app_to_launch do
19
25
  env_stuff = '/usr/bin/env -u BUNDLE_GEMFILE -u BUNDLE_BIN_PATH -u RUBYOPT -u GEM_HOME -u GEM_PATH RAILS_ENV=test'
20
- puts `#{env_stuff} bundle install --path=#{gem_root + 'tmp' + 'signonotron2_bundle'}`
21
- FileUtils.cp gem_root.join('spec', 'fixtures', 'integration', 'signonotron2_database.yml'), File.join('config', 'database.yml')
26
+ puts `#{env_stuff} bundle install --path=#{gem_root + 'tmp' + "#{@app_to_launch}_bundle"}`
27
+ FileUtils.cp gem_root.join('spec', 'fixtures', 'integration', "#{@app_to_launch}_database.yml"), File.join('config', 'database.yml')
22
28
  puts `#{env_stuff} bundle exec rake db:drop db:create db:schema:load`
23
29
 
24
30
  puts "Starting signonotron instance in the background"
@@ -7,14 +7,14 @@ class TestOmniAuthStrategy < Test::Unit::TestCase
7
7
  def setup
8
8
  @app = stub("app")
9
9
  @strategy = OmniAuth::Strategies::Gds.new(@app, :gds, 'client_id', 'client_secret')
10
- @strategy.stubs(:fetch_user_data).returns({
10
+ @strategy.stubs(:fetch_user_data).returns({ 'user' => {
11
11
  'uid' => 'abcde',
12
12
  'version' => 1,
13
13
  'name' => 'Matt Patterson',
14
14
  'email' => 'matt@alphagov.co.uk',
15
15
  'github' => 'fidothe',
16
16
  'twitter' => 'fidothe'
17
- }.to_json)
17
+ }}.to_json)
18
18
  end
19
19
 
20
20
  def test_build_auth_hash_returns_name_and_email
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: gds-sso
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.5.0
5
+ version: 0.5.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Matt Patterson
@@ -11,11 +11,10 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2012-04-20 00:00:00 Z
14
+ date: 2012-04-24 00:00:00 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rails
18
- prerelease: false
19
18
  requirement: &id001 !ruby/object:Gem::Requirement
20
19
  none: false
21
20
  requirements:
@@ -23,10 +22,10 @@ dependencies:
23
22
  - !ruby/object:Gem::Version
24
23
  version: 3.0.0
25
24
  type: :runtime
25
+ prerelease: false
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: warden
29
- prerelease: false
30
29
  requirement: &id002 !ruby/object:Gem::Requirement
31
30
  none: false
32
31
  requirements:
@@ -34,10 +33,10 @@ dependencies:
34
33
  - !ruby/object:Gem::Version
35
34
  version: 1.0.6
36
35
  type: :runtime
36
+ prerelease: false
37
37
  version_requirements: *id002
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: oauth2
40
- prerelease: false
41
40
  requirement: &id003 !ruby/object:Gem::Requirement
42
41
  none: false
43
42
  requirements:
@@ -45,10 +44,10 @@ dependencies:
45
44
  - !ruby/object:Gem::Version
46
45
  version: 0.5.2
47
46
  type: :runtime
47
+ prerelease: false
48
48
  version_requirements: *id003
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: oa-oauth
51
- prerelease: false
52
51
  requirement: &id004 !ruby/object:Gem::Requirement
53
52
  none: false
54
53
  requirements:
@@ -56,10 +55,10 @@ dependencies:
56
55
  - !ruby/object:Gem::Version
57
56
  version: 0.3.2
58
57
  type: :runtime
58
+ prerelease: false
59
59
  version_requirements: *id004
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: oa-core
62
- prerelease: false
63
62
  requirement: &id005 !ruby/object:Gem::Requirement
64
63
  none: false
65
64
  requirements:
@@ -67,10 +66,10 @@ dependencies:
67
66
  - !ruby/object:Gem::Version
68
67
  version: 0.3.2
69
68
  type: :runtime
69
+ prerelease: false
70
70
  version_requirements: *id005
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: rack-accept
73
- prerelease: false
74
73
  requirement: &id006 !ruby/object:Gem::Requirement
75
74
  none: false
76
75
  requirements:
@@ -78,10 +77,10 @@ dependencies:
78
77
  - !ruby/object:Gem::Version
79
78
  version: 0.4.4
80
79
  type: :runtime
80
+ prerelease: false
81
81
  version_requirements: *id006
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: rack
84
- prerelease: false
85
84
  requirement: &id007 !ruby/object:Gem::Requirement
86
85
  none: false
87
86
  requirements:
@@ -89,10 +88,10 @@ dependencies:
89
88
  - !ruby/object:Gem::Version
90
89
  version: 1.3.5
91
90
  type: :runtime
91
+ prerelease: false
92
92
  version_requirements: *id007
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: rake
95
- prerelease: false
96
95
  requirement: &id008 !ruby/object:Gem::Requirement
97
96
  none: false
98
97
  requirements:
@@ -100,10 +99,10 @@ dependencies:
100
99
  - !ruby/object:Gem::Version
101
100
  version: 0.9.2
102
101
  type: :development
102
+ prerelease: false
103
103
  version_requirements: *id008
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: mocha
106
- prerelease: false
107
106
  requirement: &id009 !ruby/object:Gem::Requirement
108
107
  none: false
109
108
  requirements:
@@ -111,10 +110,10 @@ dependencies:
111
110
  - !ruby/object:Gem::Version
112
111
  version: 0.9.0
113
112
  type: :development
113
+ prerelease: false
114
114
  version_requirements: *id009
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: capybara
117
- prerelease: false
118
117
  requirement: &id010 !ruby/object:Gem::Requirement
119
118
  none: false
120
119
  requirements:
@@ -122,10 +121,10 @@ dependencies:
122
121
  - !ruby/object:Gem::Version
123
122
  version: 1.1.2
124
123
  type: :development
124
+ prerelease: false
125
125
  version_requirements: *id010
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: rspec-rails
128
- prerelease: false
129
128
  requirement: &id011 !ruby/object:Gem::Requirement
130
129
  none: false
131
130
  requirements:
@@ -133,10 +132,10 @@ dependencies:
133
132
  - !ruby/object:Gem::Version
134
133
  version: 2.9.0
135
134
  type: :development
135
+ prerelease: false
136
136
  version_requirements: *id011
137
137
  - !ruby/object:Gem::Dependency
138
138
  name: capybara-mechanize
139
- prerelease: false
140
139
  requirement: &id012 !ruby/object:Gem::Requirement
141
140
  none: false
142
141
  requirements:
@@ -144,10 +143,10 @@ dependencies:
144
143
  - !ruby/object:Gem::Version
145
144
  version: 0.3.0
146
145
  type: :development
146
+ prerelease: false
147
147
  version_requirements: *id012
148
148
  - !ruby/object:Gem::Dependency
149
149
  name: combustion
150
- prerelease: false
151
150
  requirement: &id013 !ruby/object:Gem::Requirement
152
151
  none: false
153
152
  requirements:
@@ -155,6 +154,7 @@ dependencies:
155
154
  - !ruby/object:Gem::Version
156
155
  version: 0.3.1
157
156
  type: :development
157
+ prerelease: false
158
158
  version_requirements: *id013
159
159
  description: Client for GDS' OAuth 2-based SSO
160
160
  email:
@@ -185,6 +185,8 @@ files:
185
185
  - test/omniauth_strategy_test.rb
186
186
  - test/test_helper.rb
187
187
  - test/user_test.rb
188
+ - spec/fixtures/integration/sign-on-o-tron.sql
189
+ - spec/fixtures/integration/sign-on-o-tron_database.yml
188
190
  - spec/fixtures/integration/signonotron2.sql
189
191
  - spec/fixtures/integration/signonotron2_database.yml
190
192
  - spec/internal/app/controllers/application_controller.rb
@@ -196,6 +198,7 @@ files:
196
198
  - spec/internal/db/schema.rb
197
199
  - spec/internal/log/test.log
198
200
  - spec/internal/public/favicon.ico
201
+ - spec/requests/authentication_soot2.rb
199
202
  - spec/requests/end_to_end_spec.rb
200
203
  - spec/spec_helper.rb
201
204
  - spec/support/signonotron2_integration_helpers.rb
@@ -213,12 +216,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
213
216
  requirements:
214
217
  - - ">="
215
218
  - !ruby/object:Gem::Version
219
+ hash: -1832840277119493135
220
+ segments:
221
+ - 0
216
222
  version: "0"
217
223
  required_rubygems_version: !ruby/object:Gem::Requirement
218
224
  none: false
219
225
  requirements:
220
226
  - - ">="
221
227
  - !ruby/object:Gem::Version
228
+ hash: -1832840277119493135
229
+ segments:
230
+ - 0
222
231
  version: "0"
223
232
  requirements: []
224
233
 
@@ -232,6 +241,8 @@ test_files:
232
241
  - test/omniauth_strategy_test.rb
233
242
  - test/test_helper.rb
234
243
  - test/user_test.rb
244
+ - spec/fixtures/integration/sign-on-o-tron.sql
245
+ - spec/fixtures/integration/sign-on-o-tron_database.yml
235
246
  - spec/fixtures/integration/signonotron2.sql
236
247
  - spec/fixtures/integration/signonotron2_database.yml
237
248
  - spec/internal/app/controllers/application_controller.rb
@@ -243,6 +254,7 @@ test_files:
243
254
  - spec/internal/db/schema.rb
244
255
  - spec/internal/log/test.log
245
256
  - spec/internal/public/favicon.ico
257
+ - spec/requests/authentication_soot2.rb
246
258
  - spec/requests/end_to_end_spec.rb
247
259
  - spec/spec_helper.rb
248
260
  - spec/support/signonotron2_integration_helpers.rb