authenticate 0.7.1 → 0.7.2

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: 385cdcc42a02c88733f5236180cbf2f8fe9b26cd
4
- data.tar.gz: 467b36878265dd502f6fd88fd0fe4eb8075ff2a4
3
+ metadata.gz: 4b20e579605068181100a79652e0d2f59b40d7a5
4
+ data.tar.gz: 4cca1df92302dee427285af9453c9489fe9b985e
5
5
  SHA512:
6
- metadata.gz: 5dbfc58d5d80c63d57ea44f2609cb5d7945db12c0122aba71b498f3a90e9dd395573389aebd8bfa12a8c048d4507307e5e0ac4470b01ac2dfb72cdcde97ea8a8
7
- data.tar.gz: 576dedbcf695565157b8a5df868f510695e50a38a6ed0e36a68be484017fbad396a4d10428411727bcfb15c9f99b89a15b196637ae2700fb223ea1b023a89ae8
6
+ metadata.gz: '0855f6f3b59e182affb16b9e71ad9224ac031494c73acb869e335ff86781e5130fa9dcc0d28f24d17cf3f2e9e2dad2fcd82caefd15d0b27604b5cf9096975f58'
7
+ data.tar.gz: 58f3a8f48083d62280a32221c0130056cb5abf360dce3c9eb50c274667aff6dfc14eedb3e0f145b32579af653b0be068394609f5e59f3058069ef99e2695f45d
@@ -1,6 +1,17 @@
1
1
  # Authenticate Changelog
2
2
 
3
3
 
4
+ ## [0.7.2] - June 22, 2017
5
+
6
+ ### API change
7
+ - removed new_users_path, sign_up_path remains
8
+
9
+ ### New Feature
10
+ - added allow_sign_up flag to install generator
11
+
12
+ [0.7.2]: https://github.com/tomichj/authenticate/compare/v0.7.1...v0.7.2
13
+
14
+
4
15
  ## [0.7.1] - June 22, 2017
5
16
 
6
17
  ### Fixed
data/README.md CHANGED
@@ -2,10 +2,11 @@
2
2
 
3
3
  A Rails authentication gem.
4
4
 
5
- Authenticate is small, simple, but extensible. It has highly opinionated defaults but is
6
- open to significant modification.
5
+ Authenticate is small, simple, but extensible and comprehensive. Authenticate comes out of the box with opinionated
6
+ defaults but is open to complete modification.
7
7
 
8
- Authenticate is inspired by, and draws from, Devise, Warden, Authlogic, Clearance, Sorcery, and restful_authentication.
8
+ Authenticate is inspired by, and draws both concepts and code from:
9
+ Devise, Warden, Authlogic, Clearance, Sorcery, and restful_authentication.
9
10
 
10
11
  Please use [GitHub Issues] to report bugs. You can contact me directly on twitter
