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 +7 -0
- data/README.md +53 -0
- data/example/app.rb +28 -0
- data/example/config.ru +2 -0
- data/example/views/index.erb +21 -0
- data/lib/sinatra/browserid.rb +63 -0
- metadata +92 -0
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,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: []
|