authenticate 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/Gemfile +0 -4
  4. data/Gemfile.lock +0 -5
  5. data/README.md +149 -78
  6. data/app/controllers/authenticate/passwords_controller.rb +130 -0
  7. data/app/controllers/authenticate/sessions_controller.rb +46 -0
  8. data/app/controllers/authenticate/users_controller.rb +46 -0
  9. data/app/mailers/authenticate_mailer.rb +13 -0
  10. data/app/views/authenticate_mailer/change_password.html.erb +8 -0
  11. data/app/views/authenticate_mailer/change_password.text.erb +5 -0
  12. data/app/views/layouts/application.html.erb +25 -0
  13. data/app/views/passwords/edit.html.erb +20 -0
  14. data/app/views/passwords/new.html.erb +19 -0
  15. data/app/views/sessions/new.html.erb +28 -0
  16. data/app/views/users/new.html.erb +24 -0
  17. data/authenticate.gemspec +1 -2
  18. data/config/locales/authenticate.en.yml +57 -0
  19. data/config/routes.rb +14 -1
  20. data/lib/authenticate/callbacks/brute_force.rb +5 -9
  21. data/lib/authenticate/callbacks/lifetimed.rb +1 -0
  22. data/lib/authenticate/callbacks/timeoutable.rb +2 -1
  23. data/lib/authenticate/callbacks/trackable.rb +1 -3
  24. data/lib/authenticate/configuration.rb +94 -5
  25. data/lib/authenticate/controller.rb +69 -9
  26. data/lib/authenticate/debug.rb +1 -0
  27. data/lib/authenticate/engine.rb +4 -11
  28. data/lib/authenticate/model/brute_force.rb +22 -3
  29. data/lib/authenticate/model/db_password.rb +12 -7
  30. data/lib/authenticate/model/email.rb +8 -10
  31. data/lib/authenticate/model/password_reset.rb +76 -0
  32. data/lib/authenticate/model/timeoutable.rb +9 -3
  33. data/lib/authenticate/model/trackable.rb +1 -1
  34. data/lib/authenticate/model/username.rb +21 -8
  35. data/lib/authenticate/modules.rb +19 -1
  36. data/lib/authenticate/session.rb +3 -1
  37. data/lib/authenticate/user.rb +6 -1
  38. data/lib/authenticate/version.rb +1 -1
  39. data/lib/generators/authenticate/controllers/USAGE +12 -0
  40. data/lib/generators/authenticate/controllers/controllers_generator.rb +21 -0
  41. data/lib/generators/authenticate/install/USAGE +7 -0
  42. data/lib/generators/authenticate/install/install_generator.rb +140 -0
  43. data/lib/generators/authenticate/install/templates/authenticate.rb +22 -0
  44. data/lib/generators/authenticate/install/templates/db/migrate/add_authenticate_brute_force_to_users.rb +6 -0
  45. data/lib/generators/authenticate/install/templates/db/migrate/add_authenticate_password_reset_to_users.rb +7 -0
  46. data/lib/generators/authenticate/install/templates/db/migrate/add_authenticate_timeoutable_to_users.rb +5 -0
  47. data/lib/generators/authenticate/install/templates/db/migrate/add_authenticate_to_users.rb +21 -0
  48. data/lib/generators/authenticate/install/templates/db/migrate/create_users.rb +14 -0
  49. data/lib/generators/authenticate/install/templates/user.rb +3 -0
  50. data/lib/generators/authenticate/routes/USAGE +8 -0
  51. data/lib/generators/authenticate/routes/routes_generator.rb +32 -0
  52. data/lib/generators/authenticate/routes/templates/routes.rb +10 -0
  53. data/lib/generators/authenticate/views/USAGE +13 -0
  54. data/lib/generators/authenticate/views/views_generator.rb +21 -0
  55. data/spec/dummy/app/controllers/application_controller.rb +1 -0
  56. data/spec/dummy/config/initializers/authenticate.rb +12 -5
  57. data/spec/dummy/db/development.sqlite3 +0 -0
  58. data/spec/dummy/db/migrate/20160130192728_create_users.rb +18 -0
  59. data/spec/dummy/db/migrate/20160130192729_add_authenticate_brute_force_to_users.rb +6 -0
  60. data/spec/dummy/db/migrate/20160130192730_add_authenticate_timeoutable_to_users.rb +5 -0
  61. data/spec/dummy/db/migrate/20160130192731_add_authenticate_password_reset_to_users.rb +7 -0
  62. data/spec/dummy/db/schema.rb +14 -10
  63. data/spec/dummy/db/test.sqlite3 +0 -0
  64. data/spec/factories/users.rb +5 -8
  65. data/spec/model/brute_force_spec.rb +63 -0
  66. data/spec/model/session_spec.rb +4 -0
  67. data/spec/model/user_spec.rb +15 -5
  68. data/spec/spec_helper.rb +2 -1
  69. metadata +41 -9
  70. data/app/controllers/.keep +0 -0
  71. data/app/mailers/.keep +0 -0
  72. data/app/views/.keep +0 -0
  73. data/spec/dummy/db/migrate/20160120003910_create_users.rb +0 -18
