omniauth-heroku 0.1.1 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7114a261c4657b1093fa15c002dc0c5dc501c3a147670c99b31bb82bb2173290
4
+ data.tar.gz: 409fe3bd640e82ec72fc30f92ef9a0fd383bb95260b4f1d8d7d9d070b6d325b4
5
+ SHA512:
6
+ metadata.gz: 36e9c08495d7941cf3a19b8e2b972ec2d70fd992c326f88586141892c5bc445ab4ee9ff28927062d6a5babd58351f7b16fda97fcea9e5933750bc73178f5d6fd
7
+ data.tar.gz: 6d8bcd09cd0847c01f870ad2d955a90b21ac449b56ba0aafcd275790a9fc8efbca5aae86252a80f3ec916583780d352516b4065e275a9b9450c6201d034c4703
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Pedro Belo
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 CHANGED
@@ -1,8 +1,19 @@
1
1
  # OmniAuth Heroku
2
2
 
3
- [OmniAuth](https://github.com/intridea/omniauth) strategy for authenticating to Heroku.
3
+ [![Build Status](https://github.com/heroku/omniauth-heroku/actions/workflows/ci.yml/badge.svg)](https://github.com/heroku/omniauth-heroku/actions)
4
4
 
5
- Heroku's support for OAuth is still private/experimental.
5
+ [OmniAuth](https://github.com/intridea/omniauth) strategy for authenticating
6
+ Heroku users.
7
+
8
+ Mount this with your Rack application (be it Rails or Sinatra) to simplify the
9
+ [OAuth flow with Heroku](https://devcenter.heroku.com/articles/oauth).
10
+
11
+ This is intended for apps already using OmniAuth, for apps that authenticate
12
+ against more than one service (eg: Heroku and GitHub), or apps that have
13
+ specific needs on session management. If your app doesn't fall in any of these
14
+ you should consider using [Heroku Bouncer][heroku-bouncer] instead.
15
+
16
+ [heroku-bouncer]: https://github.com/heroku/heroku-bouncer
6
17
 
7
18
 
8
19
  ## Configuration
@@ -11,20 +22,116 @@ OmniAuth works as a Rack middleware. Mount this Heroku adapter with:
11
22
 
12
23
  ```ruby
13
24
  use OmniAuth::Builder do
14
- provider :heroku, ENV['HEROKU_OAUTH_ID'], ENV['HEROKU_OAUTH_SECRET']
25
+ provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET")
15
26
  end
16
27
  ```
17
28
 
18
- Your Heroku OAuth client should be set to receive callbacks on `/auth/heroku/callback`.
29
+ Obtain a `HEROKU_OAUTH_ID` and `HEROKU_OAUTH_SECRET` by creating a client with
30
+ the [Heroku OAuth CLI plugin](https://github.com/heroku/heroku-oauth).
31
+
32
+ Your Heroku OAuth client should be set to receive callbacks on
33
+ `/auth/heroku/callback`.
19
34
 
20
35
 
21
36
  ## Usage
22
37
 
23
38
  Initiate the OAuth flow sending users to `/auth/heroku`.
24
39
 
25
- Once the authorization flow is complete and the user is bounced back to your application, check `env["omniauth.auth"]["credentials"]`. It contains both a refresh token and an access token (identified just as `"token"`) to the account.
40
+ Once the authorization flow is complete and the user is bounced back to your
41
+ application, check `env["omniauth.auth"]["credentials"]`. It contains both a
42
+ refresh token and an access token (identified just as `"token"`) to the
43
+ account.
44
+
45
+ We recommend using this access token together with
46
+ the [Heroku Platform API gem][heroku-ruby-client] to make API calls on behalf of the user.
47
+
48
+ [heroku-ruby-client]: https://github.com/heroku/platform-api
49
+
50
+ Refer to the examples below to see how these work.
51
+
52
+
53
+ ### Basic account information
54
+
55
+ If you want this middleware to fetch additional Heroku account information like
56
+ the user email address and name, use the `fetch_info` option, like:
57
+
58
+ ```ruby
59
+ use OmniAuth::Builder do
60
+ provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET"),
61
+ fetch_info: true
62
+ end
63
+ ```
64
+
65
+ This sets name and email in the [omniauth auth hash][auth-hash]. You can access
66
+ it from your app via `env["omniauth.auth"]["info"]`.
67
+
68
+ [auth-hash]: https://github.com/intridea/omniauth/wiki/Auth-Hash-Schema
69
+
70
+ It will also add [additional Heroku account info][platform-api] to
71
+ `env["omniauth.auth"]["extra"]`.
72
+
73
+ [platform-api]: https://devcenter.heroku.com/articles/platform-api-reference#account
74
+
75
+ ### OAuth scopes
76
+
77
+ [Heroku supports different OAuth scopes][oauth-scopes]. By default this
78
+ strategy will request global access to the account, but you're encouraged to
79
+ request for less permissions when possible.
80
+
81
+ [oauth-scopes]: https://devcenter.heroku.com/articles/oauth#scopes
82
+
83
+ To do so, configure it like:
84
+
85
+ ```ruby
86
+ use OmniAuth::Builder do
87
+ provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET"),
88
+ scope: "identity"
89
+ end
90
+ ```
91
+
92
+ This will trim down the permissions associated to the access token given back
93
+ to you.
94
+
95
+ The Oauth scope can also be decided dynamically at runtime. For example, you
96
+ could use a `scope` GET parameter if it exists, and revert to a default `scope`
97
+ if it does not:
98
+
99
+ ```ruby
100
+ use OmniAuth::Builder do
101
+ provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET"),
102
+ scope: ->(request) { request.params["scope"] || "identity" }
103
+ end
104
+ ```
105
+
106
+
107
+ ## Example - Sinatra
108
+
109
+ ```ruby
110
+ class Myapp < Sinatra::Application
111
+ use Rack::Session::Cookie, secret: ENV.fetch("SESSION_SECRET")
112
+
113
+ use OmniAuth::Builder do
114
+ provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET")
115
+ end
116
+
117
+ get "/" do
118
+ redirect "/auth/heroku"
119
+ end
26
120
 
27
- We recommend using this access token together with [Heroku.rb](https://github.com/heroku/heroku.rb) to make API calls on behalf of the user.
121
+ get "/auth/heroku/callback" do
122
+ access_token = env["omniauth.auth"]["credentials"]["token"]
123
+ # DO NOT store this token in an unencrypted cookie session
124
+ # Please read "A note on security" below!
125
+ heroku = PlatformAPI.connect_oauth(access_token)
126
+ "You have #{heroku.app.list.count} apps"
127
+ end
128
+ end
129
+ ```
130
+
131
+ Note that we're explicitly calling `Rack::Session::Cookie` with a secret. Using
132
+ `enable :sessions` is not recommended because the secret is generated randomly,
133
+ and not reused across processes – so your users can lose their session whenever
134
+ your app restarts.
28
135
 
29
136
 
30
137
  ## Example - Rails
@@ -33,7 +140,7 @@ Under `config/initializers/omniauth.rb`:
33
140
 
34
141
  ```ruby
35
142
  Rails.application.config.middleware.use OmniAuth::Builder do
36
- provider :heroku, ENV['HEROKU_OAUTH_ID'], ENV['HEROKU_OAUTH_SECRET']
143
+ provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET")
37
144
  end
38
145
  ```
39
146
 
@@ -56,8 +163,10 @@ class SessionsController < ApplicationController
56
163
 
57
164
  def create
58
165
  access_token = request.env['omniauth.auth']['credentials']['token']
59
- heroku_api = Heroku::API.new(:api_key => access_token)
60
- @apps = api.get_apps.body
166
+ # DO NOT store this token in an unencrypted cookie session
167
+ # Please read "A note on security" below!
168
+ heroku = PlatformAPI.connect_oauth(access_token)
169
+ @apps = heroku.app.list
61
170
  end
62
171
  end
63
172
  ```
@@ -74,6 +183,20 @@ And view:
74
183
  </ul>
75
184
  ```
76
185
 
186
+ ## A note on security
187
+
188
+ **Make sure your cookie session is encrypted before storing sensitive
189
+ information on it, like access tokens**. [encrypted_cookie][encrypted-cookie]
190
+ is a popular gem to do that in Ruby.
191
+
192
+ [encrypted-cookie]: https://github.com/cvonkleist/encrypted_cookie
193
+
194
+ Both Rails and Sinatra take a cookie secret, but that is only used to protect
195
+ against tampering; any information stored on standard cookie sessions can
196
+ easily be read from the client side, which can be further exploited to leak
197
+ credentials off your app.
198
+
199
+
77
200
  ## Meta
78
201
 
79
202
  Released under the MIT license.
@@ -3,13 +3,88 @@ require 'omniauth-oauth2'
3
3
  module OmniAuth
4
4
  module Strategies
5
5
  class Heroku < OmniAuth::Strategies::OAuth2
6
- BaseAuthUrl = ENV["HEROKU_AUTH_URL"] || "https://id.heroku.com"
6
+ AuthUrl = ENV["HEROKU_AUTH_URL"] || "https://id.heroku.com"
7
+ ApiUrl = ENV["HEROKU_API_URL"] || "https://api.heroku.com"
7
8
 
8
9
  option :client_options, {
9
- :site => BaseAuthUrl,
10
- :authorize_url => "#{BaseAuthUrl}/oauth/authorize",
11
- :token_url => "#{BaseAuthUrl}/oauth/token"
10
+ site: AuthUrl,
11
+ authorize_url: "#{AuthUrl}/oauth/authorize",
12
+ token_url: "#{AuthUrl}/oauth/token"
12
13
  }
14
+
15
+ # whether we should make another API call to Heroku to fetch
16
+ # additional account info like the real user name and email
17
+ option :fetch_info
18
+
19
+ uid do
20
+ access_token.params["user_id"]
21
+ end
22
+
23
+ info do
24
+ if options.fetch_info
25
+ email_hash = Digest::MD5.hexdigest(account_info['email'].to_s)
26
+ default_image_url = "https://dashboard.heroku.com/ninja-avatar-48x48.png"
27
+ image_url = "https://secure.gravatar.com/avatar/#{email_hash}.png?d=#{default_image_url}"
28
+
29
+ {
30
+ name: account_info["name"],
31
+ email: account_info["email"],
32
+ image: image_url,
33
+ }
34
+ else
35
+ { name: "Heroku user" } # only mandatory field
36
+ end
37
+ end
38
+
39
+ extra do
40
+ if options.fetch_info
41
+ account_info
42
+ else
43
+ {}
44
+ end
45
+ end
46
+
47
+ # override method in OmniAuth::Strategies::OAuth2 to error
48
+ # when we don't have a client_id or secret:
49
+ def request_phase
50
+ if missing_client_id?
51
+ fail!(:missing_client_id)
52
+ elsif missing_client_secret?
53
+ fail!(:missing_client_secret)
54
+ else
55
+ super
56
+ end
57
+ end
58
+
59
+ def authorize_params
60
+ super.tap do |params|
61
+ # Allow the scope to be determined dynamically based on the request.
62
+ if params.scope.respond_to?(:call)
63
+ params.scope = params.scope.call(request)
64
+ end
65
+ end
66
+ end
67
+
68
+ def account_info
69
+ @account_info ||= MultiJson.decode(heroku_api.get("/account").body)
70
+ end
71
+
72
+ def heroku_api
73
+ @heroku_api ||= Faraday.new(
74
+ url: ApiUrl,
75
+ headers: {
76
+ "Accept" => "application/vnd.heroku+json; version=3",
77
+ "Authorization" => "Bearer #{access_token.token}",
78
+ })
79
+ end
80
+
81
+ def missing_client_id?
82
+ [nil, ""].include?(options.client_id)
83
+ end
84
+
85
+ def missing_client_secret?
86
+ [nil, ""].include?(options.client_secret)
87
+ end
13
88
  end
14
89
  end
15
90
  end
metadata CHANGED
@@ -1,48 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-heroku
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
5
- prerelease:
4
+ version: 0.4.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Pedro Belo
9
- autorequire:
8
+ autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-03-12 00:00:00.000000000 Z
11
+ date: 2021-07-09 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: omniauth
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: '1.0'
19
+ version: 1.9.0
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '1.0'
26
+ version: 1.9.0
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: omniauth-oauth2
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
- version: '1.0'
33
+ version: 1.6.0
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
- version: '1.0'
40
+ version: 1.6.0
46
41
  description: OmniAuth strategy for Heroku.
47
42
  email:
48
43
  - pedro@heroku.com
@@ -50,35 +45,31 @@ executables: []
50
45
  extensions: []
51
46
  extra_rdoc_files: []
52
47
  files:
53
- - .gitignore
54
- - .rspec
48
+ - LICENSE
55
49
  - README.md
56
- - Rakefile
57
50
  - lib/omniauth-heroku.rb
58
51
  - lib/omniauth/strategies/heroku.rb
59
- - omniauth-heroku.gemspec
60
52
  homepage: https://github.com/heroku/omniauth-heroku
61
- licenses: []
62
- post_install_message:
53
+ licenses:
54
+ - MIT
55
+ metadata: {}
56
+ post_install_message:
63
57
  rdoc_options: []
64
58
  require_paths:
65
59
  - lib
66
60
  required_ruby_version: !ruby/object:Gem::Requirement
67
- none: false
68
61
  requirements:
69
- - - ! '>='
62
+ - - ">="
70
63
  - !ruby/object:Gem::Version
71
64
  version: '0'
72
65
  required_rubygems_version: !ruby/object:Gem::Requirement
73
- none: false
74
66
  requirements:
75
- - - ! '>='
67
+ - - ">="
76
68
  - !ruby/object:Gem::Version
77
69
  version: '0'
78
70
  requirements: []
79
- rubyforge_project:
80
- rubygems_version: 1.8.24
81
- signing_key:
82
- specification_version: 3
71
+ rubygems_version: 3.2.14
72
+ signing_key:
73
+ specification_version: 4
83
74
  summary: OmniAuth strategy for Heroku.
84
75
  test_files: []
data/.gitignore DELETED
@@ -1,17 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- /pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --colour
data/Rakefile DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
@@ -1,16 +0,0 @@
1
- Gem::Specification.new do |gem|
2
- gem.authors = ["Pedro Belo"]
3
- gem.email = ["pedro@heroku.com"]
4
- gem.description = %q{OmniAuth strategy for Heroku.}
5
- gem.summary = %q{OmniAuth strategy for Heroku.}
6
- gem.homepage = "https://github.com/heroku/omniauth-heroku"
7
-
8
- gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
9
- gem.files = `git ls-files`.split("\n")
10
- gem.name = "omniauth-heroku"
11
- gem.require_paths = ["lib"]
12
- gem.version = "0.1.1"
13
-
14
- gem.add_dependency 'omniauth', '~> 1.0'
15
- gem.add_dependency 'omniauth-oauth2', '~> 1.0'
16
- end