userbin 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +95 -119
- data/lib/userbin/authentication.rb +7 -0
- data/lib/userbin/configuration.rb +0 -1
- data/lib/userbin/rails/auth_helpers.rb +4 -1
- data/lib/userbin/userbin.rb +20 -31
- data/lib/userbin/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cca8bc4a6426e0d967af3cc4746ff35f0ec24d43
|
4
|
+
data.tar.gz: 70f0ad7d7a4b46f9603aee952b7451be197c0eba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55cfd4067825ff8db777b0d188c95f7a631a12d201b335503c037ca2c50e25c9f923c41f4d8b3e1cc5532802b473aa161340d3029980fa6f05501a0c06fc7e14
|
7
|
+
data.tar.gz: 46d8f465f92b40b9c606a844850fadee936fc131c70717a5e74693de617d9267b40c4e4fd28426f590a869316d2c941f572008f28e8b0b9f00cc4063c322d498
|
data/README.md
CHANGED
@@ -5,16 +5,16 @@
|
|
5
5
|
Userbin for Ruby
|
6
6
|
================
|
7
7
|
|
8
|
-
Userbin for Ruby adds user authentication, login flows and user management to your **Rails**, **Sinatra** or **Rack** app
|
8
|
+
Userbin for Ruby adds user authentication, login flows and user management to your **Rails**, **Sinatra** or **Rack** app.
|
9
9
|
|
10
|
-
[Userbin](https://userbin.com) provides a set of login, signup, and password reset forms that drop right into your application without any need of styling or writing markup. Connect your users via traditional logins or third party social networks.
|
10
|
+
[Userbin](https://userbin.com) provides a set of login, signup, and password reset forms that drop right into your application without any need of styling or writing markup. Connect your users via traditional logins or third party social networks. We take care of linking accounts across networks, resetting passwords, and keeping everything safe and secure.
|
11
11
|
|
12
12
|
[Create a free account](https://userbin.com) at Userbin to start accepting users in your application.
|
13
13
|
|
14
14
|
Installation
|
15
15
|
------------
|
16
16
|
|
17
|
-
1.
|
17
|
+
1. Add the `userbin` gem to your `Gemfile`
|
18
18
|
|
19
19
|
```ruby
|
20
20
|
gem "userbin"
|
@@ -26,52 +26,76 @@ Installation
|
|
26
26
|
bundle install
|
27
27
|
```
|
28
28
|
|
29
|
-
1.
|
29
|
+
1. Configure the Userbin module with the credentials you got from signing up.
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
In a Rails app, put the following code into a new file at `config/initializers/userbin.rb`, and in Sinatra put it in your main application file and add `require "userbin"`.
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
Userbin.configure do |config|
|
35
|
+
config.app_id = "YOUR_APP_ID"
|
36
|
+
config.api_secret = "YOUR_API_SECRET"
|
37
|
+
end
|
33
38
|
```
|
34
39
|
|
35
|
-
If you don't configure the
|
40
|
+
*If you don't configure the `app_id` and `api_secret`, the Userbin module will read the `USERBIN_APP_ID` and `USERBIN_API_SECRET` environment variables. This may come in handy on Heroku.*
|
36
41
|
|
37
|
-
1.
|
42
|
+
1. Implement getter and setter for your user model.
|
38
43
|
|
39
44
|
```ruby
|
40
|
-
|
45
|
+
# will be called when accessing `current_user`
|
46
|
+
config.find_user = -> (userbin_id) do
|
47
|
+
User.find_by_userbin_id(userbin_id)
|
48
|
+
}
|
49
|
+
|
50
|
+
# will be called when a user signs up
|
51
|
+
config.create_user = -> (profile) do
|
52
|
+
User.create! do |user|
|
53
|
+
user.userbin_id = profile.id
|
54
|
+
user.email = profile.email
|
55
|
+
user.photo = profile.image
|
56
|
+
end
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
*For more information about the available attributes in the profile see the [Userbin profile](https://userbin.com/docs/concepts) documentation.*
|
61
|
+
|
62
|
+
1. Migrate your users (or do it manually if not using Rails) and add a reference to the Userbin profile:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
rails g migration AddUserbinIdToUsers userbin_id:integer:index
|
66
|
+
```
|
41
67
|
|
68
|
+
1. **Rack/Sinatra apps only**: Activate the Userbin Rack middleware
|
69
|
+
|
70
|
+
```ruby
|
42
71
|
use Userbin::Authentication
|
43
72
|
```
|
44
73
|
|
45
74
|
|
46
|
-
|
47
|
-
|
75
|
+
Usage
|
76
|
+
-----
|
48
77
|
|
49
78
|
### Authenticating
|
50
79
|
|
51
|
-
|
52
|
-
|
53
|
-
``` ruby
|
54
|
-
Userbin.configure do
|
55
|
-
current_user do |profile|
|
56
|
-
User.find(profile.uid).first_or_initialize(
|
57
|
-
email: profile.email,
|
58
|
-
image: profile.image
|
59
|
-
)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
```
|
80
|
+
#### Rails
|
63
81
|
|
64
|
-
|
65
|
-
to the methods defined over there.
|
82
|
+
Userbin keeps track of the currently logged in user which can be accessed through `current_user` in controllers, views, and helpers. This automatically taps into libraries such as the authorization solution [CanCan](https://github.com/ryanb/cancan).
|
66
83
|
|
84
|
+
```haml
|
85
|
+
- if logged_in?
|
86
|
+
= current_user.email
|
87
|
+
- else
|
88
|
+
Not logged in
|
89
|
+
```
|
67
90
|
|
68
|
-
|
91
|
+
<!-- **Rack/Sinatra apps only**: Since above helpers aren't available outside Rails, instead use `Userbin.current_user` and `Userbin.logged_in?`.
|
92
|
+
-->
|
69
93
|
|
70
|
-
|
94
|
+
To set up a controller with user authentication, just add this before_filter:
|
71
95
|
|
72
96
|
```ruby
|
73
97
|
class ArticlesController < ApplicationController
|
74
|
-
before_filter :
|
98
|
+
before_filter :authenticate_user!
|
75
99
|
|
76
100
|
def index
|
77
101
|
current_user.articles
|
@@ -79,110 +103,70 @@ class ArticlesController < ApplicationController
|
|
79
103
|
end
|
80
104
|
```
|
81
105
|
|
82
|
-
|
106
|
+
#### Sinatra
|
83
107
|
|
84
|
-
|
85
|
-
Blog::Application.routes.draw do
|
86
|
-
constraints Userbin::Protect.new { |user| user.admin? } do
|
87
|
-
root to: 'admin'
|
88
|
-
end
|
108
|
+
Helpers are accessed through the global Userbin object:
|
89
109
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
Usage
|
97
|
-
-----
|
98
|
-
|
99
|
-
### The current user
|
100
|
-
|
101
|
-
Userbin keeps track of the currently logged in user which can be accessed through the `current_user` property. This automatically taps into libraries such as the authorization solution [CanCan](https://github.com/ryanb/cancan).
|
102
|
-
|
103
|
-
```erb
|
104
|
-
Welcome to your account, <%= current_user.email %>
|
110
|
+
```haml
|
111
|
+
- if Userbin.logged_in?
|
112
|
+
= Userbin.current_user.email
|
113
|
+
- else
|
114
|
+
Not logged in
|
105
115
|
```
|
106
116
|
|
107
|
-
To
|
117
|
+
To set up routes with user authentication, just wrap them like this:
|
108
118
|
|
109
|
-
```
|
110
|
-
|
111
|
-
|
112
|
-
|
119
|
+
```ruby
|
120
|
+
authenticate_user do
|
121
|
+
get "/articles" do
|
122
|
+
"Restricted page that logged in users can access"
|
123
|
+
end
|
124
|
+
end
|
113
125
|
```
|
114
126
|
|
115
127
|
|
116
|
-
**Rack/Sinatra apps only**: Since above helpers aren't available outside Rails, instead use `Userbin.current_user` and `Userbin.user_logged_in?`.
|
117
|
-
|
118
128
|
### Forms
|
119
129
|
|
120
|
-
|
130
|
+
#### Ready-made forms
|
121
131
|
|
122
|
-
|
123
|
-
|
124
|
-
Use `current_user` and `logged_in?` in controllers, views, and helpers:
|
132
|
+
These are opened in a popup.
|
125
133
|
|
126
134
|
```haml
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
- else
|
131
|
-
= link_to 'Sign up', '/dashboard', class: 'ub-signup'
|
132
|
-
= link_to 'Log in', '/dashboard', class: 'ub-login'
|
135
|
+
%a{href: "/account", rel: "login"} Log in
|
136
|
+
%a{href: "/account", rel: "signup"} Sign up
|
137
|
+
%a{href: "/", rel: 'logout'} Log out
|
133
138
|
```
|
134
139
|
|
135
|
-
|
136
|
-
|
137
|
-
...
|
140
|
+
#### Social buttons
|
138
141
|
|
142
|
+
These require you to first configure your social apps in the dashboard.
|
139
143
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
The `Userbin.configure` block supports a range of options additional to the Userbin credentials. None of the following options are mandatory.
|
144
|
-
|
145
|
-
### protected_path
|
146
|
-
|
147
|
-
By default, Userbin reloads the current page on a successful login. If you set the `protected_path` option, users will be redirected to this path instead.
|
148
|
-
|
149
|
-
Once set, this path and any sub-path of it will be protected from unauthenticated users by instead rendering a login form.
|
150
|
-
|
151
|
-
```ruby
|
152
|
-
config.protected_path = '/dashboard'
|
153
|
-
```
|
154
|
-
|
155
|
-
### root_path
|
156
|
-
|
157
|
-
By default, Userbin reloads the current page on a successful logout. If you set the `root_path` option, users will be redirected to this path instead.
|
158
|
-
|
159
|
-
```ruby
|
160
|
-
config.root_path = '/login'
|
144
|
+
```haml
|
145
|
+
%a{href: "/account", rel: "facebook"} Connect with Facebook
|
146
|
+
%a{href: "/account", rel: "twitter"} Connect with Twitter
|
161
147
|
```
|
162
148
|
|
163
|
-
|
164
|
-
|
165
|
-
By default, `current_user` will reference a *limited* Userbin profile, enabling you to work without a database. If you override the functions `create_user` and `find_user`, the current user will instead reference one of your models. The `profile` object is an *extended* Userbin profile. For more information about the available attributes in the profile see the [Userbin profile](https://userbin.com/docs/concepts) documentation.
|
149
|
+
#### Custom forms
|
166
150
|
|
167
|
-
|
168
|
-
config.create_user = Proc.new { |profile|
|
169
|
-
User.create! do |user|
|
170
|
-
user.userbin_id = profile.id
|
171
|
-
user.email = profile.email
|
172
|
-
user.photo = profile.image
|
173
|
-
end
|
174
|
-
}
|
151
|
+
Only
|
175
152
|
|
176
|
-
|
177
|
-
|
178
|
-
|
153
|
+
```haml
|
154
|
+
%form{action: "/account", name: "signup"}
|
155
|
+
%span.errors
|
156
|
+
.form-row
|
157
|
+
%label
|
158
|
+
%span E-mail
|
159
|
+
%input{name: "email", type: "text"}
|
160
|
+
.form-row
|
161
|
+
%label
|
162
|
+
%span Password
|
163
|
+
%input{name: "password", type: "password"}
|
164
|
+
%button{type: "submit"} Sign up
|
179
165
|
```
|
180
166
|
|
181
|
-
You'll need to migrate your users and add a reference to the Userbin profile:
|
182
167
|
|
183
|
-
|
184
|
-
|
185
|
-
```
|
168
|
+
Further configuration
|
169
|
+
---------------------
|
186
170
|
|
187
171
|
### skip_script_injection
|
188
172
|
|
@@ -192,19 +176,11 @@ By default, the Userbin middleware will automatically insert a `<script>` tag be
|
|
192
176
|
config.skip_script_injection = true
|
193
177
|
```
|
194
178
|
|
195
|
-
### lock_file
|
196
|
-
|
197
|
-
By default, no locking is performed to ensure that multiple processes race for finding and creating users. Setting this option in multi-process (not multi-thread) setups like Unicorn is **highly recommended**.
|
198
|
-
|
199
|
-
```ruby
|
200
|
-
config.lock_file = File.join(Rails.root, 'tmp/userbin.lock')
|
201
|
-
```
|
202
|
-
|
203
179
|
|
204
|
-
|
205
|
-
|
180
|
+
Admin dashboard
|
181
|
+
---------------
|
206
182
|
|
207
|
-
Your
|
183
|
+
Your [dashboard](https://userbin.com/dashboard) gives you access to a range of functionality:
|
208
184
|
|
209
185
|
- Configure the appearance of the login widget to feel more integrated with your service
|
210
186
|
- Connect 10+ OAuth providers like Facebook, Github and Google.
|
@@ -13,6 +13,7 @@ module Userbin
|
|
13
13
|
end
|
14
14
|
|
15
15
|
Thread.current[:userbin] = nil
|
16
|
+
env['userbin.unauthenticated'] = false
|
16
17
|
|
17
18
|
request = Rack::Request.new(env)
|
18
19
|
|
@@ -72,7 +73,10 @@ module Userbin
|
|
72
73
|
<!DOCTYPE html>
|
73
74
|
<html>
|
74
75
|
<head>
|
76
|
+
<meta charset="utf-8">
|
77
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
75
78
|
<title>Log in</title>
|
79
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
76
80
|
</head>
|
77
81
|
<body>
|
78
82
|
<a class="ub-login-form"></a>
|
@@ -90,6 +94,9 @@ module Userbin
|
|
90
94
|
def generate_response(env, jwt)
|
91
95
|
status, headers, response = @app.call(env)
|
92
96
|
|
97
|
+
# application stack is responsible for setting userbin.authenticated
|
98
|
+
return render_gateway(env["PATH_INFO"]) if env['userbin.unauthenticated']
|
99
|
+
|
93
100
|
if headers['Content-Type'] && headers['Content-Type']['text/html']
|
94
101
|
if response.respond_to?(:body)
|
95
102
|
body = [*response.body]
|
data/lib/userbin/userbin.rb
CHANGED
@@ -61,44 +61,33 @@ module Userbin
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def self.current_user
|
64
|
-
if
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
if _current_user
|
65
|
+
if Userbin.config.find_user
|
66
|
+
u = Userbin.config.find_user.call(_current_user.id)
|
67
|
+
if u
|
68
|
+
u
|
69
|
+
else
|
70
|
+
if Userbin.config.create_user
|
68
71
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
u
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
# Fetch a full profile from the API. This way we can get more
|
79
|
-
# sensitive details than those stored in the cookie. It also checks
|
80
|
-
# that the user still exists in Userbin.
|
81
|
-
profile = User.find(_current_user.id)
|
82
|
-
|
83
|
-
u = Userbin.config.create_user.call(profile)
|
84
|
-
if u
|
85
|
-
u
|
86
|
-
else
|
87
|
-
_current_user
|
88
|
-
end
|
72
|
+
# Fetch a full profile from the API. This way we can get more
|
73
|
+
# sensitive details than those stored in the cookie. It also checks
|
74
|
+
# that the user still exists in Userbin.
|
75
|
+
profile = User.find(_current_user.id)
|
76
|
+
|
77
|
+
u = Userbin.config.create_user.call(profile)
|
78
|
+
if u
|
79
|
+
u
|
89
80
|
else
|
90
|
-
|
81
|
+
_current_user
|
91
82
|
end
|
83
|
+
else
|
84
|
+
raise ConfigurationError, "You need to implement create_user"
|
92
85
|
end
|
93
|
-
else
|
94
|
-
_current_user
|
95
86
|
end
|
87
|
+
else
|
88
|
+
_current_user
|
96
89
|
end
|
97
|
-
|
98
|
-
ensure
|
99
|
-
file.flock(File::LOCK_UN) if Userbin.config.lock_file
|
100
90
|
end
|
101
|
-
|
102
91
|
end
|
103
92
|
|
104
93
|
def self.user
|
data/lib/userbin/version.rb
CHANGED