11
12
  [@JustinTomich](https://twitter.com/justintomich).
@@ -23,6 +24,17 @@ Please use [GitHub Issues] to report bugs. You can contact me directly on twitte
23
24
  * configuration driven - almost all configuration is performed in the initializer
24
25
 
25
26
 
27
+ ### What's different about Authenticate?
28
+
29
+ Authenticate provides rails authentication with email & password. Authenticate only works with Rails, and only
30
+ with active record; this keeps it simple. There's no middleware, and no compromises or added complexity to
31
+ support other ORMs.
32
+
33
+ Authenticate uses a modular callback mechanism similar to Warden, but much simpler. A lot of
34
+ functionality is provided: there are modules to detect brute force attacks, enforce maximum session
35
+ lifetimes, session timeouts, track logins, etc.
36
+
37
+
26
38
  ## Implementation Overview
27
39
 
28
40
  Authenticate:
@@ -188,12 +200,14 @@ end
188
200
 
189
201
  ### User Model
190
202
 
191
- You can [use an alternate user model class](https://github.com/tomichj/authenticate/wiki/custom-user-model).
203
+ Authenticate assumes your user model is a class named User, but you can
204
+ [specify any user model class](https://github.com/tomichj/authenticate/wiki/custom-user-model).
192
205
 
193
206
 
194
207
  ### Username Authentication
195
208
 
196
- You can [authenticate with username](https://github.com/tomichj/authenticate/wiki/Authenticate-with-username).
209
+ Authenticate uses email and password to login users. You
210
+ can also [authenticate with username](https://github.com/tomichj/authenticate/wiki/Authenticate-with-username).
197
211
 
198
212
 
199
213
  ### Routes
@@ -3,8 +3,8 @@ if Authenticate.configuration.routes_enabled?
3
3
  resource :session, controller: 'authenticate/sessions', only: [:create, :new, :destroy]
4
4
  resources :passwords, controller: 'authenticate/passwords', only: [:new, :create]
5
5
 
6
- user_actions = Authenticate.configuration.allow_sign_up? ? [:new, :create] : []
7
6
  user_model = Authenticate.configuration.user_model_route_key
7
+ user_actions = Authenticate.configuration.allow_sign_up? ? [:create] : []
8
8
  resource user_model, controller: 'authenticate/users', only: user_actions do
9
9
  resources :passwords, controller: 'authenticate/passwords', only: [:edit, :update]
10
10
  end
@@ -202,9 +202,8 @@ module Authenticate
202
202
  #
203
203
  # Set to `false` to disable user creation routes. The setting is ignored if routes are disabled.
204
204
  #
205
- # @param [Boolean] value
206
205
  # @return [Boolean]
207
- attr_accessor :allow_sign_up
206
+ attr_writer :allow_sign_up
208
207
 
209
208
  # Enable or disable Authenticate's built-in routes.
210
209
  #
@@ -277,6 +276,13 @@ module Authenticate
277
276
  user_model_class.model_name.param_key.to_sym
278
277
  end
279
278
 
279
+ # Actions allowed for :user resources (in routes.rb).
280
+ # If sign up is allowed, the [:create] action is allowed, otherwise [].
281
+ # @return [Array<Symbol>]
282
+ def user_actions
283
+ allow_sign_up? ? [:create] : []
284
+ end
285
+
280
286
  # Is the user sign up route enabled?
281
287
  # @return [Boolean]
282
288
  def allow_sign_up?
@@ -1,3 +1,3 @@
1
1
  module Authenticate
2
- VERSION = '0.7.1'.freeze
2
+ VERSION = '0.7.2'.freeze
3
3
  end
@@ -15,6 +15,12 @@ module Authenticate
15
15
  banner: 'model',
16
16
  desc: "Specify the model class name if you will use anything other than 'User'"
17
17
 
18
+ class_option :allow_sign_up,
19
+ optional: true,
20
+ type: :boolean,
21
+ banner: 'allow_sign_up',
22
+ desc: 'Disable the sign up route'
23
+
18
24
  def initialize(*)
19
25
  super
20
26
  assign_names!(model_class_name)
@@ -32,7 +38,6 @@ module Authenticate
32
38
  inject_into_class(model_path, model_class_name, " include Authenticate::User\n\n")
33
39
  else
34
40
  @model_base_class = model_base_class
35
- # copy_file 'user.rb', 'app/models/user.rb'
36
41
  template 'user.rb.erb', 'app/models/user.rb'
37
42
  end
38
43
  end
@@ -64,7 +69,15 @@ module Authenticate
64
69
  if options[:model]
65
70
  inject_into_file(
66
71
  'config/initializers/authenticate.rb',
67
- " config.user_model = '#{options[:model]}' \n",
72
+ " config.user_model = '#{options[:model]}'\n",
73
+ after: "Authenticate.configure do |config|\n"
74
+ )
75
+ end
76
+
77
+ if options.key? :allow_sign_up
78
+ inject_into_file(
79
+ 'config/initializers/authenticate.rb',
80
+ " config.allow_sign_up = #{options['allow_sign_up']}\n",
68
81
  after: "Authenticate.configure do |config|\n"
69
82
  )
70
83
  end
@@ -121,7 +134,7 @@ module Authenticate
121
134
 
122
135
  def new_indexes
123
136
  @new_indexes ||= {
124
- index_users_on_email: "add_index :#{table_name}, :email",
137
+ index_users_on_email: "add_index :#{table_name}, :email, unique: true",
125
138
  index_users_on_session_token: "add_index :#{table_name}, :session_token"
126
139
  }.reject { |index| existing_users_indexes.include?(index.to_s) }
127
140
  end
@@ -140,10 +153,21 @@ module Authenticate
140
153
  file.sub(%r{^.*(db/migrate/)(?:\d+_)?}, '')
141
154
  end
142
155
 
156
+ # def users_table_exists?
157
+ # ActiveRecord::Base.connection.table_exists?(table_name)
158
+ # end
159
+
143
160
  def users_table_exists?
144
- ActiveRecord::Base.connection.table_exists?(table_name)
161
+ # Rails 5 uses 'data sources'
162
+ if ActiveRecord::Base.connection.respond_to?(:data_source_exists?)
163
+ ActiveRecord::Base.connection.data_source_exists?(table_name)
164
+ else
165
+ # Rails 4 uses 'tables'
166
+ ActiveRecord::Base.connection.table_exists?(table_name)
167
+ end
145
168
  end
146
169
 
170
+
147
171
  def existing_users_columns
148
172
  return [] unless users_table_exists?
149
173
  ActiveRecord::Base.connection.columns(table_name).map(&:name)
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'support/controllers/controller_helpers'
3
2
 
4
3
  # Matcher that asserts user was denied access.
5
4
  RSpec::Matchers.define :deny_access do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'support/controllers/controller_helpers'
3
2
 
4
3
  # Matcher that asserts user was denied access.
5
4
  RSpec::Matchers.define :deny_access do
@@ -29,7 +29,7 @@ ActiveRecord::Schema.define(version: 20160130192731) do
29
29
  t.datetime "password_reset_sent_at"
30
30
  end
31
31
 
32
- add_index "users", ["email"], name: "index_users_on_email"
32
+ add_index "users", ["email"], name: "index_users_on_email", unique: true
33
33
  add_index "users", ["session_token"], name: "index_users_on_session_token"
34
34
 
35
35
  end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'support/features/feature_helpers'
3
2
 
4
3
  feature 'visitor has consecutive bad logins' do
5
4
  before do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'support/features/feature_helpers'
3
2
 
4
3
  feature 'create a user with valid attributes' do
5
4
 
@@ -32,13 +31,13 @@ feature 'create user after signed in' do
32
31
  scenario 'cannot get to new user page' do
33
32
  user = create(:user, email: 'test.user@example.com')
34
33
  sign_in_with user.email, user.password
35
- visit new_users_path
34
+ visit sign_up_path
36
35
  expect_path_is_redirect_url
37
36
  end
38
37
  end
39
38
 
40
39
  def create_user_with_valid_params(user_attrs = attributes_for(:user))
41
- visit new_users_path
40
+ visit sign_up_path
42
41
  fill_in 'user_email', with: user_attrs[:email]
43
42
  fill_in 'user_password', with: user_attrs[:password]
44
43
  click_button 'Sign up'
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'support/features/feature_helpers'
3
2
 
4
3
  feature 'visitor has consecutive bad logins' do
5
4
  before(:each) do
@@ -1,17 +1,16 @@
1
1
  require 'spec_helper'
2
- require 'support/features/feature_helpers'
3
2
 
4
- feature 'visitor at new user form, not signed in' do
3
+ feature 'visitor at sign up form, not signed in' do
5
4
  scenario 'visit with no arguments' do
6
- visit new_users_path
7
- expect(page).to have_current_path new_users_path
5
+ visit sign_up_path
6
+ expect(page).to have_current_path sign_up_path
8
7
  within 'h2' do
9
8
  expect(page).to have_content /Sign up/i
10
9
  end
11
10
  end
12
11
 
13
12
  scenario 'defaults email to value provided in query string' do
14
- visit new_users_path(user: { email: 'dude@example.com' })
13
+ visit sign_up_path(user: { email: 'dude@example.com' })
15
14
  expect(page).to have_selector 'input[value="dude@example.com"]'
16
15
  end
17
16
  end
@@ -20,7 +19,7 @@ feature 'visitor at new user form, already signed in' do
20
19
  scenario 'redirects user to redirect_url' do
21
20
  user = create(:user, email: 'test.user@example.com')
22
21
  sign_in_with 'Test.USER@example.com', user.password
23
- visit new_users_path
22
+ visit sign_up_path
24
23
  expect_path_is_redirect_url
25
24
  end
26
25
  end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'support/features/feature_helpers'
3
2
 
4
3
  feature 'visitor requests password reset' do
5
4
  before(:each) do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'support/features/feature_helpers'
3
2
 
4
3
 
5
4
  feature 'visit password edit screen' do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'support/features/feature_helpers'
3
2
 
4
3
  feature 'visitor signs in' do
5
4
  scenario 'with valid email and password' do
@@ -31,7 +30,7 @@ end
31
30
  feature 'visitor goes to sign in page' do
32
31
  scenario 'signed out user is not redirected' do
33
32
  visit sign_in_path
34
- expect_sign_in_path
33
+ expect_sign_in_page
35
34
  end
36
35
 
37
36
  scenario 'signed in user is redirected' do
@@ -43,6 +42,10 @@ feature 'visitor goes to sign in page' do
43
42
  end
44
43
  end
45
44
 
46
- def expect_sign_in_path
47
- expect(current_path).to eq sign_in_path
45
+ feature 'user is not signed in' do
46
+ scenario 'redirected to sign in' do
47
+ visit welcome_index_path
48
+ expect_sign_in_page
49
+ end
48
50
  end
51
+
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'support/features/feature_helpers'
3
2
 
4
3
  feature 'visitor signs out' do
5
4
  before do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'support/features/feature_helpers'
3
2
 
4
3
  feature 'visitor signs up' do
5
4
  scenario 'navigates to sign up page' do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'support/features/feature_helpers'
3
2
 
4
3
  feature 'visitor session time' do
5
4
  before do
@@ -19,4 +19,15 @@ describe Authenticate::Model::Email do
19
19
  user = create(:user)
20
20
  expect(User.authenticate([user.email, user.password])).to eq(user)
21
21
  end
22
+
23
+ it 'validates unique email address' do
24
+ original = build(:user, email: 'email@email.com')
25
+ dupe_email = build(:user, email: 'email@email.com')
26
+
27
+ original.save
28
+ dupe_email.save
29
+
30
+ expect(dupe_email.errors.count).to be(1)
31
+ expect(dupe_email.errors.messages[:email]).to include('has already been taken')
32
+ end
22
33
  end
@@ -10,7 +10,6 @@ describe Authenticate::Session do
10
10
  end
11
11
  it 'nil user without a session token' do
12
12
  request = mock_request
13
- cookies = {}
14
13
  session = Authenticate::Session.new(request)
15
14
  expect(session.current_user).to be_nil
16
15
  end
@@ -9,13 +9,13 @@ if ActiveRecord::VERSION::STRING >= '5.0'
9
9
  end
10
10
 
11
11
  require 'rspec/rails'
12
- # require 'shoulda-matchers'
13
12
  require 'capybara/rails'
14
13
  require 'capybara/rspec'
15
14
  require 'database_cleaner'
16
15
  require 'factory_girl'
17
16
  require 'timecop'
18
- require 'support/mailer'
17
+
18
+ Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require f }
19
19
 
20
20
  Rails.backtrace_cleaner.remove_silencers!
21
21
  DatabaseCleaner.strategy = :truncation
@@ -55,51 +55,3 @@ RSpec.configure do |config|
55
55
  end
56
56
  end
57
57
 
58
- #
59
- # todo - enhance test helpers, put in main project
60
- #
61
- def mock_request(params: {}, cookies: {})
62
- req = double('request')
63
- allow(req).to receive(:params).and_return(params)
64
- allow(req).to receive(:remote_ip).and_return('111.111.111.111')
65
- allow(req).to receive(:cookie_jar).and_return(cookies)
66
- req
67
- end
68
-
69
- def session_cookie_for(user)
70
- { Authenticate.configuration.cookie_name.freeze.to_sym => user.session_token }
71
- end
72
-
73
-
74
- #
75
- # Dumb glue method, deal with rails 4 vs rails 5 get/post methods.
76
- #
77
- def do_post(path, *args)
78
- if Rails::VERSION::MAJOR >= 5
79
- post path, *args
80
- else
81
- post path, *(args.collect{|i| i.values}.flatten)
82
- end
83
- end
84
-
85
- def do_get(path, *args)
86
- if Rails::VERSION::MAJOR >= 5
87
- get path, *args
88
- else
89
- get path, *(args.collect{|i| i.values}.flatten)
90
- end
91
- end
92
-
93
- def do_put(path, *args)
94
- if Rails::VERSION::MAJOR >= 5
95
- put path, *args
96
- else
97
- put path, *(args.collect{|i| i.values}.flatten)
98
- end
99
- end
100
-
101
- # class ActionMailer::MessageDelivery
102
- # def deliver_later
103
- # deliver_now
104
- # end
105
- # end
@@ -30,6 +30,10 @@ module Features
30
30
  def expect_path_is_redirect_url
31
31
  expect(current_path).to eq(Authenticate.configuration.redirect_url)
32
32
  end
33
+
34
+ def expect_sign_in_page
35
+ expect(current_path).to eq sign_in_path
36
+ end
33
37
  end
34
38
  end
35
39
 
@@ -0,0 +1,46 @@
1
+ module RequestHelpers
2
+
3
+ #
4
+ # Dumb glue methods, to deal with rails 4 vs rails 5 get/post methods.
5
+ #
6
+ def do_post(path, *args)
7
+ if Rails::VERSION::MAJOR >= 5
8
+ post path, *args
9
+ else
10
+ post path, *(args.collect{|i| i.values}.flatten)
11
+ end
12
+ end
13
+
14
+ def do_get(path, *args)
15
+ if Rails::VERSION::MAJOR >= 5
16
+ get path, *args
17
+ else
18
+ get path, *(args.collect{|i| i.values}.flatten)
19
+ end
20
+ end
21
+
22
+ # def do_put(path, *args)
23
+ # if Rails::VERSION::MAJOR >= 5
24
+ # put path, *args
25
+ # else
26
+ # put path, *(args.collect{|i| i.values}.flatten)
27
+ # end
28
+ # end
29
+
30
+
31
+ def mock_request(params: {}, cookies: {})
32
+ req = double('request')
33
+ allow(req).to receive(:params).and_return(params)
34
+ allow(req).to receive(:remote_ip).and_return('111.111.111.111')
35
+ allow(req).to receive(:cookie_jar).and_return(cookies)
36
+ req
37
+ end
38
+
39
+ def session_cookie_for(user)
40
+ { Authenticate.configuration.cookie_name.freeze.to_sym => user.session_token }
41
+ end
42
+ end
43
+
44
+ RSpec.configure do |config|
45
+ config.include RequestHelpers
46
+ end
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.7.1
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Tomich
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-22 00:00:00.000000000 Z
11
+ date: 2017-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bcrypt
@@ -317,10 +317,6 @@ files:
317
317
  - spec/dummy/config/locales/en.yml
318
318
  - spec/dummy/config/routes.rb
319
319
  - spec/dummy/config/secrets.yml
320
- - spec/dummy/db/migrate/20160130192728_create_users.rb
321
- - spec/dummy/db/migrate/20160130192729_add_authenticate_brute_force_to_users.rb
322
- - spec/dummy/db/migrate/20160130192730_add_authenticate_timeoutable_to_users.rb
323
- - spec/dummy/db/migrate/20160130192731_add_authenticate_password_reset_to_users.rb
324
320
  - spec/dummy/db/schema.rb
325
321
  - spec/dummy/lib/assets/.keep
326
322
  - spec/dummy/log/.keep
@@ -358,6 +354,7 @@ files:
358
354
  - spec/support/controllers/controller_helpers.rb
359
355
  - spec/support/features/feature_helpers.rb
360
356
  - spec/support/mailer.rb
357
+ - spec/support/request_helpers.rb
361
358
  homepage: http://github.com/tomichj/authenticate
362
359
  licenses:
363
360
  - MIT
@@ -1,18 +0,0 @@
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
@@ -1,6 +0,0 @@
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
@@ -1,5 +0,0 @@
1
- class AddAuthenticateTimeoutableToUsers < ActiveRecord::Migration
2
- def change
3
- add_column :users, :last_access_at, :datetime, default: nil
4
- end
5
- end
@@ -1,7 +0,0 @@
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
-