sinatra-portier 1.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3526df1906d6fda7d480ccc1059a993380b23517
4
+ data.tar.gz: f024759855c2410cc6d16fc938d9f6b626316c08
5
+ SHA512:
6
+ metadata.gz: 7ceaea629c496c9b2823f03359380824148d4f55bd7418efea7dc3c8aa63cfb36da04f9c32493e31d33e0564b8f30515aae6ba989743295132cf31fa2f69b4ce
7
+ data.tar.gz: 27b7766b99dc5c50f4e4309b060be43d1f790ad8af3df2c89783c5245c79837c11bd5d2ca5d72ccb643d0f732202409d0876abb1a0d1fb30b5e4aad2d5637a12
data/README.md ADDED
@@ -0,0 +1,53 @@
1
+ Sinatra plugin that allows authentication against portier, the successor for [Persona](https://login.persona.org/about). Like Persona, this lets you verify the email identity of a user.
2
+
3
+ To be a drop-in replacement, the code keeps using the browserid namespace.
4
+
5
+ ---
6
+
7
+ To learn more, [read about portier](https://portier.github.io/).
8
+
9
+ Note that logins are not done from within a form on your site -- you provide a login form, and that will start up the login flow and redirect back to your main page.
10
+
11
+ How to get started:
12
+
13
+ ```ruby
14
+ require 'sinatra/base'
15
+ require 'sinatra/browserid'
16
+
17
+ module MyApp < Sinatra::Base
18
+ register Sinatra::BrowserID
19
+
20
+ set :sessions, true
21
+
22
+ get '/'
23
+ if authorized?
24
+ "Welcome, #{authorized_email}"
25
+ else
26
+ render_login_button
27
+ end
28
+ end
29
+
30
+ get '/secure'
31
+ authorize! # require a user be logged in
32
+
33
+ email = authorized_email # browserid email
34
+ ...
35
+ end
36
+
37
+ get '/logout'
38
+ logout!
39
+
40
+ redirect '/'
41
+ end
42
+ end
43
+ ```
44
+
45
+ See the rdoc for more details on the helper functions. For a functioning
46
+ example app, run <tt>rackup -p $PORT</tt> in the example directory.
47
+
48
+ Available sinatra settings:
49
+
50
+ * <tt>:browserid_url</tt>: If you're using an alternate auth provider
51
+ other than https://broker.portier.io
52
+ * <tt>:browserid_login_url</tt>: URL users get redirected to when the
53
+ <tt>authorize!</tt> helper is called and a user is not logged in
data/example/app.rb ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.join(File.dirname(__FILE__), "..", "lib")
4
+
5
+ require "sinatra/base"
6
+ require "sinatra/browserid"
7
+
8
+ class TestApp < Sinatra::Base
9
+ register Sinatra::BrowserID
10
+
11
+ set :sessions, true
12
+
13
+ get '/' do
14
+ erb :index
15
+ end
16
+
17
+ get '/logout' do
18
+ logout!
19
+
20
+ redirect '/'
21
+ end
22
+
23
+ get '/confidential' do
24
+ authorize!
25
+
26
+ "Hey #{authorized_email}, you're authorized!"
27
+ end
28
+ end
data/example/config.ru ADDED
@@ -0,0 +1,2 @@
1
+ require "./app"
2
+ run TestApp
@@ -0,0 +1,21 @@
1
+ <html>
2
+ <head>
3
+ </head>
4
+ <body>
5
+
6
+ <h1>Test App</h1>
7
+
8
+ <p>
9
+ <% if authorized? %>
10
+ Hello, <%= authorized_email %> <a href="/logout">(logout)</a>
11
+ <% else %>
12
+ <%= render_login_button %>
13
+ <% end %>
14
+ </p>
15
+
16
+ <p>
17
+ see a <a href="/confidential">page that requires a login</a>.
18
+ </p>
19
+
20
+ </body>
21
+ </html>
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "open-uri"
4
+ require 'json'
5
+ require 'url_safe_base64'
6
+ require 'jwt'
7
+ require "sinatra/base"
8
+ require 'sinatra/browserid/helpers'
9
+ require 'sinatra/browserid/template'
10
+
11
+ # This module provides an interface to verify a users email address
12
+ # with browserid.org.
13
+ module Sinatra
14
+ module BrowserID
15
+ def self.registered(app)
16
+ app.helpers BrowserID::Helpers
17
+
18
+ app.set :browserid_url, "https://broker.portier.io"
19
+ app.set :browserid_login_button, :red
20
+ app.set :browserid_login_url, "/_browserid_login"
21
+
22
+ app.get '/_browserid_login' do
23
+ # TODO(petef): render a page that initiates login without
24
+ # waiting for a user click.
25
+ render_login_button
26
+ end
27
+
28
+ app.post '/_browserid_assert' do
29
+ begin
30
+ # 3. Server checks signature
31
+ # for that, fetch the public key from the LA instance (TODO: Do that beforehand for trusted instances, and generally cache the key)
32
+ public_key_jwks = JSON.parse(URI.parse(URI.escape(settings.browserid_url + '/jwks.json')).read)
33
+ public_key = OpenSSL::PKey::RSA.new
34
+ public_key.e = OpenSSL::BN.new UrlSafeBase64.decode64(public_key_jwks["keys"][0]["e"]), 2
35
+ public_key.n = OpenSSL::BN.new UrlSafeBase64.decode64(public_key_jwks["keys"][0]["n"]), 2
36
+
37
+ id_token = JWT.decode params[:id_token], public_key, true, { :algorithm => 'RS256' }
38
+ id_token = id_token[0]
39
+ # 4. Needs to make sure token is still valid
40
+ if (id_token["iss"] == settings.browserid_url &&
41
+ id_token["aud"] == request.base_url.chomp('/') &&
42
+ id_token["exp"] > Time.now.to_i &&
43
+ id_token["email_verified"] &&
44
+ id_token["nonce"] == session[:nonce])
45
+ session[:browserid_email] = id_token["email"]
46
+ session.delete(:nonce)
47
+ if session['redirect_url']
48
+ redirect session['redirect_url']
49
+ else
50
+ redirect "/"
51
+ end
52
+ end
53
+ rescue OpenURI::HTTPError => e
54
+ puts "could not validate token: " + e.to_s
55
+ end
56
+ halt 403
57
+
58
+ end
59
+ end # def self.registered
60
+ end # module BrowserID
61
+ register BrowserID
62
+ end # module Sinatra
63
+
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-portier
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Pete Fritchman
8
+ - Malte Paskuda
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-10-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sinatra
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: 1.1.0
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: 1.1.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: jwt
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 1.5.4
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: 1.5.4
42
+ - !ruby/object:Gem::Dependency
43
+ name: url_safe_base64
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: 0.2.2
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 0.2.2
56
+ description:
57
+ email:
58
+ - malte@paskuda.biz
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - README.md
64
+ - example/app.rb
65
+ - example/config.ru
66
+ - example/views/index.erb
67
+ - lib/sinatra/browserid.rb
68
+ homepage: https://github.com/onli/sinatra-portier
69
+ licenses: []
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options:
73
+ - "--inline-source"
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 2.6.7
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: Sinatra extension for user authentication with portier
92
+ test_files: []