heroku-bouncer 0.0.1
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/Gemfile +3 -0
- data/Gemfile.lock +51 -0
- data/README.md +68 -0
- data/Rakefile +0 -0
- data/lib/heroku/bouncer.rb +87 -0
- metadata +102 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
heroku-bouncer (0.0.1)
|
5
|
+
heroku-api (>= 0.0.0)
|
6
|
+
omniauth-heroku (>= 0.1.0)
|
7
|
+
sinatra (~> 1.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
excon (0.16.10)
|
13
|
+
faraday (0.8.6)
|
14
|
+
multipart-post (~> 1.1)
|
15
|
+
hashie (1.2.0)
|
16
|
+
heroku-api (0.3.8)
|
17
|
+
excon (~> 0.16.10)
|
18
|
+
httpauth (0.2.0)
|
19
|
+
jwt (0.1.5)
|
20
|
+
multi_json (>= 1.0)
|
21
|
+
multi_json (1.6.1)
|
22
|
+
multipart-post (1.2.0)
|
23
|
+
oauth2 (0.8.1)
|
24
|
+
faraday (~> 0.8)
|
25
|
+
httpauth (~> 0.1)
|
26
|
+
jwt (~> 0.1.4)
|
27
|
+
multi_json (~> 1.0)
|
28
|
+
rack (~> 1.2)
|
29
|
+
omniauth (1.1.3)
|
30
|
+
hashie (~> 1.2)
|
31
|
+
rack
|
32
|
+
omniauth-heroku (0.1.0)
|
33
|
+
omniauth (~> 1.0)
|
34
|
+
omniauth-oauth2 (~> 1.0)
|
35
|
+
omniauth-oauth2 (1.1.1)
|
36
|
+
oauth2 (~> 0.8.0)
|
37
|
+
omniauth (~> 1.0)
|
38
|
+
rack (1.5.2)
|
39
|
+
rack-protection (1.4.0)
|
40
|
+
rack
|
41
|
+
sinatra (1.3.5)
|
42
|
+
rack (~> 1.4)
|
43
|
+
rack-protection (~> 1.3)
|
44
|
+
tilt (~> 1.3, >= 1.3.3)
|
45
|
+
tilt (1.3.4)
|
46
|
+
|
47
|
+
PLATFORMS
|
48
|
+
ruby
|
49
|
+
|
50
|
+
DEPENDENCIES
|
51
|
+
heroku-bouncer!
|
data/README.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# Heroku Bouncer
|
2
|
+
|
3
|
+
Heroku Bounder is a Rack middleware (implemented in Sinatra) that
|
4
|
+
requires Heroku OAuth on all requests.
|
5
|
+
|
6
|
+
## Use
|
7
|
+
|
8
|
+
1. Set `HEROKU_ID` and `HEROKU_SECRET` in your environment.
|
9
|
+
2. Use the middleware:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require 'heroku/bouncer'
|
13
|
+
require 'your_app'
|
14
|
+
|
15
|
+
use Heroku::Bouncer
|
16
|
+
run YourApp
|
17
|
+
```
|
18
|
+
|
19
|
+
## Options
|
20
|
+
|
21
|
+
There are 4 boolean options you can pass to the middleware:
|
22
|
+
|
23
|
+
* `herokai_only`: Automatically redirects non-Heroku accounts to
|
24
|
+
`www.heroku.com`. Alternatively, pass a valid URL and non-Herokai will
|
25
|
+
be redirected there. Default: `false`
|
26
|
+
* `expose_token`: Expose the OAuth token in the session, allowing you to
|
27
|
+
make API calls as the user. Default: `false`
|
28
|
+
* `expose_email`: Expose the user's email address in the session.
|
29
|
+
Default: `true`
|
30
|
+
* `expose_user`: Expose the user attributes in the session. Default:
|
31
|
+
`true`
|
32
|
+
|
33
|
+
You use these by passing a hash to the `use` call, for example:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
use Heroku::Builder, expose_token: true
|
37
|
+
```
|
38
|
+
|
39
|
+
## How to get the data
|
40
|
+
|
41
|
+
Based on your choice of the expose options above, the middleware adds
|
42
|
+
the following keys to your request environment:
|
43
|
+
|
44
|
+
* `bouncer.token`
|
45
|
+
* `bouncer.email`
|
46
|
+
* `bouncer.user`
|
47
|
+
|
48
|
+
You can access this in your Rack app by reading `request.env[key]`.
|
49
|
+
|
50
|
+
## Logging out
|
51
|
+
|
52
|
+
Send users to `/auth/sso-logout` if logging out of Heroku is
|
53
|
+
appropriate, or `/auth/logout` if you only wish to logout of your app.
|
54
|
+
The latter will redirect to `/`, which may result is the user being
|
55
|
+
logging in again.
|
56
|
+
|
57
|
+
## Conditionally disabling the middleware
|
58
|
+
|
59
|
+
Don't want to OAuth on every request? Use a middleware to conditionally
|
60
|
+
enable this middleware, like
|
61
|
+
[`Rack::Builder`](http://rack.rubyforge.org/doc/Rack/Builder.html).
|
62
|
+
|
63
|
+
## There be dragons
|
64
|
+
|
65
|
+
* This middleware uses a session stored in a cookie. The cookie secret
|
66
|
+
is `HEROKU_ID + HEROKU_SECRET`. So keep these secret.
|
67
|
+
* There's no tests yet. You may encounter bugs. Please report them (or
|
68
|
+
fix them in a pull request).
|
data/Rakefile
ADDED
File without changes
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'omniauth-heroku'
|
3
|
+
require 'heroku-api'
|
4
|
+
|
5
|
+
Heroku ||= Module.new
|
6
|
+
|
7
|
+
class Heroku::Bouncer < Sinatra::Base
|
8
|
+
|
9
|
+
enable :sessions
|
10
|
+
set :session_secret, ENV['HEROKU_ID'].to_s + ENV['HEROKU_SECRET'].to_s
|
11
|
+
|
12
|
+
# sets up the /auth/heroku endpoint
|
13
|
+
use OmniAuth::Builder do
|
14
|
+
provider :heroku, ENV['HEROKU_ID'], ENV['HEROKU_SECRET']
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(app, options = {})
|
18
|
+
super(app)
|
19
|
+
@herokai_only = extract_option(options, :herokai_only, false)
|
20
|
+
@expose_token = extract_option(options, :expose_token, false)
|
21
|
+
@expose_email = extract_option(options, :expose_email, true)
|
22
|
+
@expose_user = extract_option(options, :expose_user, true)
|
23
|
+
end
|
24
|
+
|
25
|
+
def extract_option(options, option, default = nil)
|
26
|
+
options.has_key?(option) ? options[option] : default
|
27
|
+
end
|
28
|
+
|
29
|
+
def store(key, value)
|
30
|
+
session[:store] ||= {}
|
31
|
+
session[:store][key] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def expose_store
|
35
|
+
session[:store].each_pair do |key, value|
|
36
|
+
request.env["bouncer.#{key}"] = value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
before do
|
41
|
+
if session[:user]
|
42
|
+
expose_store
|
43
|
+
elsif ! %w[/auth/heroku/callback /auth/heroku /auth/failure /auth/sso-logout /auth/logout].include?(request.path)
|
44
|
+
session[:return_to] = request.url
|
45
|
+
redirect to('/auth/heroku')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# callback when successful, time to save data
|
50
|
+
get '/auth/heroku/callback' do
|
51
|
+
session[:user] = true
|
52
|
+
token = request.env['omniauth.auth']['credentials']['token']
|
53
|
+
store(:token, token) if @expose_token
|
54
|
+
if @expose_email || @expose_user || @herokai_only
|
55
|
+
api = Heroku::API.new(:api_key => token)
|
56
|
+
user = api.get_user.body if @expose_user
|
57
|
+
store(:user, user) if @expose_user
|
58
|
+
store(:email, user['email']) if @expose_email
|
59
|
+
|
60
|
+
if @herokai_only && user['email'] !~ /@heroku\.com$/
|
61
|
+
url = @herokai_only.is_a?(String) ? @herokai_only : 'https://www.heroku.com'
|
62
|
+
redirect to(url) and return
|
63
|
+
end
|
64
|
+
end
|
65
|
+
redirect to(session.delete(:return_to) || '/')
|
66
|
+
end
|
67
|
+
|
68
|
+
# something went wrong
|
69
|
+
get '/auth/failure' do
|
70
|
+
session.destroy
|
71
|
+
redirect to("/")
|
72
|
+
end
|
73
|
+
|
74
|
+
# logout, single sign-on style
|
75
|
+
get '/auth/sso-logout' do
|
76
|
+
session.destroy
|
77
|
+
auth_url = ENV["HEROKU_AUTH_URL"] || "https://api.heroku.com"
|
78
|
+
redirect to("#{auth_url}/logout")
|
79
|
+
end
|
80
|
+
|
81
|
+
# logout but only locally
|
82
|
+
get '/auth/logout' do
|
83
|
+
session.destroy
|
84
|
+
redirect to("/")
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: heroku-bouncer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jonathan Dance
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: omniauth-heroku
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.1.0
|
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: 0.1.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: sinatra
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.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: '1.0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: heroku-api
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.0.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.0.0
|
62
|
+
description: ID please.
|
63
|
+
email:
|
64
|
+
- jd@heroku.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files:
|
68
|
+
- README.md
|
69
|
+
files:
|
70
|
+
- lib/heroku/bouncer.rb
|
71
|
+
- README.md
|
72
|
+
- Gemfile
|
73
|
+
- Gemfile.lock
|
74
|
+
- Rakefile
|
75
|
+
homepage: http://github.com/heroku/heroku-bouncer
|
76
|
+
licenses: []
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 1.8.23
|
96
|
+
signing_key:
|
97
|
+
specification_version: 3
|
98
|
+
summary: Requires Heroku OAuth on all requests.
|
99
|
+
test_files:
|
100
|
+
- Gemfile
|
101
|
+
- Gemfile.lock
|
102
|
+
- Rakefile
|