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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 054c324709315f71ea222d681cb6c2c504199ec4
4
- data.tar.gz: 5e283d805bee17f01081990684fee42a6a8e2024
3
+ metadata.gz: cca8bc4a6426e0d967af3cc4746ff35f0ec24d43
4
+ data.tar.gz: 70f0ad7d7a4b46f9603aee952b7451be197c0eba
5
5
  SHA512:
6
- metadata.gz: f767abb26fb9315a7c3e7224c185e58fc254f25330790b02650df6ff73dedcfa6e774d7b35b623e1b415a852d6e4c8f430a225ecda5032203c353731dddd087b
7
- data.tar.gz: 5350abbbb4a1060ecc24cdab082eed44d17933a702e6b6a906b9e91f0659c46d2ae7095a5dddea6ce1a3d00a90c5a4a52b85564fbe070a56d7236b547a6e0f07
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, with users stored in your own database.
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. It takes care of linking accounts across networks, resetting passwords, and keeping everything safe and secure.
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. Add the `userbin` gem to your `Gemfile`
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. Generate configuration
29
+ 1. Configure the Userbin module with the credentials you got from signing up.
30
30
 
31
- ```shell
32
- curl https://lib.userbin.com/install.sh | sh YOUR_APP_ID YOUR_API_SECRET
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 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.
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. **Rack/Sinatra apps only**: Load and activate the Userbin Rack middleware
42
+ 1. Implement getter and setter for your user model.
38
43
 
39
44
  ```ruby
40
- require 'userbin'
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
- Configuration
47
- -------------
75
+ Usage
76
+ -----
48
77
 
49
78
  ### Authenticating
50
79
 
51
- You need to configure Userbin in order to provide the `current_user` model:
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
- This code is run in the context of your application so you have access to your models, session or routes helpers. However, since this code is not run in the context of your application's ApplicationController it doesn't have access
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
- ### Protecting routes
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
- Use `authorize` to control access in controllers:
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 :authorize
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
- Or, you can authorize users in `config/routes.rb`:
106
+ #### Sinatra
83
107
 
84
- ```ruby
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
- constraints Userbin::Protect.new do
91
- mount MagicalWorker
92
- end
93
- end
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 check if a user is logged in, use `user_logged_in?` (or its alias `user_signed_in?` if you prefer Devise conventions)
117
+ To set up routes with user authentication, just wrap them like this:
108
118
 
109
- ```erb
110
- <% if user_logged_in? %>
111
- You are logged in!
112
- <% end %>
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
- An easy way to integrate Userbin is via the [Widget](https://userbin.com/docs/javascript#widget), which will take care of building forms, validating input and provides a drop-in design that adapts nicely to all devices.
130
+ #### Ready-made forms
121
131
 
122
- The Widget is fairly high level, so remember that you can still use Userbin with your [own forms](https://userbin.com) if it doesn't fit your use-case.
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
- - if signed_in?
128
- = current_user.email
129
- = link_to 'Log out', '/', class: 'ub-logout'
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
- ### Protecting resources
136
-
137
- ...
140
+ #### Social buttons
138
141
 
142
+ These require you to first configure your social apps in the dashboard.
139
143
 
140
- Configuration
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
- ### create_user and find_user
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
- ```ruby
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
- config.find_user = Proc.new { |userbin_id|
177
- User.find_by_userbin_id(userbin_id)
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
- ```ruby
184
- rails g migration AddUserbinIdToUsers userbin_id:integer:index
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
- Further configuration and customization
205
- ---------------------------------------
180
+ Admin dashboard
181
+ ---------------
206
182
 
207
- Your Userbin dashboard gives you access to a range of functionality:
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]
@@ -2,7 +2,6 @@ module Userbin
2
2
  class Configuration
3
3
  attr_accessor :create_user
4
4
  attr_accessor :find_user
5
- attr_accessor :lock_file
6
5
  attr_accessor :protected_path
7
6
  attr_accessor :root_path
8
7
  attr_accessor :skip_script_injection
@@ -1,7 +1,10 @@
1
1
  module Userbin
2
2
  module AuthHelpers
3
3
  def authenticate_user!
4
- binding.pry
4
+ unless user_logged_in?
5
+ env['userbin.unauthenticated'] = true
6
+ render nothing: true
7
+ end
5
8
  end
6
9
 
7
10
  def current_user
@@ -61,44 +61,33 @@ module Userbin
61
61
  end
62
62
 
63
63
  def self.current_user
64
- if Userbin.config.lock_file
65
- file = File.open(Userbin.config.lock_file, "a+")
66
- file.flock(File::LOCK_EX)
67
- end
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
- begin
70
- if _current_user
71
- if Userbin.config.find_user
72
- u = Userbin.config.find_user.call(_current_user.id)
73
- if u
74
- u
75
- else
76
- if Userbin.config.create_user
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
- raise ConfigurationError, "You need to implement create_user"
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
@@ -1,3 +1,3 @@
1
1
  module Userbin
2
- VERSION = "0.4.3"
2
+ VERSION = "0.4.4"
3
3
  end
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.3
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johan