@@ -0,0 +1,18 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def change
3
+
4
+ create_table :users do |t|
5
+ t.string :email
6
+ t.string :encrypted_password, limit: 128
7
+ t.string :session_token, limit: 128
8
+ t.datetime :current_sign_in_at
9
+ t.string :current_sign_in_ip, limit: 128
10
+ t.datetime :last_sign_in_at
11
+ t.string :last_sign_in_ip, limit: 128
12
+ t.integer :sign_in_count
13
+ end
14
+
15
+ add_index :users, :email
16
+ add_index :users, :session_token
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ class AddAuthenticateBruteForceToUsers < ActiveRecord::Migration
2
+ def change
3
+ add_column :users, :failed_logins_count, :integer, default: 0
4
+ add_column :users, :lock_expires_at, :datetime, default: nil
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddAuthenticateTimeoutableToUsers < ActiveRecord::Migration
2
+ def change
3
+ add_column :users, :last_access_at, :datetime, default: nil
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class AddAuthenticatePasswordResetToUsers < ActiveRecord::Migration
2
+ def change
3
+ add_column :users, :password_reset_token, :string, default: nil
4
+ add_column :users, :password_reset_sent_at, :datetime, default: nil
5
+ end
6
+ end
7
+
@@ -11,21 +11,25 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20160120003910) do
14
+ ActiveRecord::Schema.define(version: 20160130192731) do
15
15
 
16
16
  create_table "users", force: :cascade do |t|
17
17
  t.string "email"
18
- t.string "encrypted_password"
19
- t.string "session_token"
20
- t.datetime "session_expiration"
21
- t.integer "sign_in_count"
18
+ t.string "encrypted_password", limit: 128
19
+ t.string "session_token", limit: 128
20
+ t.datetime "current_sign_in_at"
21
+ t.string "current_sign_in_ip", limit: 128
22
22
  t.datetime "last_sign_in_at"
23
- t.string "last_sign_in_ip"
23
+ t.string "last_sign_in_ip", limit: 128
24
+ t.integer "sign_in_count"
25
+ t.integer "failed_logins_count", default: 0
26
+ t.datetime "lock_expires_at"
24
27
  t.datetime "last_access_at"
25
- t.datetime "current_sign_in_at"
26
- t.string "current_sign_in_ip"
27
- t.datetime "created_at", null: false
28
- t.datetime "updated_at", null: false
28
+ t.string "password_reset_token"
29
+ t.datetime "password_reset_sent_at"
29
30
  end
30
31
 
32
+ add_index "users", ["email"], name: "index_users_on_email"
33
+ add_index "users", ["session_token"], name: "index_users_on_session_token"
34
+
31
35
  end
