userbin 0.1.4 → 0.2.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 +4 -4
- data/README.md +73 -1
- data/lib/userbin/authentication.rb +3 -3
- data/lib/userbin/basic_auth.rb +1 -1
- data/lib/userbin/configuration.rb +8 -0
- data/lib/userbin/events.rb +44 -0
- data/lib/userbin/railtie.rb +7 -0
- data/lib/userbin/userbin.rb +3 -51
- data/lib/userbin/version.rb +3 -0
- data/lib/userbin.rb +20 -0
- data/spec/session_spec.rb +4 -2
- data/spec/userbin_spec.rb +4 -2
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bdd5a2e5b60112f95a92dae7500b03dbea87ee9
|
4
|
+
data.tar.gz: 4766121c403480224819add35e1c65e8b37666d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ceebaf8f995b7adc429b83601dead50efea180b7f2410bad462752b548b9402ef5d5ffd1af2840cf763e7cdd593e8edfca0b4fffdc064e3e14d506acdacfb9b3
|
7
|
+
data.tar.gz: 042c0a0bcad92c24e50c05b6adc0929c72736bc0fc75a860b3aa2e63060ea4a08745171dd6985ca1d5bd57656d34140067ca6177768f9d944e090f43c86aa663
|
data/README.md
CHANGED
@@ -1,4 +1,76 @@
|
|
1
1
|
Userbin Ruby gem
|
2
2
|
================
|
3
3
|
|
4
|
-
|
4
|
+
Installation
|
5
|
+
------------
|
6
|
+
|
7
|
+
Begin with signing up at [https://userbin.com](https://userbin.com) to obtain
|
8
|
+
your App ID and API secret.
|
9
|
+
|
10
|
+
For simplicity’s sake, we will use the [Sinatra](http://www.sinatrarb.com/) framework. Start by installing Userbin and Sinatra:
|
11
|
+
|
12
|
+
```bash
|
13
|
+
$ gem install sinatra userbin
|
14
|
+
```
|
15
|
+
|
16
|
+
Now create a file called app.rb, require the gems and configure Userbin.
|
17
|
+
|
18
|
+
Set up your restricted path to which users will be redirected on a successful logins. Browsing to this path or a sub-path will require the user to login. Logging out redirects the user back to the root path.
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
# app.rb
|
22
|
+
require "sinatra"
|
23
|
+
require "userbin"
|
24
|
+
|
25
|
+
Userbin.app_id = "15_DIGIT_APP_ID"
|
26
|
+
Userbin.api_secret = "32_BYTE_API_SECRET"
|
27
|
+
|
28
|
+
use Userbin::Authentication, restricted_path: '/admin'
|
29
|
+
```
|
30
|
+
|
31
|
+
That's it! People are now able sign up and log in to your application.
|
32
|
+
|
33
|
+
Usage
|
34
|
+
-----
|
35
|
+
|
36
|
+
### Signup, login and logout
|
37
|
+
|
38
|
+
To make installation as easy as possible, markup required for the Userbin UI are automatically inserted before the closing </body> and </head> tags in your HTML. It is therefore important that these tags are present on all pages where you want to use the links below.
|
39
|
+
|
40
|
+
These links will open up the [Userbin Widget](https://userbin.com/docs/javascript#widget) with either the login or signup form.
|
41
|
+
|
42
|
+
```html
|
43
|
+
<!-- put this on a public page -->
|
44
|
+
<a class="ub-login">Login</a>
|
45
|
+
or
|
46
|
+
<a class="ub-signup">Signup</a>
|
47
|
+
```
|
48
|
+
|
49
|
+
The logout link will clear the session and redirect the user back to your root path:
|
50
|
+
|
51
|
+
```html
|
52
|
+
<!-- put this on a restricted page -->
|
53
|
+
<a class="ub-logout">Log out</a>
|
54
|
+
```
|
55
|
+
|
56
|
+
See the [Javascript reference](https://userbin.com/docs/javascript#markup) for more info on this markup.
|
57
|
+
|
58
|
+
### The current user
|
59
|
+
|
60
|
+
Userbin keeps track of the currently logged in user:
|
61
|
+
|
62
|
+
```erb
|
63
|
+
Welcome to your account, <%= Userbin.user.email %>
|
64
|
+
```
|
65
|
+
|
66
|
+
To check if a user is logged in, use the following helper:
|
67
|
+
|
68
|
+
```erb
|
69
|
+
<% if Userbin.authenticated? %>
|
70
|
+
You are logged in!
|
71
|
+
<% end %>
|
72
|
+
```
|
73
|
+
|
74
|
+
Documentation
|
75
|
+
-------------
|
76
|
+
For complete documentation go to [userbin.com/docs](https://userbin.com/docs)
|
@@ -18,7 +18,7 @@ module Userbin
|
|
18
18
|
signature, data = Userbin.authenticate_events!(request)
|
19
19
|
|
20
20
|
MultiJson.decode(data)['events'].each do |event|
|
21
|
-
Userbin.trigger(event)
|
21
|
+
Userbin::Events.trigger(event)
|
22
22
|
end
|
23
23
|
|
24
24
|
[ 200, { 'Content-Type' => 'text/html',
|
@@ -51,7 +51,7 @@ module Userbin
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def restrict
|
54
|
-
Userbin.restricted_path || @restricted_path
|
54
|
+
Userbin.config.restricted_path || @restricted_path
|
55
55
|
end
|
56
56
|
|
57
57
|
def link_tags(login_path)
|
@@ -72,7 +72,7 @@ module Userbin
|
|
72
72
|
"https://userbin.com/js/v0"
|
73
73
|
}
|
74
74
|
str = <<-SCRIPT_TAG
|
75
|
-
<script src="#{script_url}?#{Userbin.app_id}"></script>
|
75
|
+
<script src="#{script_url}?#{Userbin.config.app_id}"></script>
|
76
76
|
SCRIPT_TAG
|
77
77
|
end
|
78
78
|
|
data/lib/userbin/basic_auth.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Userbin
|
2
2
|
class BasicAuth < Faraday::Middleware
|
3
3
|
def call(env)
|
4
|
-
value = Base64.encode64([Userbin.app_id, Userbin.api_secret].join(':'))
|
4
|
+
value = Base64.encode64([Userbin.config.app_id, Userbin.config.api_secret].join(':'))
|
5
5
|
value.gsub!("\n", '')
|
6
6
|
env[:request_headers]["Authorization"] = "Basic #{value}"
|
7
7
|
@app.call(env)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Userbin
|
2
|
+
|
3
|
+
Callback = Struct.new(:pattern, :block) do; end
|
4
|
+
|
5
|
+
class Events
|
6
|
+
def self.on(*names, &block)
|
7
|
+
pattern = Regexp.union(names.empty? ? TYPE_LIST.to_a : names)
|
8
|
+
callbacks.each do |callback|
|
9
|
+
if pattern == callback.pattern
|
10
|
+
callbacks.delete(callback)
|
11
|
+
callbacks << Userbin::Callback.new(pattern, block)
|
12
|
+
return
|
13
|
+
end
|
14
|
+
end
|
15
|
+
callbacks << Userbin::Callback.new(pattern, block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.trigger(raw_event)
|
19
|
+
event = Userbin::Event.new(raw_event)
|
20
|
+
callbacks.each do |callback|
|
21
|
+
if event.type =~ callback.pattern
|
22
|
+
object = case event['type']
|
23
|
+
when /^user\./
|
24
|
+
Userbin::User.new(event.object)
|
25
|
+
else
|
26
|
+
event.object
|
27
|
+
end
|
28
|
+
model = event.instance_exec object, &callback.block
|
29
|
+
|
30
|
+
if event.type =~ /user\.created/ && model.respond_to?(:id)
|
31
|
+
object.update_local_id(model.id)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def self.callbacks
|
40
|
+
@callbacks ||= []
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/userbin/userbin.rb
CHANGED
@@ -1,11 +1,4 @@
|
|
1
1
|
module Userbin
|
2
|
-
|
3
|
-
Callback = Struct.new(:pattern, :block) do; end
|
4
|
-
|
5
|
-
class << self
|
6
|
-
attr_accessor :app_id, :api_secret, :restricted_path
|
7
|
-
end
|
8
|
-
|
9
2
|
def self.authenticate_events!(request, now = Time.now)
|
10
3
|
signature, data =
|
11
4
|
request.params.values_at('userbin_signature', 'userbin_data')
|
@@ -43,9 +36,9 @@ module Userbin
|
|
43
36
|
def self.refresh_session(user_id)
|
44
37
|
api_endpoint = ENV["USERBIN_API_ENDPOINT"] || 'https://userbin.com/api/v0'
|
45
38
|
uri = URI("#{api_endpoint}/users/#{user_id}/sessions")
|
46
|
-
uri.user = app_id
|
47
|
-
uri.password = api_secret
|
48
39
|
net = Net::HTTP.post_form(uri, {})
|
40
|
+
uri.user = config.app_id
|
41
|
+
uri.password = config.api_secret
|
49
42
|
[net['X-Userbin-Signature'], net.body]
|
50
43
|
end
|
51
44
|
|
@@ -69,54 +62,13 @@ module Userbin
|
|
69
62
|
current_user
|
70
63
|
end
|
71
64
|
|
72
|
-
# Event handling
|
73
|
-
#
|
74
|
-
class << self
|
75
|
-
def on(*names, &block)
|
76
|
-
pattern = Regexp.union(names.empty? ? TYPE_LIST.to_a : names)
|
77
|
-
callbacks.each do |callback|
|
78
|
-
if pattern == callback.pattern
|
79
|
-
callbacks.delete(callback)
|
80
|
-
callbacks << Userbin::Callback.new(pattern, block)
|
81
|
-
return
|
82
|
-
end
|
83
|
-
end
|
84
|
-
callbacks << Userbin::Callback.new(pattern, block)
|
85
|
-
end
|
86
|
-
|
87
|
-
def trigger(raw_event)
|
88
|
-
event = Userbin::Event.new(raw_event)
|
89
|
-
callbacks.each do |callback|
|
90
|
-
if event.type =~ callback.pattern
|
91
|
-
object = case event['type']
|
92
|
-
when /^user\./
|
93
|
-
Userbin::User.new(event.object)
|
94
|
-
else
|
95
|
-
event.object
|
96
|
-
end
|
97
|
-
model = event.instance_exec object, &callback.block
|
98
|
-
|
99
|
-
if event.type =~ /user\.created/ && model.respond_to?(:id)
|
100
|
-
object.update_local_id(model.id)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
private
|
107
|
-
|
108
|
-
def callbacks
|
109
|
-
@callbacks ||= []
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
65
|
private
|
114
66
|
|
115
67
|
# Checks signature against secret and returns boolean
|
116
68
|
#
|
117
69
|
def self.valid_signature?(signature, data)
|
118
70
|
digest = OpenSSL::Digest::SHA256.new
|
119
|
-
valid = signature == OpenSSL::HMAC.hexdigest(digest, api_secret, data)
|
71
|
+
valid = signature == OpenSSL::HMAC.hexdigest(digest, config.api_secret, data)
|
120
72
|
raise SecurityError, "Invalid signature" unless valid
|
121
73
|
valid
|
122
74
|
end
|
data/lib/userbin.rb
CHANGED
@@ -6,6 +6,8 @@ require 'net/http'
|
|
6
6
|
require "userbin/userbin"
|
7
7
|
require "userbin/basic_auth"
|
8
8
|
|
9
|
+
require "userbin/railtie" if defined?(Rails::Railtie)
|
10
|
+
|
9
11
|
api_endpoint = ENV.fetch('USERBIN_API_ENDPOINT') {
|
10
12
|
"https://userbin.com/api/v0"
|
11
13
|
}
|
@@ -18,6 +20,8 @@ api_endpoint = ENV.fetch('USERBIN_API_ENDPOINT') {
|
|
18
20
|
c.use Userbin::VerifySignature
|
19
21
|
end
|
20
22
|
|
23
|
+
require "userbin/configuration"
|
24
|
+
require "userbin/events"
|
21
25
|
require "userbin/current"
|
22
26
|
require "userbin/session"
|
23
27
|
require "userbin/authentication"
|
@@ -25,4 +29,20 @@ require "userbin/authentication"
|
|
25
29
|
class Userbin::Error < Exception; end
|
26
30
|
class Userbin::SecurityError < Userbin::Error; end
|
27
31
|
|
32
|
+
module Userbin
|
33
|
+
class << self
|
34
|
+
def configure(config_hash=nil)
|
35
|
+
if config_hash
|
36
|
+
config_hash.each do |k,v|
|
37
|
+
config.send("#{k}=", v)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
yield(config) if block_given?
|
42
|
+
end
|
28
43
|
|
44
|
+
def config
|
45
|
+
@configuration ||= Userbin::Configuration.new
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/spec/session_spec.rb
CHANGED
@@ -3,8 +3,10 @@ require 'multi_json'
|
|
3
3
|
|
4
4
|
describe 'Userbin::Session' do
|
5
5
|
before do
|
6
|
-
Userbin.
|
7
|
-
|
6
|
+
Userbin.configure do |config|
|
7
|
+
config.app_id = '100000000000000'
|
8
|
+
config.api_secret = 'test'
|
9
|
+
end
|
8
10
|
end
|
9
11
|
|
10
12
|
before do
|
data/spec/userbin_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: userbin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Johan
|
@@ -89,9 +89,13 @@ extra_rdoc_files: []
|
|
89
89
|
files:
|
90
90
|
- lib/userbin/authentication.rb
|
91
91
|
- lib/userbin/basic_auth.rb
|
92
|
+
- lib/userbin/configuration.rb
|
92
93
|
- lib/userbin/current.rb
|
94
|
+
- lib/userbin/events.rb
|
95
|
+
- lib/userbin/railtie.rb
|
93
96
|
- lib/userbin/session.rb
|
94
97
|
- lib/userbin/userbin.rb
|
98
|
+
- lib/userbin/version.rb
|
95
99
|
- lib/userbin.rb
|
96
100
|
- README.md
|
97
101
|
- spec/session_spec.rb
|