├── Procfile
├── config.ru
├── views
├── token.erb
├── layout.erb
└── index.erb
├── Gemfile
├── README.md
├── LICENSE
├── .gitignore
├── Gemfile.lock
└── tokenate.rb
/Procfile:
--------------------------------------------------------------------------------
1 | web: rackup -s puma -p $PORT
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | env = ENV['RACK_ENV'].to_sym || :development
2 |
3 | require "bundler/setup"
4 | Bundler.require(:default, env)
5 |
6 | require_relative 'tokenate.rb'
7 | run Tokenate
8 |
--------------------------------------------------------------------------------
/views/token.erb:
--------------------------------------------------------------------------------
1 |
Token with "<%= @scope %>" scope:
2 |
3 | <%= @token %>
4 |
5 |
6 | Request a new token
7 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | ruby '2.3.1'
4 |
5 | gem 'sinatra'
6 | gem 'sinatra-contrib'
7 | gem 'rack-contrib'
8 | gem 'rack-ssl'
9 | gem 'puma'
10 | gem 'httparty'
11 |
12 |
--------------------------------------------------------------------------------
/views/layout.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Tokenate
6 |
7 |
8 |
9 |
10 |
11 |
12 | <%= yield %>
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Tokenate
2 |
3 | Tokenate helps you generate test or other personal tokens from your
4 | [Token Endpoint][tokenendpoint] with a specified scope. The authorization and token endpoints fields in the form are preset to the
5 | [Indieauth][] defaults.
6 |
7 | Read more about authorization using your own website at
8 | [IndieWeb.org][indieweb].
9 |
10 | ## Installation
11 |
12 | 1. `$ bundle install`
13 | 1. `$ foreman start`
14 | 1. Visit http://localhost:5000/ in your browser.
15 |
16 | You can probably also run this on Heroku or another public web server but make
17 | sure you run over a secure (https) connection.
18 |
19 | ---
20 |
21 | [Barry Frost][barryf].
22 |
23 |
24 | [tokenendpoint]: https://indieweb.org/token-endpoint
25 | [indieauth]: https://indieauth.com
26 | [indieweb]: https://indieweb.org
27 | [barryf]: https://barryfrost.com
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Barry Frost
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.gem
2 | *.rbc
3 | /.config
4 | /coverage/
5 | /InstalledFiles
6 | /pkg/
7 | /spec/reports/
8 | /spec/examples.txt
9 | /test/tmp/
10 | /test/version_tmp/
11 | /tmp/
12 |
13 | # Used by dotenv library to load environment variables.
14 | # .env
15 |
16 | ## Specific to RubyMotion:
17 | .dat*
18 | .repl_history
19 | build/
20 | *.bridgesupport
21 | build-iPhoneOS/
22 | build-iPhoneSimulator/
23 |
24 | ## Specific to RubyMotion (use of CocoaPods):
25 | #
26 | # We recommend against adding the Pods directory to your .gitignore. However
27 | # you should judge for yourself, the pros and cons are mentioned at:
28 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29 | #
30 | # vendor/Pods/
31 |
32 | ## Documentation cache and generated files:
33 | /.yardoc/
34 | /_yardoc/
35 | /doc/
36 | /rdoc/
37 |
38 | ## Environment normalization:
39 | /.bundle/
40 | /vendor/bundle
41 | /lib/bundler/man/
42 |
43 | # for a library or gem, you might want to ignore these files since the code is
44 | # intended to run in multiple environments; otherwise, check them in:
45 | # Gemfile.lock
46 | # .ruby-version
47 | # .ruby-gemset
48 |
49 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50 | .rvmrc
51 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | activesupport (5.2.4.3)
5 | concurrent-ruby (~> 1.0, >= 1.0.2)
6 | i18n (>= 0.7, < 2)
7 | minitest (~> 5.1)
8 | tzinfo (~> 1.1)
9 | backports (3.11.3)
10 | concurrent-ruby (1.1.6)
11 | httparty (0.16.2)
12 | multi_xml (>= 0.5.2)
13 | i18n (1.8.2)
14 | concurrent-ruby (~> 1.0)
15 | minitest (5.14.1)
16 | multi_json (1.13.1)
17 | multi_xml (0.6.0)
18 | mustermann (1.0.2)
19 | puma (3.12.6)
20 | rack (2.2.3)
21 | rack-contrib (2.0.1)
22 | rack (~> 2.0)
23 | rack-protection (2.0.3)
24 | rack
25 | rack-ssl (1.4.1)
26 | rack
27 | sinatra (2.0.3)
28 | mustermann (~> 1.0)
29 | rack (~> 2.0)
30 | rack-protection (= 2.0.3)
31 | tilt (~> 2.0)
32 | sinatra-contrib (2.0.3)
33 | activesupport (>= 4.0.0)
34 | backports (>= 2.8.2)
35 | multi_json
36 | mustermann (~> 1.0)
37 | rack-protection (= 2.0.3)
38 | sinatra (= 2.0.3)
39 | tilt (>= 1.3, < 3)
40 | thread_safe (0.3.6)
41 | tilt (2.0.8)
42 | tzinfo (1.2.7)
43 | thread_safe (~> 0.1)
44 |
45 | PLATFORMS
46 | ruby
47 |
48 | DEPENDENCIES
49 | httparty
50 | puma
51 | rack-contrib
52 | rack-ssl
53 | sinatra
54 | sinatra-contrib
55 |
56 | RUBY VERSION
57 | ruby 2.3.1p112
58 |
59 | BUNDLED WITH
60 | 1.13.6
61 |
--------------------------------------------------------------------------------
/views/index.erb:
--------------------------------------------------------------------------------
1 | Request a scoped token from your endpoint
2 |
3 |
--------------------------------------------------------------------------------
/tokenate.rb:
--------------------------------------------------------------------------------
1 | class Tokenate < Sinatra::Application
2 |
3 | configure do
4 | set :server, :puma
5 | use Rack::SSL unless settings.development?
6 |
7 | secret = ENV['COOKIE_SECRET'] || Random.new_seed.to_s
8 | use Rack::Session::Cookie, secret: secret, expire_after: 2_592_000
9 | end
10 |
11 | get '/' do
12 | erb :index
13 | end
14 |
15 | get '/auth' do
16 | session[:state] = Random.new_seed.to_s
17 | session[:token_endpoint] = params[:token_endpoint]
18 | session[:scope] = params[:scope]
19 | session[:me] = params[:me]
20 |
21 | qs = URI.encode_www_form({
22 | me: params[:me],
23 | client_id: base_url,
24 | state: session[:state],
25 | scope: session[:scope],
26 | redirect_uri: "#{base_url}auth/callback"
27 | })
28 |
29 | redirect "#{params[:authorization_endpoint]}?#{qs}"
30 | end
31 |
32 | get '/auth/callback' do
33 | response = HTTParty.post(
34 | session[:token_endpoint],
35 | body: {
36 | me: params[:me],
37 | code: params[:code],
38 | redirect_uri: "#{base_url}auth/callback",
39 | client_id: base_url,
40 | state: session[:state],
41 | scope: session[:scope]
42 | })
43 | response_hash = CGI.parse(response.parsed_response)
44 | @token = response_hash['access_token'].first
45 | @scope = session[:scope]
46 | erb :token
47 | end
48 |
49 | def base_url
50 | @base_url ||=
51 | "#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}/"
52 | end
53 |
54 | end
55 |
--------------------------------------------------------------------------------