Binary file
@@ -1,3 +1,5 @@
1
+ require 'authenticate/user'
2
+
1
3
  FactoryGirl.define do
2
4
  sequence :email do |n|
3
5
  "user#{n}@example.com"
@@ -11,13 +13,8 @@ FactoryGirl.define do
11
13
  session_token 'this_is_a_big_fake_long_token'
12
14
  end
13
15
 
14
- # trait :with_forgotten_password do
15
- # confirmation_token Clearance::Token.new
16
- # end
17
-
18
- # factory :user_with_optional_password, class: 'UserWithOptionalPassword' do
19
- # password nil
20
- # encrypted_password ''
21
- # end
16
+ trait :with_forgotten_password do
17
+ password_reset_token Authenticate::Token.new
18
+ end
22
19
  end
23
20
  end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ require 'authenticate/model/brute_force'
3
+
4
+
5
+ describe Authenticate::Model::BruteForce do
6
+ before {
7
+ Authenticate.configure do |config|
8
+ config.max_consecutive_bad_logins_allowed = 2
9
+ config.bad_login_lockout_period = 2.minutes
10
+ end
11
+ }
12
+
13
+ it 'knows when it is locked' do
14
+ user = User.new
15
+ expect(user.locked?).to be_falsey
16
+ user.lock!
17
+ expect(user.locked?).to be_truthy
18
+ end
19
+
20
+ context '#register_failed_login!' do
21
+ it 'locks when failed login count reaches max' do
22
+ user = User.new
23
+ user.register_failed_login!
24
+ user.register_failed_login!
25
+ expect(user.locked?).to be_truthy
26
+ end
27
+
28
+ it 'sets lockout period' do
29
+ user = User.new
30
+ user.register_failed_login!
31
+ user.register_failed_login!
32
+ expect(user.lock_expires_at).to_not be_nil
33
+ end
34
+ end
35
+
36
+ context '#lock!' do
37
+ it 'before lock, locked_expires_at is nil' do
38
+ user = User.new
39
+ expect(user.lock_expires_at).to be_nil
40
+ end
41
+
42
+ it 'sets locked_expires_at' do
43
+ user = User.new
44
+ user.lock!
45
+ expect(user.lock_expires_at).to_not be_nil
46
+ expect(user.lock_expires_at).to be_utc
47
+ end
48
+ end
49
+
50
+ context '#unlock!' do
51
+ let(:user) { User.new }
52
+ before(:each) {
53
+ user.lock!
54
+ user.unlock!
55
+ }
56
+ it 'zeros failed_logins_count' do
57
+ expect(user.failed_logins_count).to be(0)
58
+ end
59
+ it 'nils lock_expires_at' do
60
+ expect(user.lock_expires_at).to be_nil
61
+ end
62
+ end
63
+ end
@@ -41,6 +41,9 @@ describe Authenticate::Session do
41
41
  end
42
42
  end
43
43
  it 'passes the failure status to the block when login fails' do
44
+ Authenticate.configure do |config|
45
+ config.max_consecutive_bad_logins_allowed = nil
46
+ end
44
47
  session = Authenticate::Session.new(mock_request, {})
45
48
  session.login nil do |status|
46
49
  expect(status.success?).to eq false
@@ -80,6 +83,7 @@ describe Authenticate::Session do
80
83
 
81
84
  def mock_request
82
85
  req = double("request")
86
+ allow(req).to receive(:params)
83
87
  allow(req).to receive(:remote_ip).and_return('111.111.111.111')
84
88
  return req
85
89
  end
@@ -2,11 +2,21 @@ require 'spec_helper'
2
2
 
3
3
  describe Authenticate::User do
4
4
 
