authenticate 0.7.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
-