sinatra-browserid 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,59 @@
1
+ Sinatra plugin that allows authentication against [BrowserID](https://browserid.org/). BrowserID lets you verify the email identity of a user.
2
+
3
+ To learn more, see how it works [from a users perspective](https://browserid.org/about) and [from a developers perspective](https://github.com/mozilla/browserid/wiki/How-to-Use-BrowserID-on-Your-Site).
4
+
5
+ Note that BrowserID logins are not done from within a form on your site -- you provide a login button, and that will start up the BrowserID login flow (either via a pop-up or an in-browser widget).
6
+
7
+ How to get started:
8
+
9
+ ```ruby
10
+ require 'sinatra/base'
11
+ require 'sinatra/browserid'
12
+
13
+ module MyApp < Sinatra::Base
14
+ register Sinatra::BrowserID
15
+
16
+ set :browserid_login_button, :orange
17
+ set :sessions, true
18
+
19
+ get '/'
20
+ if authorized?
21
+ "Welcome, #{authorized_email}"
22
+ else
23
+ render_login_button
24
+ end
25
+ end
26
+
27
+ get '/secure'
28
+ authorize! # require a user be logged in
29
+
30
+ email = authorized_email # browserid email
31
+ ...
32
+ end
33
+
34
+ get '/logout'
35
+ logout!
36
+
37
+ redirect '/'
38
+ end
39
+ end
40
+ ```
41
+
42
+ See the rdoc for more details on the helper functions. For a functioning
43
+ example app, run <tt>rackup -p $PORT</tt> in the example directory.
44
+
45
+ Available sinatra settings:
46
+
47
+ * <tt>:browserid_login_button</tt>: set to a color (:orange, :red, :blue,
48
+ :green, :grey) or an image URL
49
+ * <tt>:browserid_server</tt>: If you're using an alternate auth provider
50
+ other than https://browserid.org
51
+ * <tt>:browserid_login_url</tt>: URL users get redirected to when the
52
+ <tt>authorize!</tt> helper is called and a user is not logged in
53
+
54
+
55
+ Still TODO:
56
+
57
+ * better error handling
58
+ * local assertion verification (eliminate callback)
59
+
@@ -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
@@ -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,138 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "json"
4
+ require "net/https"
5
+ require "sinatra/base"
6
+
7
+ # This module provides an interface to verify a users email address
8
+ # with browserid.org.
9
+ module Sinatra
10
+ module BrowserID
11
+
12
+ module Helpers
13
+ # Returns true if the current user has logged in and presented
14
+ # a valid assertion.
15
+ def authorized?
16
+ ! session[:browserid_email].nil?
17
+ end
18
+
19
+ # If the current user is not logged in, redirects to a login
20
+ # page. Override the login page by setting the Sinatra
21
+ # option <tt>:browserid_login_url</tt>.
22
+ def authorize!
23
+ session[:authorize_redirect_url] = request.url
24
+ login_url = settings.browserid_login_url
25
+ redirect login_url unless authorized?
26
+ end
27
+
28
+ # Logs out the current user.
29
+ def logout!
30
+ session[:browserid_email] = nil
31
+ end
32
+
33
+ # Returns the BrowserID verified email address, or nil if the
34
+ # user is not logged in.
35
+ def authorized_email
36
+ session[:browserid_email]
37
+ end
38
+
39
+ # Returns the HTML to render the BrowserID login button.
40
+ # Optionally takes a URL parameter for where the user should
41
+ # be redirected to after the assert POST back. You can
42
+ # customize the button image by setting the Sinatra option
43
+ # <tt>:browserid_login_button</tt> to a color (:orange,
44
+ # :red, :blue, :green, :grey) or an actual URL.
45
+ def render_login_button(redirect_url = nil)
46
+ case settings.browserid_login_button
47
+ when :orange, :red, :blue, :green, :grey
48
+ button_url = "#{settings.browserid_url}/i/sign_in_" \
49
+ "#{settings.browserid_login_button.to_s}.png"
50
+ else
51
+ button_url = settings.browserid_login_button
52
+ end
53
+
54
+ if session[:authorize_redirect_url]
55
+ redirect_url = session[:authorize_redirect_url]
56
+ session[:authorize_redirect_url] = nil
57
+ end
58
+ redirect_url ||= request.url
59
+
60
+ template = ERB.new(Templates::LOGIN_BUTTON)
61
+ template.result(binding)
62
+ end
63
+ end # module Helpers
64
+
65
+ def self.registered(app)
66
+ app.helpers BrowserID::Helpers
67
+
68
+ app.set :browserid_url, "https://browserid.org"
69
+ app.set :browserid_login_button, :red
70
+ app.set :browserid_login_url, "/_browserid_login"
71
+
72
+ app.get '/_browserid_login' do
73
+ # TODO(petef): render a page that initiates login without
74
+ # waiting for a user click.
75
+ render_login_button
76
+ end
77
+
78
+ app.post '/_browserid_assert' do
79
+ # TODO(petef): do verification locally, without a callback
80
+ audience = request.host_with_port
81
+ http = Net::HTTP.new("browserid.org", 443)
82
+ http.use_ssl = true
83
+ data = {
84
+ "assertion" => params[:assertion],
85
+ "audience" => audience,
86
+ }
87
+ data_str = data.collect { |k, v| "#{k}=#{v}" }.join("&")
88
+ res, body = http.post("/verify", data_str)
89
+
90
+ # TODO: check res is a 200
91
+ verify = JSON.parse(body) || nil
92
+ if verify.nil?
93
+ # JSON parsing error
94
+ return
95
+ end
96
+
97
+ if verify["status"] != "okay"
98
+ $stderr.puts "status was not OK. #{verify.inspect}"
99
+ return
100
+ end
101
+
102
+ session[:browserid_email] = verify["email"]
103
+ session[:browserid_expires] = verify["expires"].to_f / 1000
104
+
105
+ redirect params[:redirect] || "/"
106
+ end
107
+ end # def self.registered
108
+
109
+ module Templates
110
+ LOGIN_BUTTON = %q{
111
+ <script src="<%= settings.browserid_url %>/include.js" type="text/javascript"></script>
112
+ <script type="text/javascript">
113
+ function _browserid_login() {
114
+ navigator.id.getVerifiedEmail(function(assertion) {
115
+ if (assertion) {
116
+ document.forms._browserid_assert.assertion.value = assertion;
117
+ document.forms._browserid_assert.submit();
118
+ } else {
119
+ // TODO: handle failure case?
120
+ }
121
+ });
122
+ }
123
+ </script>
124
+
125
+ <form name="_browserid_assert" action="/_browserid_assert" method="post">
126
+ <input type="hidden" name="redirect" value="<%= redirect_url %>">
127
+ <input type="hidden" name="assertion" value="">
128
+ </form>
129
+
130
+ <a href="#"><img src="<%= button_url %>" id="browserid_login_button" border=0 onClick="_browserid_login()" /></a>
131
+ }
132
+ end
133
+ end # module BrowserID
134
+
135
+ register BrowserID
136
+ end # module Sinatra
137
+
138
+ #set :sessions, true
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-browserid
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ version: "0.1"
10
+ platform: ruby
11
+ authors:
12
+ - Pete Fritchman
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-10-21 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: sinatra
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 19
29
+ segments:
30
+ - 1
31
+ - 1
32
+ - 0
33
+ version: 1.1.0
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ description:
37
+ email:
38
+ - petef@databits.net
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ files:
46
+ - README.md
47
+ - lib/sinatra/browserid.rb
48
+ - example/app.rb
49
+ - example/config.ru
50
+ - example/views/index.erb
51
+ has_rdoc: true
52
+ homepage: https://github.com/fetep/sinatra-browserid
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --inline-source
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ hash: 3
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ requirements: []
79
+
80
+ rubyforge_project:
81
+ rubygems_version: 1.3.7
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Sinatra extension for user authentication with browserid.org
85
+ test_files: []
86
+