5
- it 'generates a new session token' do
6
- user = create(:user, :with_session_token)
7
- old_token = user.session_token
8
- user.generate_session_token
9
- expect(user.session_token).to_not eq old_token
5
+ context 'session tokens' do
6
+ it 'generates a new session token' do
7
+ user = create(:user, :with_session_token)
8
+ old_token = user.session_token
9
+ user.generate_session_token
10
+ expect(user.session_token).to_not eq old_token
11
+ end
12
+
13
+ it 'saves user when reset_session_token! called' do
14
+ user = create(:user, :with_session_token)
15
+ old_token = user.session_token
16
+ user.reset_session_token!
17
+ new_user = User.find(user.id)
18
+ expect(new_user.session_token).to_not eq old_token
19
+ end
10
20
  end
11
21
 
12
22
  end
data/spec/spec_helper.rb CHANGED
@@ -12,11 +12,12 @@ MY_ORM = :active_record
12
12
 
13
13
 
14
14
  require 'rails/all'
15
- # require 'rspec'
16
15
  require 'rspec/rails'
17
16
  require 'factory_girl_rails'
18
17
  # require 'timecop'
19
18
 
19
+ require 'authenticate'
20
+
20
21
  ENGINE_RAILS_ROOT=File.join(File.dirname(__FILE__), '../')
21
22
  Dir[File.join(ENGINE_RAILS_ROOT, "spec/factories/**/*.rb")].each {|f| require f }
22
23
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authenticate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Tomich
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-23 00:00:00.000000000 Z
11
+ date: 2016-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bcrypt
@@ -73,7 +73,7 @@ dependencies:
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
75
  - !ruby/object:Gem::Dependency
76
- name: rspec
76
+ name: rspec-rails
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - ">="
@@ -87,7 +87,7 @@ dependencies:
87
87
  - !ruby/object:Gem::Version
88
88
  version: '0'
89
89
  - !ruby/object:Gem::Dependency
90
- name: rspec-rails
90
+ name: factory_girl_rails
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - ">="
@@ -101,7 +101,7 @@ dependencies:
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
103
  - !ruby/object:Gem::Dependency
104
- name: factory_girl_rails
104
+ name: pry
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - ">="
@@ -126,6 +126,7 @@ files:
126
126
  - ".gitignore"
127
127
  - ".rspec"
128
128
  - ".ruby-version"
129
+ - CHANGELOG.md
129
130
  - Gemfile
130
131
  - Gemfile.lock
131
132
  - LICENSE
@@ -135,13 +136,22 @@ files:
135
136
  - app/assets/images/authenticate/.keep
136
137
  - app/assets/javascripts/authenticate/.keep
137
138
  - app/assets/stylesheets/authenticate/.keep
138
- - app/controllers/.keep
139
+ - app/controllers/authenticate/passwords_controller.rb
140
+ - app/controllers/authenticate/sessions_controller.rb
141
+ - app/controllers/authenticate/users_controller.rb
139
142
  - app/helpers/.keep
140
- - app/mailers/.keep
143
+ - app/mailers/authenticate_mailer.rb
141
144
  - app/models/.keep
142
- - app/views/.keep
145
+ - app/views/authenticate_mailer/change_password.html.erb
146
+ - app/views/authenticate_mailer/change_password.text.erb
147
+ - app/views/layouts/application.html.erb
148
+ - app/views/passwords/edit.html.erb
149
+ - app/views/passwords/new.html.erb
150
+ - app/views/sessions/new.html.erb
151
+ - app/views/users/new.html.erb
143
152
  - authenticate.gemspec
144
153
  - bin/rails
154
+ - config/locales/authenticate.en.yml
145
155
  - config/routes.rb
146
156
  - lib/authenticate.rb
147
157
  - lib/authenticate/callbacks/authenticatable.rb
@@ -160,6 +170,7 @@ files:
160
170
  - lib/authenticate/model/db_password.rb
161
171
  - lib/authenticate/model/email.rb
162
172
  - lib/authenticate/model/lifetimed.rb
173
+ - lib/authenticate/model/password_reset.rb
163
174
  - lib/authenticate/model/timeoutable.rb
164
175
  - lib/authenticate/model/trackable.rb
165
176
  - lib/authenticate/model/username.rb
