omniauth-heroku 0.1.1 → 0.1.2.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +9 -2
- data/lib/omniauth/strategies/heroku.rb +1 -3
- data/lib/omniauth/strategies/heroku_oauth2.rb +124 -0
- data/lib/omniauth-heroku.rb +1 -0
- data/omniauth-heroku.gemspec +2 -2
- metadata +10 -9
data/README.md
CHANGED
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
[OmniAuth](https://github.com/intridea/omniauth) strategy for authenticating to Heroku.
|
4
4
|
|
5
|
-
Heroku's support for OAuth is still private/experimental.
|
6
|
-
|
7
5
|
|
8
6
|
## Configuration
|
9
7
|
|
@@ -74,6 +72,15 @@ And view:
|
|
74
72
|
</ul>
|
75
73
|
```
|
76
74
|
|
75
|
+
## A note on security
|
76
|
+
|
77
|
+
Be careful if you intend to store access tokens in cookie-based sessions.
|
78
|
+
|
79
|
+
Many web frameworks offer protection against session tampering, but still store sessions with no encryption. This allows attackers with some access to the user session to obtain valuable information from cookies.
|
80
|
+
|
81
|
+
Rails, Sinatra and others can be configured to encrypt cookies, but don't do it by default. So make sure to encrypt cookie-based sessions before storing confidential data on it!
|
82
|
+
|
83
|
+
|
77
84
|
## Meta
|
78
85
|
|
79
86
|
Released under the MIT license.
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'uri'
|
3
|
+
require 'oauth2'
|
4
|
+
require 'omniauth'
|
5
|
+
require 'timeout'
|
6
|
+
require 'securerandom'
|
7
|
+
|
8
|
+
module OmniAuth
|
9
|
+
module Strategies
|
10
|
+
# Vendored in from `omniauth-oauth2`, but with slight modifications to
|
11
|
+
# allow request IDs to be passed through during the token phase so that the
|
12
|
+
# OAuth 2 dance can be more easily debugged.
|
13
|
+
class HerokuOAuth2
|
14
|
+
include OmniAuth::Strategy
|
15
|
+
|
16
|
+
args [:client_id, :client_secret]
|
17
|
+
|
18
|
+
option :client_id, nil
|
19
|
+
option :client_secret, nil
|
20
|
+
option :client_options, {}
|
21
|
+
option :authorize_params, {}
|
22
|
+
option :authorize_options, [:scope]
|
23
|
+
option :token_params, {}
|
24
|
+
option :token_options, []
|
25
|
+
option :provider_ignores_state, false
|
26
|
+
option :request_id, lambda { |env| nil }
|
27
|
+
|
28
|
+
attr_accessor :access_token
|
29
|
+
|
30
|
+
def client
|
31
|
+
::OAuth2::Client.new(options.client_id, options.client_secret, deep_symbolize(options.client_options))
|
32
|
+
end
|
33
|
+
|
34
|
+
def callback_url
|
35
|
+
full_host + script_name + callback_path
|
36
|
+
end
|
37
|
+
|
38
|
+
credentials do
|
39
|
+
hash = {'token' => access_token.token}
|
40
|
+
hash.merge!('refresh_token' => access_token.refresh_token) if access_token.expires? && access_token.refresh_token
|
41
|
+
hash.merge!('expires_at' => access_token.expires_at) if access_token.expires?
|
42
|
+
hash.merge!('expires' => access_token.expires?)
|
43
|
+
hash
|
44
|
+
end
|
45
|
+
|
46
|
+
def request_phase
|
47
|
+
redirect client.auth_code.authorize_url({:redirect_uri => callback_url}.merge(authorize_params))
|
48
|
+
end
|
49
|
+
|
50
|
+
def authorize_params
|
51
|
+
options.authorize_params[:state] = SecureRandom.hex(24)
|
52
|
+
params = options.authorize_params.merge(options.authorize_options.inject({}){|h,k| h[k.to_sym] = options[k] if options[k]; h})
|
53
|
+
if OmniAuth.config.test_mode
|
54
|
+
@env ||= {}
|
55
|
+
@env['rack.session'] ||= {}
|
56
|
+
end
|
57
|
+
session['omniauth.state'] = params[:state]
|
58
|
+
params
|
59
|
+
end
|
60
|
+
|
61
|
+
def token_params
|
62
|
+
options.token_params.merge(options.token_options.inject({}){|h,k| h[k.to_sym] = options[k] if options[k]; h})
|
63
|
+
end
|
64
|
+
|
65
|
+
def callback_phase
|
66
|
+
if request.params['error'] || request.params['error_reason']
|
67
|
+
raise CallbackError.new(request.params['error'], request.params['error_description'] || request.params['error_reason'], request.params['error_uri'])
|
68
|
+
end
|
69
|
+
# if !options.provider_ignores_state && (request.params['state'].to_s.empty? || request.params['state'] != session.delete('omniauth.state'))
|
70
|
+
# raise CallbackError.new(nil, :csrf_detected)
|
71
|
+
# end
|
72
|
+
|
73
|
+
self.access_token = build_access_token
|
74
|
+
params = {}
|
75
|
+
if request_id = options.request_id.call(@env)
|
76
|
+
params.merge!(:headers => { "Request-Id" => request_id })
|
77
|
+
end
|
78
|
+
self.access_token = access_token.refresh!(params) if access_token.expired?
|
79
|
+
|
80
|
+
super
|
81
|
+
rescue ::OAuth2::Error, CallbackError => e
|
82
|
+
fail!(:invalid_credentials, e)
|
83
|
+
rescue ::MultiJson::DecodeError => e
|
84
|
+
fail!(:invalid_response, e)
|
85
|
+
rescue ::Timeout::Error, ::Errno::ETIMEDOUT => e
|
86
|
+
fail!(:timeout, e)
|
87
|
+
rescue ::SocketError => e
|
88
|
+
fail!(:failed_to_connect, e)
|
89
|
+
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
def deep_symbolize(hash)
|
94
|
+
hash.inject({}) do |h, (k,v)|
|
95
|
+
h[k.to_sym] = v.is_a?(Hash) ? deep_symbolize(v) : v
|
96
|
+
h
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def build_access_token
|
101
|
+
verifier = request.params['code']
|
102
|
+
params = {:redirect_uri => callback_url}.
|
103
|
+
merge(token_params.to_hash(:symbolize_keys => true))
|
104
|
+
# inject a request ID if one is available
|
105
|
+
if request_id = options.request_id.call(@env)
|
106
|
+
params.merge!(:headers => { "Request-Id" => request_id })
|
107
|
+
end
|
108
|
+
client.auth_code.get_token(verifier, params)
|
109
|
+
end
|
110
|
+
|
111
|
+
# An error that is indicated in the OAuth 2.0 callback.
|
112
|
+
# This could be a `redirect_uri_mismatch` or other
|
113
|
+
class CallbackError < StandardError
|
114
|
+
attr_accessor :error, :error_reason, :error_uri
|
115
|
+
|
116
|
+
def initialize(error, error_reason=nil, error_uri=nil)
|
117
|
+
self.error = error
|
118
|
+
self.error_reason = error_reason
|
119
|
+
self.error_uri = error_uri
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
data/lib/omniauth-heroku.rb
CHANGED
data/omniauth-heroku.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |gem|
|
|
9
9
|
gem.files = `git ls-files`.split("\n")
|
10
10
|
gem.name = "omniauth-heroku"
|
11
11
|
gem.require_paths = ["lib"]
|
12
|
-
gem.version = "0.1.
|
12
|
+
gem.version = "0.1.2.pre"
|
13
13
|
|
14
|
+
gem.add_dependency 'oauth2', '~> 0.8.0'
|
14
15
|
gem.add_dependency 'omniauth', '~> 1.0'
|
15
|
-
gem.add_dependency 'omniauth-oauth2', '~> 1.0'
|
16
16
|
end
|
metadata
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omniauth-heroku
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.2.pre
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Pedro Belo
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: oauth2
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 0.8.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,9 +26,9 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 0.8.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name: omniauth
|
31
|
+
name: omniauth
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
@@ -56,6 +56,7 @@ files:
|
|
56
56
|
- Rakefile
|
57
57
|
- lib/omniauth-heroku.rb
|
58
58
|
- lib/omniauth/strategies/heroku.rb
|
59
|
+
- lib/omniauth/strategies/heroku_oauth2.rb
|
59
60
|
- omniauth-heroku.gemspec
|
60
61
|
homepage: https://github.com/heroku/omniauth-heroku
|
61
62
|
licenses: []
|
@@ -72,9 +73,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
72
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
74
|
none: false
|
74
75
|
requirements:
|
75
|
-
- - ! '
|
76
|
+
- - ! '>'
|
76
77
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
78
|
+
version: 1.3.1
|
78
79
|
requirements: []
|
79
80
|
rubyforge_project:
|
80
81
|
rubygems_version: 1.8.24
|