omniauth-tent 0.1.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/.gitignore +18 -0
- data/.kick +17 -0
- data/.travis.yml +9 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +52 -0
- data/Rakefile +8 -0
- data/lib/omniauth-tent.rb +2 -0
- data/lib/omniauth-tent/version.rb +5 -0
- data/lib/omniauth/strategies/tent.rb +220 -0
- data/omniauth-tent.gemspec +31 -0
- data/spec/omniauth/strategies/tent_spec.rb +177 -0
- data/spec/spec_helper.rb +19 -0
- metadata +220 -0
data/.gitignore
ADDED
data/.kick
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
process do |files|
|
2
|
+
test_files = files.take_and_map do |file|
|
3
|
+
if file =~ %r{^(spec|lib)/(.+?)(_spec)?\.rb$}
|
4
|
+
path = $2
|
5
|
+
if file =~ %r{^spec/spec_helper\.rb}
|
6
|
+
""
|
7
|
+
else
|
8
|
+
"spec/#{path}_spec.rb"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
rspec_command = "time bundle exec rspec --tty --color"
|
13
|
+
res = execute "#{rspec_command} #{test_files.join(' ')}" unless test_files.empty?
|
14
|
+
if res.exit_code == 0 && test_files != [""]
|
15
|
+
execute rspec_command
|
16
|
+
end
|
17
|
+
end
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in omniauth-tent.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
gem 'tent-client', :git => 'git://github.com/tent/tent-client-ruby.git', :branch => 'master'
|
7
|
+
gem 'faraday_middleware-multi_json', :git => 'git://github.com/jvatic/faraday_middleware-multi_json.git', :branch => :master
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Jesse Stuart
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
[](http://travis-ci.org/tent/omniauth-tent)
|
2
|
+
|
3
|
+
# Omniauth::Tent
|
4
|
+
|
5
|
+
Omniauth strategy for Tent.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'omniauth-tent'
|
12
|
+
|
13
|
+
|
14
|
+
## Usage
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
use OmniAuth::Builder do
|
18
|
+
provider :tent, options
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
Available options (see [the Tent.io docs for details](http://tent.io/docs/app-auth))
|
23
|
+
|
24
|
+
| Option | Required | Description |
|
25
|
+
| ------ | -------- | ----------- |
|
26
|
+
| get_app | Yes | Should be a lambda (or anything which responds to `call`) returning either an existing app attributes hash or `nil`. The entity URI will be passed in as a single argument. |
|
27
|
+
| on_app_created | No | Should respond to `call`. Gets called with Hashie::Mash representation of app when created |
|
28
|
+
| app | Yes | `name`, `icon`, `url`, `description`, `scopes`, and `redirect_uris` |
|
29
|
+
| profile_info_types | Yes | Array of profile info type URIs your app wants access to |
|
30
|
+
| post_types | Yes | Array of post type URIs your app wants access to |
|
31
|
+
| notification_url | Yes | URL for receiving notifications |
|
32
|
+
|
33
|
+
## Testing
|
34
|
+
|
35
|
+
bundle exec kicker
|
36
|
+
|
37
|
+
OR
|
38
|
+
|
39
|
+
bundle exec rspec
|
40
|
+
|
41
|
+
## Contributing
|
42
|
+
|
43
|
+
Here are some tasks that need to be done:
|
44
|
+
|
45
|
+
- Handle being passed an 'error' param in the callback_phase
|
46
|
+
- Find bugs and fix them
|
47
|
+
|
48
|
+
1. Fork it
|
49
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
50
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
51
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
52
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
require 'omniauth'
|
2
|
+
require 'tent-client'
|
3
|
+
require 'uri'
|
4
|
+
require 'securerandom'
|
5
|
+
|
6
|
+
module OmniAuth
|
7
|
+
module Strategies
|
8
|
+
class Tent
|
9
|
+
include OmniAuth::Strategy
|
10
|
+
|
11
|
+
Error = Class.new(StandardError)
|
12
|
+
AppCreateFailure = Class.new(Error)
|
13
|
+
AppLookupFailure = Class.new(Error)
|
14
|
+
AppAuthorizationCreateFailure = Class.new(Error)
|
15
|
+
StateMissmatchError = Class.new(Error)
|
16
|
+
|
17
|
+
option :get_app, lambda { |entity| }
|
18
|
+
option :on_app_created, lambda { |app| }
|
19
|
+
option :app, { :name => nil, :icon => nil, :description => nil, :scopes => {}, :redirect_uris => nil }
|
20
|
+
option :profile_info_types, []
|
21
|
+
option :post_types, []
|
22
|
+
option :notification_url, ""
|
23
|
+
|
24
|
+
def request_params
|
25
|
+
Hashie::Mash.new(request.params)
|
26
|
+
end
|
27
|
+
|
28
|
+
def request_phase
|
29
|
+
if request.post? && request_params.entity
|
30
|
+
delete_state!
|
31
|
+
set_state(:entity, ensure_entity_has_scheme(request_params.entity))
|
32
|
+
perform_discovery!
|
33
|
+
find_or_create_app!
|
34
|
+
build_uri_and_redirect!
|
35
|
+
else
|
36
|
+
OmniAuth::Form.build(
|
37
|
+
:title => (options[:title] || "Entity Verification")
|
38
|
+
) do |f|
|
39
|
+
f.text_field 'Entity', 'entity'
|
40
|
+
end.to_response
|
41
|
+
end
|
42
|
+
rescue AppCreateFailure => e
|
43
|
+
fail!(:app_create_failure, e)
|
44
|
+
rescue AppLookupFailure => e
|
45
|
+
fail!(:app_lookup_failure, e)
|
46
|
+
rescue => e
|
47
|
+
fail!(:unknown_error, e)
|
48
|
+
end
|
49
|
+
|
50
|
+
def callback_phase
|
51
|
+
verify_state!
|
52
|
+
create_app_authorization!
|
53
|
+
build_auth_hash!
|
54
|
+
delete_state!
|
55
|
+
call_app!
|
56
|
+
rescue AppAuthorizationCreateFailure => e
|
57
|
+
fail!(:app_auth_create_failure, e)
|
58
|
+
rescue StateMissmatchError => e
|
59
|
+
fail!(:state_missmatch, e)
|
60
|
+
rescue => e
|
61
|
+
fail!(:unknown_error, e)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def ensure_entity_has_scheme(entity_uri)
|
67
|
+
if entity_uri =~ %r{^[a-z]{3,}?://}
|
68
|
+
entity_uri
|
69
|
+
else
|
70
|
+
"https://#{entity_uri}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def set_state(key, val)
|
75
|
+
session["omniauth.#{key}"] = val
|
76
|
+
val
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_state(key)
|
80
|
+
session["omniauth.#{key}"]
|
81
|
+
end
|
82
|
+
|
83
|
+
def perform_discovery!
|
84
|
+
client = ::TentClient.new
|
85
|
+
@profile, @server_url = client.discover(request[:entity]).get_profile
|
86
|
+
set_state(:server_url, @server_url)
|
87
|
+
set_state(:profile, @profile)
|
88
|
+
end
|
89
|
+
|
90
|
+
def find_or_create_app!
|
91
|
+
app = Hashie::Mash.new(options[:get_app].call(get_state(:entity)) || {})
|
92
|
+
client = ::TentClient.new(get_state(:server_url), :mac_key_id => app[:mac_key_id],
|
93
|
+
:mac_key => app[:mac_key],
|
94
|
+
:mac_algorithm => app[:mac_algorithm])
|
95
|
+
if app[:id]
|
96
|
+
res = client.app.get(app[:id])
|
97
|
+
if res.body.kind_of?(::String)
|
98
|
+
if res.status == 403
|
99
|
+
create_app and return
|
100
|
+
else
|
101
|
+
raise AppLookupFailure.new(res.inspect)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
set_app(app)
|
105
|
+
else
|
106
|
+
create_app
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def set_app(app)
|
111
|
+
set_state(:app, app)
|
112
|
+
end
|
113
|
+
|
114
|
+
def get_app
|
115
|
+
@tent_app ||= Hashie::Mash.new(get_state(:app) || {})
|
116
|
+
end
|
117
|
+
|
118
|
+
def create_app
|
119
|
+
client = ::TentClient.new(@server_url)
|
120
|
+
app_attrs = {
|
121
|
+
:name => options.app.name,
|
122
|
+
:description => options.app.description,
|
123
|
+
:scopes => options.app.scopes,
|
124
|
+
:icon => options.app.icon,
|
125
|
+
:url => options.app.url,
|
126
|
+
:redirect_uris => options.app.redirect_uris || [callback_url]
|
127
|
+
}
|
128
|
+
|
129
|
+
res = client.app.create(app_attrs)
|
130
|
+
|
131
|
+
if (app = res.body) && !app.kind_of?(::String)
|
132
|
+
set_app(app)
|
133
|
+
options[:on_app_created].call(get_app)
|
134
|
+
else
|
135
|
+
raise AppCreateFailure.new(res.inspect)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def build_uri_and_redirect!
|
140
|
+
auth_uri = URI(@server_url + '/oauth/authorize')
|
141
|
+
params = {
|
142
|
+
:client_id => get_app[:id],
|
143
|
+
:tent_profile_info_types => options[:profile_info_types].join(','),
|
144
|
+
:tent_post_types => options[:post_types].join(','),
|
145
|
+
:tent_notification_url => options[:notification_url],
|
146
|
+
:scope => options[:app][:scopes].keys.join(','),
|
147
|
+
:redirect_uri => callback_url,
|
148
|
+
}
|
149
|
+
params[:state] = set_state(:state, SecureRandom.hex(32))
|
150
|
+
build_uri_params!(auth_uri, params)
|
151
|
+
|
152
|
+
redirect auth_uri.to_s
|
153
|
+
end
|
154
|
+
|
155
|
+
def build_uri_params!(uri, params)
|
156
|
+
uri.query = params.inject([]) do |memo, (key,val)|
|
157
|
+
memo << "#{key}=#{URI.encode_www_form_component(val)}"
|
158
|
+
memo
|
159
|
+
end.join('&')
|
160
|
+
end
|
161
|
+
|
162
|
+
def verify_state!
|
163
|
+
raise StateMissmatchError unless get_state(:state) == request.params['state']
|
164
|
+
end
|
165
|
+
|
166
|
+
def create_app_authorization!
|
167
|
+
client = ::TentClient.new(get_state(:server_url), :mac_key_id => get_app[:mac_key_id],
|
168
|
+
:mac_key => get_app[:mac_key],
|
169
|
+
:mac_algorithm => get_app[:mac_algorithm])
|
170
|
+
res = client.app.authorization.create(get_app[:id], :code => request.params['code'])
|
171
|
+
raise AppAuthorizationCreateFailure.new(res.body) if res.body.kind_of?(String)
|
172
|
+
@app_authorization = Hashie::Mash.new(res.body)
|
173
|
+
end
|
174
|
+
|
175
|
+
def build_auth_hash!
|
176
|
+
env['omniauth.auth'] = Hashie::Mash.new(
|
177
|
+
:provider => 'tent',
|
178
|
+
:uid => get_state(:entity),
|
179
|
+
:info => extract_basic_info(get_state(:profile)),
|
180
|
+
:credentials => {
|
181
|
+
:token => @app_authorization.access_token,
|
182
|
+
:secret => @app_authorization.mac_key
|
183
|
+
},
|
184
|
+
:extra => {
|
185
|
+
:raw_info => {
|
186
|
+
:profile => get_state(:profile),
|
187
|
+
:app_authorization => @app_authorization,
|
188
|
+
:app => get_app
|
189
|
+
},
|
190
|
+
:credentials => {
|
191
|
+
:mac_key_id => @app_authorization.access_token,
|
192
|
+
:mac_key => @app_authorization.mac_key,
|
193
|
+
:mac_algorithm => @app_authorization.mac_algorithm,
|
194
|
+
:token_type => @app_authorization.token_type
|
195
|
+
}
|
196
|
+
}
|
197
|
+
)
|
198
|
+
end
|
199
|
+
|
200
|
+
def delete_state!
|
201
|
+
%w( entity app server_url profile state ).each do |key|
|
202
|
+
session.delete("omniauth.#{key}")
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def extract_basic_info(profile)
|
207
|
+
basic_info = Hashie::Mash.new(profile.inject({}) { |memo, (k,v)|
|
208
|
+
memo = v if k =~ %r{^https://tent.io/types/info/basic}
|
209
|
+
memo
|
210
|
+
})
|
211
|
+
|
212
|
+
{
|
213
|
+
:name => basic_info.name,
|
214
|
+
:nickname => get_state(:entity),
|
215
|
+
:image => basic_info.avatar
|
216
|
+
}
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'omniauth-tent/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "omniauth-tent"
|
8
|
+
gem.version = Omniauth::Tent::VERSION
|
9
|
+
gem.authors = ["Jesse Stuart"]
|
10
|
+
gem.email = ["jessestuart@gmail.com"]
|
11
|
+
gem.description = %q{Omniauth Strategy for Tent}
|
12
|
+
gem.summary = %q{Omniauth Strategy for Tent}
|
13
|
+
gem.homepage = "https://github.com/tent/omniauth-tent"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_runtime_dependency 'omniauth', '~> 1.1.1'
|
21
|
+
gem.add_runtime_dependency 'tent-client'
|
22
|
+
|
23
|
+
gem.add_development_dependency 'rspec', '~> 2.7'
|
24
|
+
gem.add_development_dependency 'rack-test'
|
25
|
+
gem.add_development_dependency 'webmock'
|
26
|
+
gem.add_development_dependency 'bundler'
|
27
|
+
gem.add_development_dependency 'rake'
|
28
|
+
gem.add_development_dependency 'kicker'
|
29
|
+
gem.add_development_dependency 'mocha'
|
30
|
+
gem.add_development_dependency 'yajl-ruby'
|
31
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yajl'
|
3
|
+
|
4
|
+
describe OmniAuth::Strategies::Tent do
|
5
|
+
attr_accessor :app
|
6
|
+
|
7
|
+
# customize rack app for testing, if block is given, reverts to default
|
8
|
+
# rack app after testing is done
|
9
|
+
def set_app!(tent_options = {})
|
10
|
+
old_app = self.app
|
11
|
+
self.app = Rack::Builder.app do
|
12
|
+
use OmniAuth::Strategies::Tent, tent_options
|
13
|
+
run lambda{|env| [404, {'env' => env}, ["HELLO!"]]}
|
14
|
+
end
|
15
|
+
if block_given?
|
16
|
+
yield
|
17
|
+
self.app = old_app
|
18
|
+
end
|
19
|
+
self.app
|
20
|
+
end
|
21
|
+
|
22
|
+
before(:all) do
|
23
|
+
set_app!
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:env) { {'rack.session' => {}} }
|
27
|
+
|
28
|
+
let(:fresh_strategy){ Class.new(OmniAuth::Strategies::Tent) }
|
29
|
+
|
30
|
+
let(:tent_entity) { 'https://example.com' }
|
31
|
+
let(:tent_server) { "#{tent_entity}/tent" }
|
32
|
+
let(:app_id) { 'app-id-123' }
|
33
|
+
let(:link_header) { %(<#{tent_server}/profile>; rel="%s") % TentClient::PROFILE_REL }
|
34
|
+
let(:tent_profile) { %({"https://tent.io/types/info/core/v0.1.0":{"licenses":["http://creativecommons.org/licenses/by/3.0/"],"entity":"#{tent_entity}","servers":["#{tent_server}"]}}) }
|
35
|
+
let(:app_attrs) do
|
36
|
+
{
|
37
|
+
:name => "Example App",
|
38
|
+
:description => "An example app",
|
39
|
+
:scopes => { "read_posts" => "Display your posts feed" },
|
40
|
+
:icon => "https://example.com/icon.png",
|
41
|
+
:url => "https://example.com"
|
42
|
+
}
|
43
|
+
end
|
44
|
+
let(:app_json) { %({"name":"Example App","id":"#{app_id}"}) }
|
45
|
+
let(:app_hash) { Yajl::Parser.parse(app_json) }
|
46
|
+
|
47
|
+
let(:token_code) { 'token-code-123abc' }
|
48
|
+
|
49
|
+
let(:access_token) { 'access-token-abc' }
|
50
|
+
let(:mac_key) { 'mac-key-312' }
|
51
|
+
let(:mac_algorithm) { 'hmac-sha-256' }
|
52
|
+
let(:token_type) { 'mac' }
|
53
|
+
let(:app_auth_json) { %({"access_token":"#{access_token}","mac_key":"#{mac_key}","mac_algorithm":"#{mac_algorithm}","token_type":"#{token_type}") }
|
54
|
+
|
55
|
+
let(:stub_head_discovery!) do
|
56
|
+
stub_request(:head, tent_entity).to_return(:headers => {'Link' => link_header})
|
57
|
+
end
|
58
|
+
|
59
|
+
let(:stub_profile_discovery!) do
|
60
|
+
stub_request(:get, "#{tent_server}/profile").to_return(:body => tent_profile, :headers => {'Content-Type' => TentClient::MEDIA_TYPE})
|
61
|
+
end
|
62
|
+
|
63
|
+
let(:stub_app_lookup_success!) do
|
64
|
+
stub_request(:get, "#{tent_server}/apps/#{app_id}").to_return(:body => app_json, :headers => { 'Content-Type' => TentClient::MEDIA_TYPE })
|
65
|
+
end
|
66
|
+
|
67
|
+
let(:stub_app_lookup_failure!) do
|
68
|
+
stub_request(:get, "#{tent_server}/apps/#{app_id}").to_return(:status => 404)
|
69
|
+
end
|
70
|
+
|
71
|
+
let(:stub_app_create_success!) do
|
72
|
+
stub_request(:post, "#{tent_server}/apps").to_return(:body => app_json, :headers => { 'Content-Type' => TentClient::MEDIA_TYPE })
|
73
|
+
end
|
74
|
+
|
75
|
+
let(:stub_app_auth_create_success!) do
|
76
|
+
stub_request(:post, "#{tent_server}/apps/#{app_id}/authorizations").with(:body => Yajl::Encoder.encode({ :code => token_code })).to_return(:body => app_auth_json, :headers => { 'Content-Type' => TentClient::MEDIA_TYPE })
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '#request_phase' do
|
80
|
+
it 'should display a form' do
|
81
|
+
get '/auth/tent', {}, env
|
82
|
+
expect(last_response.body).to be_include("<form")
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should perform disvocery' do
|
86
|
+
head_stub = stub_head_discovery!
|
87
|
+
profile_stub = stub_profile_discovery!
|
88
|
+
|
89
|
+
described_class.any_instance.stubs(:find_or_create_app!)
|
90
|
+
described_class.any_instance.stubs(:build_uri_and_redirect!).returns([200, {}, []])
|
91
|
+
|
92
|
+
post '/auth/tent', { :entity => tent_entity }, env
|
93
|
+
|
94
|
+
expect(head_stub).to have_been_requested
|
95
|
+
expect(profile_stub).to have_been_requested
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should create app if app_id callback returns nil' do
|
99
|
+
set_app!(:app => app_attrs)
|
100
|
+
stub_head_discovery!
|
101
|
+
stub_profile_discovery!
|
102
|
+
app_create_stub = stub_app_create_success!
|
103
|
+
described_class.any_instance.stubs(:build_uri_and_redirect!).returns([200, {}, []])
|
104
|
+
|
105
|
+
post '/auth/tent', { :entity => tent_entity }, env
|
106
|
+
|
107
|
+
expect(app_create_stub).to have_been_requested
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should create app if not found' do
|
111
|
+
set_app!(:app => app_attrs, :on_app_created => mock(:call))
|
112
|
+
stub_head_discovery!
|
113
|
+
stub_profile_discovery!
|
114
|
+
stub_app_lookup_failure!
|
115
|
+
app_create_stub = stub_app_create_success!
|
116
|
+
described_class.any_instance.stubs(:build_uri_and_redirect!).returns([200, {}, []])
|
117
|
+
|
118
|
+
post '/auth/tent', { :entity => tent_entity }, env
|
119
|
+
|
120
|
+
expect(app_create_stub).to have_been_requested
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should build uri and redirect' do
|
124
|
+
set_app!(:get_app => lambda { |entity| app_hash })
|
125
|
+
stub_head_discovery!
|
126
|
+
stub_profile_discovery!
|
127
|
+
stub_app_lookup_success!
|
128
|
+
|
129
|
+
post '/auth/tent', { :entity => tent_entity }, env
|
130
|
+
|
131
|
+
expect(last_response.status).to eq(302)
|
132
|
+
expect(last_response.headers["Location"]).to match(%r{^#{tent_server}/oauth/authorize})
|
133
|
+
expect(last_response.headers["Location"]).to match(%r{client_id=#{app_id}})
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe '#callback_phase' do
|
138
|
+
it 'should create app authorization' do
|
139
|
+
state = 'abcdef'
|
140
|
+
session = {}
|
141
|
+
session['omniauth.state'] = state
|
142
|
+
session['omniauth.entity'] = tent_entity
|
143
|
+
session['omniauth.server_url'] = tent_server
|
144
|
+
session['omniauth.app'] = { :id => app_id }
|
145
|
+
session['omniauth.profile'] = Yajl::Parser.parse(tent_profile)
|
146
|
+
|
147
|
+
stub_app_auth_create_success!
|
148
|
+
stub_app_lookup_success!
|
149
|
+
|
150
|
+
get '/auth/tent/callback', { :code => token_code, :state => state }, 'rack.session' => session
|
151
|
+
|
152
|
+
auth_hash = last_response['env']['omniauth.auth']
|
153
|
+
expect(auth_hash).to_not be_nil
|
154
|
+
expect(auth_hash.provider).to eq('tent')
|
155
|
+
expect(auth_hash.uid).to eq(tent_entity)
|
156
|
+
expect(auth_hash.info).to eq(Hashie::Mash.new(
|
157
|
+
:name => nil,
|
158
|
+
:nickname => tent_entity,
|
159
|
+
:image => nil
|
160
|
+
))
|
161
|
+
expect(auth_hash.credentials).to eq(Hashie::Mash.new(
|
162
|
+
:token => access_token,
|
163
|
+
:secret => mac_key
|
164
|
+
))
|
165
|
+
expect(auth_hash.extra.raw_info.profile).to eq(Hashie::Mash.new(Yajl::Parser.parse(tent_profile)))
|
166
|
+
expect(auth_hash.extra.credentials).to eq(Hashie::Mash.new(
|
167
|
+
:mac_key_id => access_token,
|
168
|
+
:mac_key => mac_key,
|
169
|
+
:mac_algorithm => mac_algorithm,
|
170
|
+
:token_type => token_type
|
171
|
+
))
|
172
|
+
expect(auth_hash.extra.raw_info.app_authorization).to eq(Hashie::Mash.new(
|
173
|
+
Yajl::Parser.parse(app_auth_json)
|
174
|
+
))
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'mocha_standalone'
|
6
|
+
require 'rack/test'
|
7
|
+
require 'webmock/rspec'
|
8
|
+
require 'omniauth-tent'
|
9
|
+
|
10
|
+
Dir["#{File.dirname(__FILE__)}/support/*.rb"].each { |f| require f }
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.include WebMock::API
|
14
|
+
config.include Rack::Test::Methods
|
15
|
+
config.extend OmniAuth::Test::StrategyMacros, :type => :strategy
|
16
|
+
config.mock_with :mocha
|
17
|
+
end
|
18
|
+
|
19
|
+
OmniAuth.config.logger = Logger.new(File.join(File.dirname(__FILE__), '..', 'log', 'test.log'))
|
metadata
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: omniauth-tent
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jesse Stuart
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-10-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: omniauth
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.1.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.1.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: tent-client
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.7'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.7'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rack-test
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: webmock
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: bundler
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: rake
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: kicker
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: mocha
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: yajl-ruby
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
description: Omniauth Strategy for Tent
|
175
|
+
email:
|
176
|
+
- jessestuart@gmail.com
|
177
|
+
executables: []
|
178
|
+
extensions: []
|
179
|
+
extra_rdoc_files: []
|
180
|
+
files:
|
181
|
+
- .gitignore
|
182
|
+
- .kick
|
183
|
+
- .travis.yml
|
184
|
+
- Gemfile
|
185
|
+
- LICENSE.txt
|
186
|
+
- README.md
|
187
|
+
- Rakefile
|
188
|
+
- lib/omniauth-tent.rb
|
189
|
+
- lib/omniauth-tent/version.rb
|
190
|
+
- lib/omniauth/strategies/tent.rb
|
191
|
+
- omniauth-tent.gemspec
|
192
|
+
- spec/omniauth/strategies/tent_spec.rb
|
193
|
+
- spec/spec_helper.rb
|
194
|
+
homepage: https://github.com/tent/omniauth-tent
|
195
|
+
licenses: []
|
196
|
+
post_install_message:
|
197
|
+
rdoc_options: []
|
198
|
+
require_paths:
|
199
|
+
- lib
|
200
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
207
|
+
none: false
|
208
|
+
requirements:
|
209
|
+
- - ! '>='
|
210
|
+
- !ruby/object:Gem::Version
|
211
|
+
version: '0'
|
212
|
+
requirements: []
|
213
|
+
rubyforge_project:
|
214
|
+
rubygems_version: 1.8.23
|
215
|
+
signing_key:
|
216
|
+
specification_version: 3
|
217
|
+
summary: Omniauth Strategy for Tent
|
218
|
+
test_files:
|
219
|
+
- spec/omniauth/strategies/tent_spec.rb
|
220
|
+
- spec/spec_helper.rb
|