@@ -168,6 +179,22 @@ files:
168
179
  - lib/authenticate/token.rb
169
180
  - lib/authenticate/user.rb
170
181
  - lib/authenticate/version.rb
182
+ - lib/generators/authenticate/controllers/USAGE
183
+ - lib/generators/authenticate/controllers/controllers_generator.rb
184
+ - lib/generators/authenticate/install/USAGE
185
+ - lib/generators/authenticate/install/install_generator.rb
186
+ - lib/generators/authenticate/install/templates/authenticate.rb
187
+ - lib/generators/authenticate/install/templates/db/migrate/add_authenticate_brute_force_to_users.rb
188
+ - lib/generators/authenticate/install/templates/db/migrate/add_authenticate_password_reset_to_users.rb
189
+ - lib/generators/authenticate/install/templates/db/migrate/add_authenticate_timeoutable_to_users.rb
190
+ - lib/generators/authenticate/install/templates/db/migrate/add_authenticate_to_users.rb
191
+ - lib/generators/authenticate/install/templates/db/migrate/create_users.rb
192
+ - lib/generators/authenticate/install/templates/user.rb
193
+ - lib/generators/authenticate/routes/USAGE
194
+ - lib/generators/authenticate/routes/routes_generator.rb
195
+ - lib/generators/authenticate/routes/templates/routes.rb
196
+ - lib/generators/authenticate/views/USAGE
197
+ - lib/generators/authenticate/views/views_generator.rb
171
198
  - lib/tasks/authenticate_tasks.rake
172
199
  - spec/configuration_spec.rb
173
200
  - spec/dummy/README.rdoc
@@ -208,7 +235,10 @@ files:
208
235
  - spec/dummy/config/routes.rb
209
236
  - spec/dummy/config/secrets.yml
210
237
  - spec/dummy/db/development.sqlite3
211
- - spec/dummy/db/migrate/20160120003910_create_users.rb
238
+ - spec/dummy/db/migrate/20160130192728_create_users.rb
239
+ - spec/dummy/db/migrate/20160130192729_add_authenticate_brute_force_to_users.rb
240
+ - spec/dummy/db/migrate/20160130192730_add_authenticate_timeoutable_to_users.rb
241
+ - spec/dummy/db/migrate/20160130192731_add_authenticate_password_reset_to_users.rb
212
242
  - spec/dummy/db/schema.rb
213
243
  - spec/dummy/db/test.sqlite3
214
244
  - spec/dummy/lib/assets/.keep
@@ -218,6 +248,7 @@ files:
218
248
  - spec/dummy/public/500.html
219
249
  - spec/dummy/public/favicon.ico
220
250
  - spec/factories/users.rb
251
+ - spec/model/brute_force_spec.rb
221
252
  - spec/model/session_spec.rb
222
253
  - spec/model/token_spec.rb
223
254
  - spec/model/user_spec.rb
@@ -250,6 +281,7 @@ specification_version: 4
250
281
  summary: Rails authentication with email & password
251
282
  test_files:
252
283
  - spec/configuration_spec.rb
284
+ - spec/model/brute_force_spec.rb
253
285
  - spec/model/session_spec.rb
254
286
  - spec/model/token_spec.rb
255
287
  - spec/model/user_spec.rb
File without changes
data/app/mailers/.keep DELETED
File without changes
data/app/views/.keep DELETED
File without changes
@@ -1,18 +0,0 @@
1
- class CreateUsers < ActiveRecord::Migration
2
- def change
3
- create_table :users do |t|
4
- t.string :email
5
- t.string :encrypted_password
6
- t.string :session_token
7
- t.datetime :session_expiration
8
- t.integer :sign_in_count
9
- t.datetime :last_sign_in_at
10
- t.string :last_sign_in_ip
11
- t.datetime :last_access_at
12
- t.datetime :current_sign_in_at
13
- t.string :current_sign_in_ip
14
-
15
- t.timestamps null: false
16
- end
17
- end
18
- end