wristband 2.1.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Gemfile.lock +1 -0
- data/LICENSE +20 -0
- data/README.md +52 -29
- data/VERSION +1 -1
- data/app/controllers/application_controller.rb +9 -0
- data/app/controllers/passwords_controller.rb +1 -0
- data/app/controllers/sessions_controller.rb +1 -5
- data/app/controllers/users_controller.rb +0 -6
- data/app/models/user.rb +1 -1
- data/db/migrate/01_create_users_table.rb +4 -4
- data/lib/generators/wristband/wristband_generator.rb +7 -6
- data/lib/wristband/application_extensions.rb +5 -5
- data/lib/wristband/engine.rb +5 -0
- data/lib/wristband/support.rb +26 -5
- data/lib/wristband/user_extensions.rb +14 -14
- data/lib/wristband.rb +16 -10
- data/test/functional/sessions_controller_test.rb +3 -3
- data/test/test_helper.rb +1 -1
- data/test/unit/has_authorities_test.rb +2 -2
- data/test/unit/session_user_test.rb +3 -3
- data/test/unit/user_test.rb +1 -1
- data/test/unit/wristband_test.rb +3 -2
- data/wristband.gemspec +8 -2
- metadata +25 -11
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010-2011 Jack Neto, Scott Tadman, The Working Group Inc
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,40 +1,49 @@
|
|
1
1
|
# Wristband
|
2
|
-
Author: [The Working Group](http://www.theworkinggroup.ca)
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
## What is it?
|
3
|
+
A lightweight solution for two major pains: **User authentication** and **Permissions**.
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
It handles:
|
5
|
+
Summary:
|
11
6
|
|
12
7
|
* Login and logout
|
13
|
-
* Password storage with
|
8
|
+
* Password storage with bcrypt
|
14
9
|
* Password recovery
|
15
|
-
* Remember me
|
10
|
+
* Remember me
|
16
11
|
* Authority definitions
|
12
|
+
* Convert from old MD5 passwords
|
13
|
+
* Extra : easy to use sample models and controlers to get you started!
|
14
|
+
|
15
|
+
---
|
17
16
|
|
18
|
-
|
19
|
-
## Usage
|
17
|
+
## Quick start
|
20
18
|
|
21
19
|
### 1. Add gem definition to your Gemfile:
|
22
20
|
|
23
21
|
config.gem 'wristband'
|
24
22
|
|
25
|
-
### 2. From
|
23
|
+
### 2. From within your Rails project run:
|
26
24
|
|
27
25
|
bundle install
|
28
26
|
|
29
|
-
## Configuration
|
30
|
-
|
31
27
|
|
32
|
-
### In your User model
|
28
|
+
### 3. In your User model
|
33
29
|
|
34
30
|
class User < ActiveRecord::Base
|
35
|
-
wristband
|
31
|
+
wristband
|
36
32
|
end
|
37
33
|
|
34
|
+
### 4. Run the generator for the sample models and controllers
|
35
|
+
|
36
|
+
rails g wristband
|
37
|
+
|
38
|
+
### 4. Run the migrations
|
39
|
+
|
40
|
+
rake db:migrate
|
41
|
+
|
42
|
+
|
43
|
+
---
|
44
|
+
|
45
|
+
## Configuration
|
46
|
+
|
38
47
|
### Options:
|
39
48
|
|
40
49
|
**:login_with** - Array of fields you want to authenticate the user with. *Default: `:email`*
|
@@ -55,7 +64,7 @@ It handles:
|
|
55
64
|
|
56
65
|
wristband :roles => [:regular_user, :admin]
|
57
66
|
|
58
|
-
|
67
|
+
This will give you `user.is_regular_user?` and `user.is_admin?`
|
59
68
|
|
60
69
|
|
61
70
|
**:has_authorities** - The different user authorities are defined in a separate class so as to reduce clutter in the User model itself. *Default: `false`*
|
@@ -64,14 +73,21 @@ It handles:
|
|
64
73
|
|
65
74
|
Look for more details below.
|
66
75
|
|
67
|
-
|
76
|
+
**:legacy_password** - Helps you convert from old legacy passwords to proper encryption passwords. *Default: `[]`*
|
77
|
+
|
78
|
+
Indicate the name of the column with the old passwords and the encryption type.
|
79
|
+
|
80
|
+
wristband :legacy_password => {:column_name => :old_password, :encryption => :md5}
|
81
|
+
|
68
82
|
|
69
|
-
|
70
|
-
2. **Authority Definitions** - Checkout the documentation on wristband/authority_check_rb
|
83
|
+
**:encryption_type** - Allows you to use the less secure SHA1 instead of BCRYPT for backwards compatibility. *Default: `:bcrypt`*
|
71
84
|
|
85
|
+
wristband :encryption_type => :sha1
|
72
86
|
|
73
87
|
|
74
|
-
|
88
|
+
---
|
89
|
+
|
90
|
+
## Generators
|
75
91
|
|
76
92
|
Wristband comes with a generator that provides you with all the files you need to get started
|
77
93
|
|
@@ -87,14 +103,14 @@ This will output something like:
|
|
87
103
|
create app/controllers/sessions_controller.rb
|
88
104
|
create app/controllers/passwords_controller.rb
|
89
105
|
== Views ==
|
90
|
-
create app/views/users/show.html.
|
91
|
-
create app/views/sessions/new.html.
|
92
|
-
create app/views/passwords/new.html.
|
93
|
-
create app/views/passwords/edit.html.
|
106
|
+
create app/views/users/show.html.erb
|
107
|
+
create app/views/sessions/new.html.erb
|
108
|
+
create app/views/passwords/new.html.erb
|
109
|
+
create app/views/passwords/edit.html.erb
|
94
110
|
== User Mailer ==
|
95
111
|
create app/mailers/user_mailer.rb
|
96
|
-
create app/views/user_mailer/password_reset.html.
|
97
|
-
create app/views/user_mailer/password_reset.text.
|
112
|
+
create app/views/user_mailer/password_reset.html.erb
|
113
|
+
create app/views/user_mailer/password_reset.text.erb
|
98
114
|
== Test helper and Dummies ==
|
99
115
|
create test/test_helper.rb
|
100
116
|
create test/dummy/user.rb
|
@@ -114,7 +130,7 @@ The basic columns are defined as such:
|
|
114
130
|
|
115
131
|
create_table :users do |t|
|
116
132
|
t.string :email
|
117
|
-
t.string :
|
133
|
+
t.string :encrypted_password, :limit => 40
|
118
134
|
t.string :password_salt, :limit => 40
|
119
135
|
t.string :perishable_token
|
120
136
|
t.string :remember_token
|
@@ -123,6 +139,7 @@ The basic columns are defined as such:
|
|
123
139
|
end
|
124
140
|
|
125
141
|
|
142
|
+
---
|
126
143
|
# AuthorityCheck
|
127
144
|
|
128
145
|
First you need to tell Wristband that you you want to define permissions for your user:
|
@@ -193,4 +210,10 @@ example:
|
|
193
210
|
|
194
211
|
In this case, the 'allow_if_admin!` method will be called before any checks are performed. If the `allow!` method is executed, all subsequent tests are halted and the check is considered to have passed.
|
195
212
|
|
196
|
-
Have fun!!
|
213
|
+
Have fun!!
|
214
|
+
|
215
|
+
---
|
216
|
+
|
217
|
+
Wristband is released under the MIT license
|
218
|
+
|
219
|
+
Copyright 2009-2011 Jack Neto, Scott Tadman, [The Working Group](http://www.theworkinggroup.ca)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.3.0
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class SessionsController < ApplicationController
|
2
|
-
|
2
|
+
skip_before_filter :login_required, :except => :destroy
|
3
3
|
before_filter :redirect_if_logged_in, :only => [ :new, :create ]
|
4
4
|
before_filter :build_user_session, :only => [ :new, :create ]
|
5
5
|
|
@@ -26,8 +26,4 @@ protected
|
|
26
26
|
def redirect_if_logged_in
|
27
27
|
redirect_to user_path(current_user) if logged_in?
|
28
28
|
end
|
29
|
-
|
30
|
-
def login_required
|
31
|
-
redirect_to login_path unless logged_in?
|
32
|
-
end
|
33
29
|
end
|
data/app/models/user.rb
CHANGED
@@ -14,7 +14,7 @@ class User < ActiveRecord::Base
|
|
14
14
|
:presence => {:message => 'Please enter your email address'},
|
15
15
|
:length => {
|
16
16
|
:within => 6..100,
|
17
|
-
:too_short => "The email address you entered is
|
17
|
+
:too_short => "The email address you entered is too short"
|
18
18
|
},
|
19
19
|
:format => {
|
20
20
|
:with => /^([\w.%-+]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i,
|
@@ -2,10 +2,10 @@ class CreateUsersTable < ActiveRecord::Migration
|
|
2
2
|
def self.up
|
3
3
|
create_table :users do |t|
|
4
4
|
t.string :email
|
5
|
-
t.string :
|
6
|
-
t.string :password_salt
|
5
|
+
t.string :encrypted_password
|
6
|
+
t.string :password_salt
|
7
|
+
t.string :session_token
|
7
8
|
t.string :perishable_token
|
8
|
-
t.string :remember_token
|
9
9
|
t.string :role
|
10
10
|
t.timestamps
|
11
11
|
# --- Other useful fields ---
|
@@ -19,7 +19,7 @@ class CreateUsersTable < ActiveRecord::Migration
|
|
19
19
|
end
|
20
20
|
add_index :users, :email
|
21
21
|
add_index :users, :perishable_token
|
22
|
-
add_index :users, :
|
22
|
+
add_index :users, :session_token
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.down
|
@@ -11,6 +11,7 @@ class WristbandGenerator < Rails::Generators::Base
|
|
11
11
|
|
12
12
|
def generate_controllers
|
13
13
|
puts "\t== Controllers =="
|
14
|
+
copy_file 'app/controllers/application_controller.rb', 'app/controllers/application_controller.rb'
|
14
15
|
copy_file 'app/controllers/users_controller.rb', 'app/controllers/users_controller.rb'
|
15
16
|
copy_file 'app/controllers/sessions_controller.rb', 'app/controllers/sessions_controller.rb'
|
16
17
|
copy_file 'app/controllers/passwords_controller.rb', 'app/controllers/passwords_controller.rb'
|
@@ -18,17 +19,17 @@ class WristbandGenerator < Rails::Generators::Base
|
|
18
19
|
|
19
20
|
def generate_views
|
20
21
|
puts "\t== Views =="
|
21
|
-
copy_file 'app/views/users/show.html.
|
22
|
-
copy_file 'app/views/sessions/new.html.
|
23
|
-
copy_file 'app/views/passwords/new.html.
|
24
|
-
copy_file 'app/views/passwords/edit.html.
|
22
|
+
copy_file 'app/views/users/show.html.erb', 'app/views/users/show.html.erb'
|
23
|
+
copy_file 'app/views/sessions/new.html.erb', 'app/views/sessions/new.html.erb'
|
24
|
+
copy_file 'app/views/passwords/new.html.erb', 'app/views/passwords/new.html.erb'
|
25
|
+
copy_file 'app/views/passwords/edit.html.erb', 'app/views/passwords/edit.html.erb'
|
25
26
|
end
|
26
27
|
|
27
28
|
def generate_user_mailer
|
28
29
|
puts "\t== User Mailer =="
|
29
30
|
copy_file 'app/mailers/user_mailer.rb', 'app/mailers/user_mailer.rb'
|
30
|
-
copy_file'app/views/user_mailer/password_reset.html.
|
31
|
-
copy_file 'app/views/user_mailer/password_reset.text.
|
31
|
+
copy_file'app/views/user_mailer/password_reset.html.erb', 'app/views/user_mailer/password_reset.html.erb'
|
32
|
+
copy_file 'app/views/user_mailer/password_reset.text.erb', 'app/views/user_mailer/password_reset.text.erb'
|
32
33
|
end
|
33
34
|
|
34
35
|
def generate_tests
|
@@ -18,15 +18,15 @@ module Wristband
|
|
18
18
|
def login_as_user(user, remember_me=false, cookie_expires_at = 2.weeks.from_now.utc)
|
19
19
|
self.current_user = user
|
20
20
|
if remember_me
|
21
|
-
token = Support.encrypt_with_salt(user.id.to_s,
|
21
|
+
token = Support.encrypt_with_salt(user.id.to_s, Wristband::Support.random_salt, ::User.wristband[:encryption_type])
|
22
22
|
cookies[:login_token] = { :value => token, :expires => cookie_expires_at}
|
23
|
-
user.update_attribute(:
|
23
|
+
user.update_attribute(:session_token, token)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
# Logs a user out and deletes the
|
27
|
+
# Logs a user out and deletes the session_token.
|
28
28
|
def logout
|
29
|
-
current_user.update_attribute(:
|
29
|
+
current_user.update_attribute(:session_token, nil) if current_user
|
30
30
|
self.current_user = nil
|
31
31
|
cookies.delete(:login_token)
|
32
32
|
reset_session
|
@@ -53,7 +53,7 @@ module Wristband
|
|
53
53
|
# You can use this function as a before filter on your controllers.
|
54
54
|
def login_from_cookie
|
55
55
|
return if (logged_in? or !cookies[:login_token])
|
56
|
-
self.current_user = ::User.
|
56
|
+
self.current_user = ::User.where(:session_token => cookies[:login_token]).first
|
57
57
|
end
|
58
58
|
|
59
59
|
# You can use this function as a before filter on your controllers that require autentication.
|
data/lib/wristband/support.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'bcrypt'
|
2
|
+
|
1
3
|
module Wristband
|
2
4
|
module Support
|
3
5
|
CONSONANTS = %w( b c d f g h j k l m n p qu r s t v w x z ch cr fr nd ng nk nt ph pr rd sh sl sp st th tr )
|
@@ -10,19 +12,38 @@ module Wristband
|
|
10
12
|
end
|
11
13
|
module_function :random_string
|
12
14
|
|
13
|
-
def encrypt_with_salt(password, salt)
|
15
|
+
def encrypt_with_salt(password, salt, encryption_type = :bcrypt)
|
14
16
|
return password unless (salt and !salt.empty?)
|
15
|
-
|
16
|
-
|
17
|
+
|
18
|
+
case encryption_type
|
19
|
+
when :bcrypt
|
20
|
+
BCrypt::Engine.hash_secret([password, salt].join, salt)
|
21
|
+
when :sha1
|
22
|
+
Digest::SHA1.hexdigest([ password, salt ].join)
|
23
|
+
end
|
17
24
|
end
|
18
25
|
module_function :encrypt_with_salt
|
19
26
|
|
20
|
-
def random_salt(length = nil)
|
21
|
-
salt =
|
27
|
+
def random_salt(length = nil, encryption_type = :bcrypt)
|
28
|
+
salt = case encryption_type
|
29
|
+
when :bcrypt
|
30
|
+
BCrypt::Engine.generate_salt
|
31
|
+
when :sha1
|
32
|
+
Digest::SHA1.hexdigest([ rand, rand, random_string(64), rand, rand ].join)
|
33
|
+
end
|
22
34
|
|
23
35
|
length ? salt[0, length] : salt
|
24
36
|
end
|
25
37
|
module_function :random_salt
|
26
38
|
|
39
|
+
def matches?(attempt, password, salt, encryption_type = :bcrypt)
|
40
|
+
case encryption_type
|
41
|
+
when :bcrypt
|
42
|
+
BCrypt::Password.new(password) == [attempt, salt].join
|
43
|
+
when :sha1
|
44
|
+
Digest::SHA1.hexdigest([ attempt, salt ].join) == password
|
45
|
+
end
|
46
|
+
end
|
47
|
+
module_function :matches?
|
27
48
|
end
|
28
49
|
end
|
@@ -11,7 +11,7 @@ module Wristband
|
|
11
11
|
self.execute_authentication_chain(self, self.wristband[:before_authentication_chain]) == false and return
|
12
12
|
user = nil
|
13
13
|
wristband[:login_with_fields].find do |field|
|
14
|
-
user =
|
14
|
+
user = self.where(field => email).first
|
15
15
|
end
|
16
16
|
(user and user.password_match?(password)) || return
|
17
17
|
self.execute_authentication_chain(user, self.wristband[:after_authentication_chain]) == false and return
|
@@ -46,29 +46,29 @@ module Wristband
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def initialize_salt
|
49
|
-
self.password_salt = Wristband::Support.random_salt
|
49
|
+
self.password_salt = Wristband::Support.random_salt(nil, self.class.wristband[:encryption_type])
|
50
50
|
end
|
51
51
|
|
52
52
|
def initialize_token
|
53
|
-
self.
|
53
|
+
self.session_token = Wristband::Support.random_salt(16, self.class.wristband[:encryption_type])
|
54
54
|
end
|
55
55
|
|
56
56
|
def encrypt_password
|
57
|
-
initialize_salt if new_record?
|
58
57
|
return if self.password.blank?
|
59
|
-
|
58
|
+
initialize_salt if new_record?
|
59
|
+
self.send("#{self.class.wristband[:password_column]}=", Wristband::Support.encrypt_with_salt(self.password, self.password_salt, self.class.wristband[:encryption_type]))
|
60
60
|
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
self.password = string
|
62
|
+
def password_match?(password_attempt)
|
63
|
+
if matches_legacy_password?(password_attempt)
|
64
|
+
self.password = password_attempt
|
66
65
|
initialize_salt
|
67
66
|
encrypt_password
|
68
67
|
self.send("#{self.class.wristband[:legacy_password][:column_name]}=", nil)
|
69
68
|
self.save
|
70
69
|
else
|
71
|
-
self.send(self.class.wristband[:password_column])
|
70
|
+
current_pwd = self.send(self.class.wristband[:password_column])
|
71
|
+
Wristband::Support.matches?(password_attempt, current_pwd, self.password_salt, self.class.wristband[:encryption_type])
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
@@ -83,15 +83,15 @@ module Wristband
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
def
|
87
|
-
if (value != read_attribute(:
|
86
|
+
def encrypted_password=(value)
|
87
|
+
if (value != read_attribute(:encrypted_password))
|
88
88
|
initialize_token
|
89
89
|
end
|
90
|
-
write_attribute(:
|
90
|
+
write_attribute(:encrypted_password, value)
|
91
91
|
end
|
92
92
|
|
93
93
|
def reset_perishable_token!
|
94
|
-
update_attribute(:perishable_token, Wristband::Support.random_salt.gsub(/[^A-Za-z0-9]/,''))
|
94
|
+
update_attribute(:perishable_token, Wristband::Support.random_salt(nil, self.class.wristband[:encryption_type]).gsub(/[^A-Za-z0-9]/,''))
|
95
95
|
end
|
96
96
|
end
|
97
97
|
end
|
data/lib/wristband.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
+
if defined?(Rails)
|
2
|
+
require File.expand_path('wristband/engine', File.dirname(__FILE__))
|
3
|
+
end
|
4
|
+
|
5
|
+
|
1
6
|
require 'wristband/user_extensions'
|
2
7
|
require 'wristband/support'
|
3
8
|
require 'wristband/application_extensions'
|
4
9
|
require 'wristband/authority_check'
|
10
|
+
require 'active_record'
|
5
11
|
|
6
12
|
module Wristband
|
7
|
-
|
8
|
-
VERSION = "1.0.5"
|
9
|
-
|
10
|
-
class Engine < ::Rails::Engine; end
|
11
|
-
|
13
|
+
|
12
14
|
class << self
|
13
15
|
def included base #:nodoc:
|
14
16
|
base.extend ClassMethods
|
@@ -23,18 +25,19 @@ module Wristband
|
|
23
25
|
options[:has_authorities] ||= false
|
24
26
|
options[:roles] ||= []
|
25
27
|
options[:legacy_password] ||= {}
|
28
|
+
options[:encryption_type] ||= :bcrypt
|
26
29
|
|
27
30
|
class_eval do
|
28
31
|
include Wristband::UserExtensions
|
29
32
|
|
30
|
-
options[:password_column] ||= :
|
33
|
+
options[:password_column] ||= :encrypted_password
|
31
34
|
|
32
35
|
# These two are used on the login form
|
33
36
|
attr_accessor :password
|
34
37
|
attr_accessor :password_confirmation
|
35
38
|
|
36
39
|
before_save :encrypt_password
|
37
|
-
|
40
|
+
|
38
41
|
# Add roles
|
39
42
|
unless options[:roles].blank?
|
40
43
|
options[:roles].each do |role|
|
@@ -55,7 +58,8 @@ module Wristband
|
|
55
58
|
:after_authentication_chain => [options[:after_authentication]].flatten,
|
56
59
|
:password_column => options[:password_column],
|
57
60
|
:roles => options[:roles],
|
58
|
-
:legacy_password => options[:legacy_password]
|
61
|
+
:legacy_password => options[:legacy_password],
|
62
|
+
:encryption_type => options[:encryption_type]
|
59
63
|
}
|
60
64
|
|
61
65
|
if options[:has_authorities]
|
@@ -81,6 +85,8 @@ module Wristband
|
|
81
85
|
|
82
86
|
end
|
83
87
|
|
84
|
-
|
85
88
|
ActiveRecord::Base.send(:extend, Wristband::ClassMethods)
|
86
|
-
|
89
|
+
|
90
|
+
if defined?(ActionController)
|
91
|
+
ActionController::Base.send(:include, Wristband::ApplicationExtensions)
|
92
|
+
end
|
@@ -77,7 +77,7 @@ class SessionsControllerTest < ActionController::TestCase
|
|
77
77
|
assert_nil cookies[:login_token]
|
78
78
|
assert_nil session[:user_id]
|
79
79
|
@regular_user.reload
|
80
|
-
assert_nil @regular_user.
|
80
|
+
assert_nil @regular_user.session_token
|
81
81
|
assert !@controller.logged_in?
|
82
82
|
assert_nil @controller.current_user
|
83
83
|
end
|
@@ -87,8 +87,8 @@ class SessionsControllerTest < ActionController::TestCase
|
|
87
87
|
def test_remember_me
|
88
88
|
post :create, :session_user => { :email => @regular_user.email, :password => @regular_user.password , :remember_me => '1' }
|
89
89
|
assert_equal request.session[:user_id], @regular_user.id
|
90
|
-
assert_not_nil assigns(:session_user).user.
|
91
|
-
|
90
|
+
assert_not_nil assigns(:session_user).user.session_token
|
91
|
+
assert_not_nil cookies['login_token']
|
92
92
|
end
|
93
93
|
|
94
94
|
end
|
data/test/test_helper.rb
CHANGED
@@ -62,7 +62,7 @@ class ActiveSupport::TestCase
|
|
62
62
|
end
|
63
63
|
|
64
64
|
session[:user_id] = user.id
|
65
|
-
token = Wristband::Support.encrypt_with_salt(user.id.to_s,
|
65
|
+
token = Wristband::Support.encrypt_with_salt(user.id.to_s, Wristband::Support.random_salt)
|
66
66
|
cookies[:login_token] = {
|
67
67
|
:value => token,
|
68
68
|
:expires => 2.weeks.from_now.utc
|
@@ -32,7 +32,7 @@ class NewUser
|
|
32
32
|
extend Wristband::ClassMethods
|
33
33
|
|
34
34
|
attr_accessor :email
|
35
|
-
attr_accessor :
|
35
|
+
attr_accessor :encrypted_password
|
36
36
|
attr_accessor :password_salt
|
37
37
|
attr_accessor :role
|
38
38
|
|
@@ -41,7 +41,7 @@ class NewUser
|
|
41
41
|
def initialize(params = {})
|
42
42
|
if params
|
43
43
|
@email = params[:email]
|
44
|
-
@
|
44
|
+
@encrypted_password = params[:encrypted_password]
|
45
45
|
@password_salt = params[:password_salt]
|
46
46
|
@role = params[:role]
|
47
47
|
end
|
@@ -31,9 +31,9 @@ class SessionUserTest < ActiveSupport::TestCase
|
|
31
31
|
:password => user.password
|
32
32
|
)
|
33
33
|
assert session_user.valid?
|
34
|
-
assert_equal
|
35
|
-
assert_equal
|
36
|
-
assert_equal
|
34
|
+
assert_equal user.email, session_user.email
|
35
|
+
assert_equal user.password, session_user.password
|
36
|
+
assert_equal user, session_user.user
|
37
37
|
end
|
38
38
|
|
39
39
|
def test_failed_authentication
|
data/test/unit/user_test.rb
CHANGED
@@ -19,7 +19,7 @@ class UserTest < ActiveSupport::TestCase
|
|
19
19
|
assert_errors_on user, :email, :password, :role
|
20
20
|
assert user.errors[:email].include?("Please enter your email address")
|
21
21
|
assert user.errors[:email].include?("The email address you entered is not valid")
|
22
|
-
assert user.errors[:email].include?("The email address you entered is
|
22
|
+
assert user.errors[:email].include?("The email address you entered is too short")
|
23
23
|
assert user.errors[:password].include?("Please choose a password")
|
24
24
|
assert user.errors[:password].include?("The password you entered is too short (minimum is 4 characters)")
|
25
25
|
assert user.errors[:role].include?("can't be blank")
|
data/test/unit/wristband_test.rb
CHANGED
@@ -10,9 +10,9 @@ class WristbandTest < ActiveSupport::TestCase
|
|
10
10
|
initialize_salt
|
11
11
|
initialize_token
|
12
12
|
encrypt_password
|
13
|
+
encrypted_password=
|
13
14
|
password_match?
|
14
15
|
matches_legacy_password?
|
15
|
-
password_hash=
|
16
16
|
is_admin?
|
17
17
|
is_regular_user?
|
18
18
|
}.each do |method|
|
@@ -45,9 +45,10 @@ class WristbandTest < ActiveSupport::TestCase
|
|
45
45
|
assert_equal User.wristband[:login_with_fields], [:email]
|
46
46
|
assert_equal User.wristband[:before_authentication_chain], []
|
47
47
|
assert_equal User.wristband[:after_authentication_chain], []
|
48
|
-
assert_equal User.wristband[:password_column], :
|
48
|
+
assert_equal User.wristband[:password_column], :encrypted_password
|
49
49
|
assert_equal User.wristband[:roles], ['admin', 'regular_user']
|
50
50
|
assert_equal User.wristband[:legacy_password], {}
|
51
|
+
assert_equal User.wristband[:encryption_type], :bcrypt
|
51
52
|
end
|
52
53
|
|
53
54
|
def test_authentication_by_email
|
data/wristband.gemspec
CHANGED
@@ -5,20 +5,22 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{wristband}
|
8
|
-
s.version = "2.
|
8
|
+
s.version = "2.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jack Neto", "The Working Group Inc"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-10-31}
|
13
13
|
s.description = %q{Provides a starting point for user authentication}
|
14
14
|
s.email = %q{jack@theworkinggroup.ca}
|
15
15
|
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
16
17
|
"README.md"
|
17
18
|
]
|
18
19
|
s.files = [
|
19
20
|
".DS_Store",
|
20
21
|
"Gemfile",
|
21
22
|
"Gemfile.lock",
|
23
|
+
"LICENSE",
|
22
24
|
"README.md",
|
23
25
|
"Rakefile",
|
24
26
|
"VERSION",
|
@@ -53,6 +55,7 @@ Gem::Specification.new do |s|
|
|
53
55
|
"lib/wristband.rb",
|
54
56
|
"lib/wristband/application_extensions.rb",
|
55
57
|
"lib/wristband/authority_check.rb",
|
58
|
+
"lib/wristband/engine.rb",
|
56
59
|
"lib/wristband/support.rb",
|
57
60
|
"lib/wristband/user_extensions.rb",
|
58
61
|
"public/robots.txt",
|
@@ -78,17 +81,20 @@ Gem::Specification.new do |s|
|
|
78
81
|
|
79
82
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
80
83
|
s.add_runtime_dependency(%q<rails>, [">= 3.1.0"])
|
84
|
+
s.add_runtime_dependency(%q<bcrypt-ruby>, [">= 0"])
|
81
85
|
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
82
86
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
83
87
|
s.add_runtime_dependency(%q<rails>, [">= 3.1.0"])
|
84
88
|
else
|
85
89
|
s.add_dependency(%q<rails>, [">= 3.1.0"])
|
90
|
+
s.add_dependency(%q<bcrypt-ruby>, [">= 0"])
|
86
91
|
s.add_dependency(%q<sqlite3>, [">= 0"])
|
87
92
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
88
93
|
s.add_dependency(%q<rails>, [">= 3.1.0"])
|
89
94
|
end
|
90
95
|
else
|
91
96
|
s.add_dependency(%q<rails>, [">= 3.1.0"])
|
97
|
+
s.add_dependency(%q<bcrypt-ruby>, [">= 0"])
|
92
98
|
s.add_dependency(%q<sqlite3>, [">= 0"])
|
93
99
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
94
100
|
s.add_dependency(%q<rails>, [">= 3.1.0"])
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wristband
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,12 +10,12 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-10-31 00:00:00.000000000 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rails
|
18
|
-
requirement: &
|
18
|
+
requirement: &2159686220 !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - ! '>='
|
@@ -23,10 +23,21 @@ dependencies:
|
|
23
23
|
version: 3.1.0
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
|
-
version_requirements: *
|
26
|
+
version_requirements: *2159686220
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bcrypt-ruby
|
29
|
+
requirement: &2159684840 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: *2159684840
|
27
38
|
- !ruby/object:Gem::Dependency
|
28
39
|
name: sqlite3
|
29
|
-
requirement: &
|
40
|
+
requirement: &2159684020 !ruby/object:Gem::Requirement
|
30
41
|
none: false
|
31
42
|
requirements:
|
32
43
|
- - ! '>='
|
@@ -34,10 +45,10 @@ dependencies:
|
|
34
45
|
version: '0'
|
35
46
|
type: :development
|
36
47
|
prerelease: false
|
37
|
-
version_requirements: *
|
48
|
+
version_requirements: *2159684020
|
38
49
|
- !ruby/object:Gem::Dependency
|
39
50
|
name: jeweler
|
40
|
-
requirement: &
|
51
|
+
requirement: &2159683300 !ruby/object:Gem::Requirement
|
41
52
|
none: false
|
42
53
|
requirements:
|
43
54
|
- - ! '>='
|
@@ -45,10 +56,10 @@ dependencies:
|
|
45
56
|
version: '0'
|
46
57
|
type: :development
|
47
58
|
prerelease: false
|
48
|
-
version_requirements: *
|
59
|
+
version_requirements: *2159683300
|
49
60
|
- !ruby/object:Gem::Dependency
|
50
61
|
name: rails
|
51
|
-
requirement: &
|
62
|
+
requirement: &2159682800 !ruby/object:Gem::Requirement
|
52
63
|
none: false
|
53
64
|
requirements:
|
54
65
|
- - ! '>='
|
@@ -56,17 +67,19 @@ dependencies:
|
|
56
67
|
version: 3.1.0
|
57
68
|
type: :runtime
|
58
69
|
prerelease: false
|
59
|
-
version_requirements: *
|
70
|
+
version_requirements: *2159682800
|
60
71
|
description: Provides a starting point for user authentication
|
61
72
|
email: jack@theworkinggroup.ca
|
62
73
|
executables: []
|
63
74
|
extensions: []
|
64
75
|
extra_rdoc_files:
|
76
|
+
- LICENSE
|
65
77
|
- README.md
|
66
78
|
files:
|
67
79
|
- .DS_Store
|
68
80
|
- Gemfile
|
69
81
|
- Gemfile.lock
|
82
|
+
- LICENSE
|
70
83
|
- README.md
|
71
84
|
- Rakefile
|
72
85
|
- VERSION
|
@@ -101,6 +114,7 @@ files:
|
|
101
114
|
- lib/wristband.rb
|
102
115
|
- lib/wristband/application_extensions.rb
|
103
116
|
- lib/wristband/authority_check.rb
|
117
|
+
- lib/wristband/engine.rb
|
104
118
|
- lib/wristband/support.rb
|
105
119
|
- lib/wristband/user_extensions.rb
|
106
120
|
- public/robots.txt
|
@@ -130,7 +144,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
144
|
version: '0'
|
131
145
|
segments:
|
132
146
|
- 0
|
133
|
-
hash:
|
147
|
+
hash: 2613277751533457790
|
134
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
149
|
none: false
|
136
150
|
requirements:
|