warden_omniauth-jonrowe 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ bin/
6
+ vendor/
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source :gemcutter
2
+
3
+ # Specify your gem's dependencies in warden_omniauth.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'nanotest'
8
+ gem 'nanotest_extensions'
9
+ gem 'rack-test', :require => 'rack/test'
10
+ gem 'rake'
11
+ gem 'omniauth-twitter'
12
+ gem 'omniauth-facebook'
13
+ gem 'omniauth-google-oauth2'
14
+ end
data/README.markdown ADDED
@@ -0,0 +1,93 @@
1
+ # Warden OmniAuth
2
+
3
+ OmniAuth is a pretty aweome library. If you haven't checked it out yet, you really should. This is a simple wrapper for OmniAuth so that it can be used from a warden project. It sorts storing the user into the sesion, redirection on callbacks etc.
4
+
5
+ With it, you can make use of any of the [OmniAuth](http://github.com/intridea/omniauth) authentication library. This provides some great external authentication mechanisms.
6
+
7
+ Warden provides a consistent interface for projects, engines, and arbitrary rack applicaitons. The benefit of warden, is that you do not need to know what the host application considers authentication to use it. It also provides a way to store the user in the session etc.
8
+
9
+ By using WardenOmniAuth, you can make use of any of the OmniAuth authentication mechanisms in your host application, and any rack middleware or applications can just continue using warden without change.
10
+
11
+ This is also usable in the [Devise](http://github.com/plataformatec/devise) Rails Engine
12
+ ## Usage (Rack)
13
+
14
+ <pre><code>use OmniAuth::Builer do
15
+ # setup omniauth
16
+ end
17
+
18
+ use Warden::Manager do |config|
19
+ # setup warden configuration
20
+ end
21
+
22
+ use WardenOmniAuth do |config|
23
+ config.redirect\_after\_callback = "/redirect/path" # default "/"
24
+ end
25
+
26
+ run MyApp
27
+ </code></pre>
28
+
29
+ ## Usage (Devise)
30
+
31
+ <pre><code># config/initializer.rb
32
+ Devise.setup do |config|
33
+ config.warden do |manager|
34
+ [:omni\_twitter, :omni\_facebook, :omni\_github].each do |strategy|
35
+ manager.default\_strategies(:scope => :user).unshift strategy
36
+ end
37
+ end
38
+ </code></pre>
39
+
40
+ This will add the stratgeies to the normal devise user login for github, then facebook, then twitter.
41
+
42
+ # Dealing with callbacks
43
+
44
+ OmniAuth uses callbacks to give you the user object, WardenOmniAuth provides a way to store this into the session
45
+
46
+ By default, it grabs just _user\\info_, _uid_, _credentials_, _provider_ as a hash in the session.
47
+
48
+ If you want to customise this you can do:
49
+
50
+ <pre><code>
51
+ WardenOmniAuth.on\_callback do |user|
52
+ # all callbacks will go here by default
53
+ end
54
+ </code></pre>
55
+
56
+ Whatever you return from the block is the user that's made available in warden.
57
+
58
+ ## Dealing with each kind of callback
59
+
60
+ <pre><code>
61
+ use WardenOmniAuth do |config|
62
+ Warden::Strategies[:omni\_twitter].on_callback do |user|
63
+ # do stuff to get a user and return it from the block
64
+ end
65
+
66
+ Warden::Strategies[:omni\_facebook].on_callback do |user|
67
+ # do stuff to get a user for a facebook user
68
+ end
69
+ end
70
+ </code></pre>
71
+
72
+ This will use a specific callback to get the user, or fallback if nothing specific has been defined.
73
+
74
+
75
+ # Why? (Gimmie an alternative)
76
+
77
+ Because I wanted to see how it would be to integrate this strategy into warden. Turns out to be pretty simple, but there's nothing stopping you from just providing a callback directly for OmniAuth.
78
+
79
+ However, it's just as simple to provide endpoints for OmniAuth callbacks. (Assuming you already have warden setup in your app)
80
+
81
+ Example:
82
+
83
+ <pre><code>
84
+ get "/auth/twitter/callback" do
85
+ user = munge_user_from_env(env['rack.auth'])
86
+ warden.set_user user
87
+ redirect "/somewhere"
88
+ end
89
+ </code></pre>
90
+
91
+ You can see from this small snippet, that you don't really need this library, just define your callbacks to set the user and you're done.
92
+
93
+ Rack is a beautiful thing!
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ # --------------------------------------------------
5
+ # Tests
6
+ # --------------------------------------------------
7
+ namespace(:test) do
8
+
9
+ desc "run framework compatibility tests"
10
+ task(:all) do
11
+ Dir['test/test_*.rb'].each do |path|
12
+ cmd = "ruby -rubygems -I.:lib -I.:test/test_helper.rb #{path}"
13
+ puts(cmd) if ENV['VERBOSE']
14
+ system(cmd)
15
+ end
16
+ end
17
+ end
18
+
19
+ task :default => ["test:all"]
@@ -0,0 +1,42 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), "..", "..", "lib")
2
+
3
+ require 'warden_omniauth'
4
+
5
+ Warden::Manager.serialize_into_session do |user|
6
+ user
7
+ end
8
+
9
+ Warden::Manager.serialize_from_session do |user|
10
+ user
11
+ end
12
+
13
+ app = lambda do |e|
14
+ request = Rack::Request.new(e)
15
+ if request.path =~ /logout/
16
+ e['warden'].logout
17
+ r = Rack::Response.new
18
+ r.redirect("/")
19
+ r.finish
20
+ else
21
+ e['warden'].authenticate!
22
+ Rack::Response.new(e['warden'].user.inspect).finish
23
+ end
24
+ end
25
+
26
+ failure = lambda{|e| Rack::Resposne.new("Can't login", 401).finish }
27
+
28
+ use Rack::Session::Cookie
29
+
30
+ use Warden::Manager do |config|
31
+ config.failure_app = failure
32
+ config.default_strategies :omni_twitter
33
+ end
34
+
35
+ use OmniAuth::Strategies::Twitter, key, sekrit
36
+ use WardenOmniAuth do |config|
37
+ config.redirect_after_callback = "/foo/bar"
38
+ end
39
+
40
+
41
+ run app
42
+
@@ -0,0 +1,149 @@
1
+ require 'warden'
2
+ require 'omniauth'
3
+
4
+ class WardenOmniAuth
5
+ DEFAULT_CALLBACK = lambda do |user|
6
+ u = {}
7
+ u[:info] = user['info']
8
+ u[:uid] = user['uid']
9
+ u[:credentials] = user['credentials']
10
+ u[:provider] = user['provider']
11
+ u
12
+ end
13
+
14
+ SCOPE_KEY = 'warden_omni_auth.scope'
15
+ SESSION_KEY = 'rack.session'
16
+
17
+ # Setup a callback to transform the user from the omni user hash
18
+ # to what you want warden to store as the user object
19
+ # @example
20
+ # WardenOmniAuth.on_callback do |omni_user|
21
+ # User.find_or_create_by_uid(omni_user['uid'])
22
+ # end
23
+ def self.on_callback(&blk)
24
+ @on_callback = blk if blk
25
+ @on_callback || DEFAULT_CALLBACK
26
+ end
27
+
28
+ # Create a warden strategy to wrap an OmniAuth strategy
29
+ # @param name - The name of the omniauth strategy
30
+ # @example
31
+ # WardenOmniAuth.setup_strategies(:twitter, :facebook)
32
+ def self.setup_strategies(*names)
33
+ names.map do |name|
34
+ full_name = :"omni_#{name}"
35
+ unless Warden::Strategies[full_name]
36
+ klass = Class.new(WardenOmniAuth::Strategy)
37
+ klass.omni_name = name
38
+ Warden::Strategies.add(full_name, klass)
39
+ end
40
+ Warden::Strategies[full_name]
41
+ end
42
+ end
43
+
44
+ # The base omniauth warden strategy. This is inherited for each
45
+ # omniauth strategy
46
+ class Strategy < Warden::Strategies::Base
47
+ # make a specific callback for this strategy
48
+ def self.on_callback(&blk)
49
+ @on_callback = blk if blk
50
+ @on_callback || WardenOmniAuth.on_callback
51
+ end
52
+
53
+ # The name of the OmniAuth strategy to map to
54
+ def self.omni_name=(name)
55
+ @omni_name = name
56
+ end
57
+
58
+ # The name of the OmniAuth strategy to map to
59
+ def self.omni_name
60
+ @omni_name
61
+ end
62
+
63
+ def authenticate!
64
+ session = env[SESSION_KEY]
65
+ session[SCOPE_KEY] = scope
66
+
67
+ # set the user if one exists
68
+ # otherwise, redirect for authentication
69
+ if user = env['omniauth.auth']
70
+ success! self.class.on_callback[user]
71
+ else
72
+ path_prefix = OmniAuth::Configuration.instance.path_prefix
73
+ redirect! File.join(path_prefix, self.class.omni_name)
74
+ end
75
+ end
76
+ end
77
+
78
+ # Pulled from extlib
79
+ # Convert to snake case.
80
+ #
81
+ # "FooBar".snake_case #=> "foo_bar"
82
+ # "HeadlineCNNNews".snake_case #=> "headline_cnn_news"
83
+ # "CNN".snake_case #=> "cnn"
84
+ #
85
+ # @return [String] Receiver converted to snake case.
86
+ #
87
+ # @api public
88
+ def self.snake_case(string)
89
+ return string.downcase if string.match(/\A[A-Z]+\z/)
90
+ string.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
91
+ gsub(/([a-z])([A-Z])/, '\1_\2').
92
+ downcase
93
+ end
94
+
95
+ def initialize(app)
96
+ # setup the warden strategies to wrap the omniauth ones
97
+ names = OmniAuth::Strategies.constants.map do |konstant|
98
+ name = WardenOmniAuth.snake_case(konstant.to_s)
99
+ end
100
+ WardenOmniAuth.setup_strategies(*names)
101
+ yield self if block_given?
102
+ @app = app
103
+ end
104
+
105
+ # redirect after a callback
106
+ def redirect_after_callback=(path)
107
+ @redirect_after_callback_path = path
108
+ end
109
+
110
+
111
+ def redirect_after_callback_path
112
+ @redirect_after_callback_path ||= "/"
113
+ end
114
+
115
+ def call(env)
116
+ request = Rack::Request.new(env)
117
+ prefix = OmniAuth::Configuration.instance.path_prefix
118
+ if request.path =~ /^#{prefix}\/(.+?)\/callback$/i
119
+ strategy_name = $1
120
+ strategy = Warden::Strategies._strategies.keys.detect{|k| k.to_s == "omni_#{strategy_name}"}
121
+
122
+ if !strategy
123
+ Rack::Response.new("Unknown Handler", 401).finish
124
+ else
125
+ # Warden needs to use a hashie for looking up scope
126
+ # and strategy names
127
+ session = env[SESSION_KEY]
128
+ scope = session[SCOPE_KEY]
129
+ if scope.nil? || scope.to_s.length < 100 # have to protect against symbols :(. need a hashie
130
+ args = [strategy]
131
+ args << {:scope => scope.to_sym} if scope
132
+ response = Rack::Response.new
133
+ if env['warden'].authenticate? *args
134
+ response.redirect(redirect_after_callback_path)
135
+ response.finish
136
+ else
137
+ auth_path = request.path.gsub(/\/callback$/, "")
138
+ response.redirect(auth_path)
139
+ response.finish
140
+ end
141
+ else
142
+ Rack::Response.new("Bad Session", 400).finish
143
+ end
144
+ end
145
+ else
146
+ @app.call(env)
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,3 @@
1
+ module WardenOmniauth
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,42 @@
1
+ require 'nanotest'
2
+ require 'nanotest/contexts'
3
+ require 'rack'
4
+ require 'rack/test'
5
+ include Nanotest
6
+ include Nanotest::Contexts
7
+
8
+ require 'warden_omniauth'
9
+
10
+ Warden::Manager.serialize_into_session do |user|
11
+ user
12
+ end
13
+
14
+ Warden::Manager.serialize_from_session do |user|
15
+ user
16
+ end
17
+
18
+
19
+ module MyHelpers
20
+ def app
21
+ @app || create_app{|e| Rack::Response.new("OK").finish }
22
+ end
23
+
24
+ def create_app(&blk)
25
+ failure = lambda{|e| Rack::Response.new("Can't login", 401).finish }
26
+ builder = Rack::Builder.new do
27
+ use Warden::Manager do |config|
28
+ config.failure_app = failure
29
+ config.default_strategies :omni_twitter
30
+ end
31
+
32
+ #use OmniAuth::Strategies::Twitter, key, sekrit
33
+
34
+ use WardenOmniAuth do |config|
35
+ $omni_auth = config
36
+ config.redirect_after_callback = "/redirect/path"
37
+ end
38
+ run blk
39
+ end.to_app
40
+ end
41
+ end
42
+
@@ -0,0 +1,145 @@
1
+ require 'test/test_helper'
2
+ require 'omniauth-twitter'
3
+ require 'omniauth-facebook'
4
+ require 'omniauth-google-oauth2'
5
+
6
+ # WardenOmniauth
7
+ context do
8
+ include Rack::Test::Methods
9
+ include MyHelpers
10
+ teardown { @_rack_mock_sessions = nil; @_rack_test_sessions = nil }
11
+
12
+ # shoudl setup all the omni auth strategies
13
+ test do
14
+ app
15
+ OmniAuth::Strategies.constants.each do |klass|
16
+ name = WardenOmniAuth.snake_case(klass.to_s)
17
+ assert { Warden::Strategies[:"omni_#{name}"] != nil }
18
+ assert { Warden::Strategies[:"omni_#{name}"].superclass == WardenOmniAuth::Strategy }
19
+ end
20
+ end
21
+
22
+ # test the middleware in a request
23
+ context do
24
+ setup do
25
+ @app = create_app do |e|
26
+ request = Rack::Request.new(e)
27
+ Rack::Response.new(request.path).finish
28
+ end
29
+ end
30
+ teardown { @_rack_mock_sessions = nil; @_rack_test_sessions = nil }
31
+
32
+ # test that any non /auth urls fall through to the app
33
+ test do
34
+ response = get "/foo", {}, {'rack.session' => {}}
35
+ assert { response.status == 200 }
36
+ assert { response.body.to_s == "/foo" }
37
+ end
38
+
39
+ # anything going to /auth/<strategy> should fall through to omniauth (the app)
40
+ test do
41
+ response = get "/auth/twitter", {}, {'rack.session' => {}}
42
+ assert { response.status == 200 }
43
+ assert { response.body.to_s == "/auth/twitter" }
44
+ end
45
+
46
+ # the callback url shoudl be intercepted and should raise if it's unknown
47
+ test do
48
+ assert { Warden::Strategies[:omni_does_not_exist].nil? }
49
+ response = get "/auth/does_not_exist/callback", {}, {'rack.session' => {}}
50
+ assert("status should be 401" ) { response.status == 401 }
51
+ assert("text should be Can't login" ) { response.body.to_s == "Can't login" }
52
+ end
53
+
54
+ # the callback url should be intercepted and should redirect back to the strategy if there is no user
55
+ # in rack['auth']
56
+ test do
57
+ response = get "/auth/twitter/callback", {}, { 'omniauth.auth' => nil, 'rack.session' => {}}
58
+ assert("status should be 302") { response.status == 302 }
59
+ assert("url should be /auth/twitter") { response.headers['Location'] == '/auth/twitter' }
60
+ end
61
+
62
+ # The session scope should not be too big
63
+ test do
64
+ session = {}
65
+ session[WardenOmniAuth::SCOPE_KEY] = "a" * 101
66
+
67
+ response = get "/auth/twitter/callback", {}, {'rack.session' => session }
68
+ assert("status should be 400" ) { response.status == 400 }
69
+ assert("body should be bad status" ) { response.body.to_s == "Bad Session" }
70
+ end
71
+ end
72
+
73
+ context do
74
+ teardown { @_rack_mock_sessions = nil; @_rack_test_sessions = nil }
75
+ setup do
76
+ $captures = []
77
+ @app = create_app do |e|
78
+ e['warden'].authenticate
79
+ $captures << e['warden'].user(:user)
80
+ Rack::Response.new("DONE").finish
81
+ end
82
+ end
83
+
84
+ # The session scope should store the user
85
+ test do
86
+ session = {}
87
+ session[WardenOmniAuth::SCOPE_KEY] = "user"
88
+ expected_redirect = $omni_auth.redirect_after_callback_path
89
+
90
+ response = get("/auth/twitter/callback", {}, {'rack.session' => session, 'omniauth.auth' => {'info' => "fred"}})
91
+
92
+ assert("should be redirected") { response.status == 302 }
93
+ assert("should go to the redirect path"){ response.headers['Location'] == expected_redirect }
94
+
95
+ response = get(expected_redirect, {}, {'rack.session' => session })
96
+ assert("should have made it into the app") { $captures.size == 1 }
97
+ assert("should have captured the user"){ $captures.first[:info] == 'fred' }
98
+ end
99
+
100
+ # should give me different handlers for different callbacks
101
+ test do
102
+ begin
103
+ session = {}
104
+ session[WardenOmniAuth::SCOPE_KEY] = "user"
105
+ expected_redirect = $omni_auth.redirect_after_callback_path
106
+
107
+ Warden::Strategies[:omni_facebook].on_callback do |user|
108
+ {:facebook => "user"}
109
+ end
110
+ Warden::Strategies[:omni_twitter].on_callback do |user|
111
+ {:twitter => "user"}
112
+ end
113
+ Warden::Strategies[:omni_google_oauth2].on_callback do |user|
114
+ {:google_oauth2 => "user"}
115
+ end
116
+
117
+ response = get("/auth/facebook/callback", {}, {'rack.session' => session, 'omniauth.auth' => {'info' => "fred"}})
118
+ response = get expected_redirect, {}, {'rack.session' => session}
119
+ assert { $captures.size == 1 }
120
+ assert { $captures.first == {:facebook => "user"} }
121
+ $captures = []
122
+
123
+ session = {}
124
+ session[WardenOmniAuth::SCOPE_KEY] = "user"
125
+ response = get("/auth/twitter/callback", {}, {'rack.session' => session, 'omniauth.auth' => {'info' => 'fred'}})
126
+ response = get expected_redirect, {}, {'rack.session' => session}
127
+ assert { $captures.size == 1 }
128
+ assert { $captures.first == {:twitter => "user"} }
129
+ $captures = []
130
+
131
+ session = {}
132
+ session[WardenOmniAuth::SCOPE_KEY] = "user"
133
+ response = get("/auth/google_oauth2/callback", {}, {'rack.session' => session, 'omniauth.auth' => {'info' => 'fred'}})
134
+ response = get expected_redirect, {}, {'rack.session' => session}
135
+ assert { $captures.size == 1 }
136
+ assert { $captures.first == {:google_oauth2 => "user"} }
137
+ ensure
138
+ Warden::Strategies[:omni_facebook].on_callback &WardenOmniAuth::DEFAULT_CALLBACK
139
+ Warden::Strategies[:omni_twitter].on_callback &WardenOmniAuth::DEFAULT_CALLBACK
140
+ Warden::Strategies[:omni_google_oauth2].on_callback &WardenOmniAuth::DEFAULT_CALLBACK
141
+ end
142
+ end
143
+
144
+ end
145
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/warden_omniauth/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "warden_omniauth-jonrowe"
6
+ s.version = WardenOmniauth::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Daniel Neighman","Jon Rowe"]
9
+ s.email = ["has.sox@gmail.com","hello@jonrowe.co.uk"]
10
+ s.homepage = "http://github.com/JonRowe/warden_omniauth"
11
+ s.summary = "A warden adapter for omniauth"
12
+ s.description = "A warden adapter for omniauth"
13
+
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+ s.rubyforge_project = "warden_omniauth"
16
+
17
+ s.add_dependency "omniauth", '~> 1.1.1'
18
+ s.add_dependency "warden", ">=0.9"
19
+
20
+ s.add_development_dependency "bundler", ">= 1.0.0"
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
24
+ s.require_path = 'lib'
25
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: warden_omniauth-jonrowe
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Daniel Neighman
9
+ - Jon Rowe
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-10-17 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: omniauth
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 1.1.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: 1.1.1
31
+ - !ruby/object:Gem::Dependency
32
+ name: warden
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0.9'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0.9'
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: 1.0.0
63
+ description: A warden adapter for omniauth
64
+ email:
65
+ - has.sox@gmail.com
66
+ - hello@jonrowe.co.uk
67
+ executables: []
68
+ extensions: []
69
+ extra_rdoc_files: []
70
+ files:
71
+ - .gitignore
72
+ - Gemfile
73
+ - README.markdown
74
+ - Rakefile
75
+ - examples/twitter/config.ru
76
+ - lib/warden_omniauth.rb
77
+ - lib/warden_omniauth/version.rb
78
+ - test/test_helper.rb
79
+ - test/test_warden_omniauth.rb
80
+ - warden_omniauth.gemspec
81
+ homepage: http://github.com/JonRowe/warden_omniauth
82
+ licenses: []
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ segments:
94
+ - 0
95
+ hash: -999869407491389986
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: 1.3.6
102
+ requirements: []
103
+ rubyforge_project: warden_omniauth
104
+ rubygems_version: 1.8.24
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: A warden adapter for omniauth
108
+ test_files: []