authenticate 0.1.0 → 0.2.0
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 +4 -4
- data/CHANGELOG.md +11 -0
- data/Gemfile +0 -4
- data/Gemfile.lock +0 -5
- data/README.md +149 -78
- data/app/controllers/authenticate/passwords_controller.rb +130 -0
- data/app/controllers/authenticate/sessions_controller.rb +46 -0
- data/app/controllers/authenticate/users_controller.rb +46 -0
- data/app/mailers/authenticate_mailer.rb +13 -0
- data/app/views/authenticate_mailer/change_password.html.erb +8 -0
- data/app/views/authenticate_mailer/change_password.text.erb +5 -0
- data/app/views/layouts/application.html.erb +25 -0
- data/app/views/passwords/edit.html.erb +20 -0
- data/app/views/passwords/new.html.erb +19 -0
- data/app/views/sessions/new.html.erb +28 -0
- data/app/views/users/new.html.erb +24 -0
- data/authenticate.gemspec +1 -2
- data/config/locales/authenticate.en.yml +57 -0
- data/config/routes.rb +14 -1
- data/lib/authenticate/callbacks/brute_force.rb +5 -9
- data/lib/authenticate/callbacks/lifetimed.rb +1 -0
- data/lib/authenticate/callbacks/timeoutable.rb +2 -1
- data/lib/authenticate/callbacks/trackable.rb +1 -3
- data/lib/authenticate/configuration.rb +94 -5
- data/lib/authenticate/controller.rb +69 -9
- data/lib/authenticate/debug.rb +1 -0
- data/lib/authenticate/engine.rb +4 -11
- data/lib/authenticate/model/brute_force.rb +22 -3
- data/lib/authenticate/model/db_password.rb +12 -7
- data/lib/authenticate/model/email.rb +8 -10
- data/lib/authenticate/model/password_reset.rb +76 -0
- data/lib/authenticate/model/timeoutable.rb +9 -3
- data/lib/authenticate/model/trackable.rb +1 -1
- data/lib/authenticate/model/username.rb +21 -8
- data/lib/authenticate/modules.rb +19 -1
- data/lib/authenticate/session.rb +3 -1
- data/lib/authenticate/user.rb +6 -1
- data/lib/authenticate/version.rb +1 -1
- data/lib/generators/authenticate/controllers/USAGE +12 -0
- data/lib/generators/authenticate/controllers/controllers_generator.rb +21 -0
- data/lib/generators/authenticate/install/USAGE +7 -0
- data/lib/generators/authenticate/install/install_generator.rb +140 -0
- data/lib/generators/authenticate/install/templates/authenticate.rb +22 -0
- data/lib/generators/authenticate/install/templates/db/migrate/add_authenticate_brute_force_to_users.rb +6 -0
- data/lib/generators/authenticate/install/templates/db/migrate/add_authenticate_password_reset_to_users.rb +7 -0
- data/lib/generators/authenticate/install/templates/db/migrate/add_authenticate_timeoutable_to_users.rb +5 -0
- data/lib/generators/authenticate/install/templates/db/migrate/add_authenticate_to_users.rb +21 -0
- data/lib/generators/authenticate/install/templates/db/migrate/create_users.rb +14 -0
- data/lib/generators/authenticate/install/templates/user.rb +3 -0
- data/lib/generators/authenticate/routes/USAGE +8 -0
- data/lib/generators/authenticate/routes/routes_generator.rb +32 -0
- data/lib/generators/authenticate/routes/templates/routes.rb +10 -0
- data/lib/generators/authenticate/views/USAGE +13 -0
- data/lib/generators/authenticate/views/views_generator.rb +21 -0
- data/spec/dummy/app/controllers/application_controller.rb +1 -0
- data/spec/dummy/config/initializers/authenticate.rb +12 -5
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20160130192728_create_users.rb +18 -0
- data/spec/dummy/db/migrate/20160130192729_add_authenticate_brute_force_to_users.rb +6 -0
- data/spec/dummy/db/migrate/20160130192730_add_authenticate_timeoutable_to_users.rb +5 -0
- data/spec/dummy/db/migrate/20160130192731_add_authenticate_password_reset_to_users.rb +7 -0
- data/spec/dummy/db/schema.rb +14 -10
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/factories/users.rb +5 -8
- data/spec/model/brute_force_spec.rb +63 -0
- data/spec/model/session_spec.rb +4 -0
- data/spec/model/user_spec.rb +15 -5
- data/spec/spec_helper.rb +2 -1
- metadata +41 -9
- data/app/controllers/.keep +0 -0
- data/app/mailers/.keep +0 -0
- data/app/views/.keep +0 -0
- data/spec/dummy/db/migrate/20160120003910_create_users.rb +0 -18
data/lib/authenticate/session.rb
CHANGED
@@ -100,7 +100,9 @@ module Authenticate
|
|
100
100
|
|
101
101
|
def write_cookie
|
102
102
|
cookie_hash = {
|
103
|
-
|
103
|
+
path: Authenticate.configuration.cookie_path,
|
104
|
+
secure: Authenticate.configuration.secure_cookie,
|
105
|
+
httponly: Authenticate.configuration.cookie_http_only,
|
104
106
|
value: @current_user.session_token,
|
105
107
|
expires: Authenticate.configuration.cookie_expiration.call
|
106
108
|
}
|
data/lib/authenticate/user.rb
CHANGED
@@ -35,16 +35,21 @@ module Authenticate
|
|
35
35
|
load_modules
|
36
36
|
end
|
37
37
|
|
38
|
+
# Generate a new session token for the user, overwriting the existing session token, if any.
|
39
|
+
# This is not automatically persisted; call {#reset_session_token!} to automatically
|
40
|
+
# generate and persist the session token update.
|
38
41
|
def generate_session_token
|
39
42
|
self.session_token = Authenticate::Token.new
|
40
|
-
# puts 'User.generate_session_token session_token:' + self.session_token.to_s
|
41
43
|
end
|
42
44
|
|
45
|
+
# Generate a new session token and persist the change, ignoring validations.
|
46
|
+
# This effectively signs out all existing sessions. Called as part of logout.
|
43
47
|
def reset_session_token!
|
44
48
|
generate_session_token
|
45
49
|
save validate: false
|
46
50
|
end
|
47
51
|
|
52
|
+
|
48
53
|
end
|
49
54
|
end
|
50
55
|
|
data/lib/authenticate/version.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
Description:
|
2
|
+
Override the default authentication controllers and mailers. This generator will copy all of the
|
3
|
+
base authenticate controllers and mailers into your project.
|
4
|
+
|
5
|
+
Examples:
|
6
|
+
rails generate authenticate:controllers
|
7
|
+
|
8
|
+
View: app/controllers/authenticate/passwords_controller.rb
|
9
|
+
View: app/controllers/authenticate/sessions_controller.rb
|
10
|
+
View: app/controllers/authenticate/users_controller.rb
|
11
|
+
View: app/mailers/authenticate_mailer.rb
|
12
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
#
|
4
|
+
# deploy view and locale assets
|
5
|
+
#
|
6
|
+
module Authenticate
|
7
|
+
module Generators
|
8
|
+
class ControllersGenerator < Rails::Generators::Base
|
9
|
+
source_root File.expand_path("../../../../..", __FILE__)
|
10
|
+
|
11
|
+
def create_views
|
12
|
+
directory 'app/controllers'
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_mailers
|
16
|
+
directory 'app/mailers'
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
require 'rails/generators/active_record'
|
3
|
+
|
4
|
+
module Authenticate
|
5
|
+
module Generators
|
6
|
+
class InstallGenerator < Rails::Generators::Base
|
7
|
+
include Rails::Generators::Migration
|
8
|
+
source_root File.expand_path('../templates', __FILE__)
|
9
|
+
|
10
|
+
def create_initializer
|
11
|
+
copy_file 'authenticate.rb', 'config/initializers/authenticate.rb'
|
12
|
+
end
|
13
|
+
|
14
|
+
def inject_into_application_controller
|
15
|
+
inject_into_class(
|
16
|
+
"app/controllers/application_controller.rb",
|
17
|
+
ApplicationController,
|
18
|
+
" include Authenticate::Controller\n"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_or_inject_into_user_model
|
23
|
+
if File.exist? "app/models/user.rb"
|
24
|
+
inject_into_file(
|
25
|
+
'app/models/user.rb',
|
26
|
+
' include Authenticate::User\n\n',
|
27
|
+
after: 'class User < ActiveRecord::Base\n'
|
28
|
+
)
|
29
|
+
else
|
30
|
+
copy_file 'user.rb', 'app/models/user.rb'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_authenticate_user_migration
|
35
|
+
if users_table_exists?
|
36
|
+
create_add_columns_migration
|
37
|
+
else
|
38
|
+
create_new_users_migration
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def copy_migration_files
|
43
|
+
copy_migration 'add_authenticate_brute_force_to_users.rb'
|
44
|
+
copy_migration 'add_authenticate_timeoutable_to_users.rb'
|
45
|
+
copy_migration 'add_authenticate_password_reset_to_users.rb'
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def create_new_users_migration
|
51
|
+
config = {
|
52
|
+
new_columns: new_columns,
|
53
|
+
new_indexes: new_indexes
|
54
|
+
}
|
55
|
+
copy_migration 'create_users.rb', config
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_add_columns_migration
|
59
|
+
if migration_needed?
|
60
|
+
config = {
|
61
|
+
new_columns: new_columns,
|
62
|
+
new_indexes: new_indexes
|
63
|
+
}
|
64
|
+
copy_migration('add_authenticate_to_users.rb', config)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def copy_migration(migration_name, config = {})
|
69
|
+
unless migration_exists?(migration_name)
|
70
|
+
migration_template(
|
71
|
+
"db/migrate/#{migration_name}",
|
72
|
+
"db/migrate/#{migration_name}",
|
73
|
+
config
|
74
|
+
)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def migration_needed?
|
79
|
+
new_columns.any? || new_indexes.any?
|
80
|
+
end
|
81
|
+
|
82
|
+
def new_columns
|
83
|
+
@new_columns ||= {
|
84
|
+
email: 't.string :email',
|
85
|
+
encrypted_password: 't.string :encrypted_password, limit: 128',
|
86
|
+
session_token: 't.string :session_token, limit: 128',
|
87
|
+
|
88
|
+
# trackable, lifetimed
|
89
|
+
current_sign_in_at: 't.datetime :current_sign_in_at',
|
90
|
+
current_sign_in_ip: 't.string :current_sign_in_ip, limit: 128',
|
91
|
+
last_sign_in_at: 't.datetime :last_sign_in_at',
|
92
|
+
last_sign_in_ip: 't.string :last_sign_in_ip, limit: 128',
|
93
|
+
sign_in_count: 't.integer :sign_in_count'
|
94
|
+
}.reject { |column| existing_users_columns.include?(column.to_s) }
|
95
|
+
end
|
96
|
+
|
97
|
+
def new_indexes
|
98
|
+
@new_indexes ||= {
|
99
|
+
index_users_on_email: 'add_index :users, :email',
|
100
|
+
index_users_on_session_token: 'add_index :users, :session_token'
|
101
|
+
}.reject { |index| existing_users_indexes.include?(index.to_s) }
|
102
|
+
end
|
103
|
+
|
104
|
+
def migration_exists?(name)
|
105
|
+
existing_migrations.include?(name)
|
106
|
+
end
|
107
|
+
|
108
|
+
def existing_migrations
|
109
|
+
@existing_migrations ||= Dir.glob("db/migrate/*.rb").map do |file|
|
110
|
+
migration_name_without_timestamp(file)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def migration_name_without_timestamp(file)
|
115
|
+
file.sub(%r{^.*(db/migrate/)(?:\d+_)?}, '')
|
116
|
+
end
|
117
|
+
|
118
|
+
def users_table_exists?
|
119
|
+
ActiveRecord::Base.connection.table_exists?(:users)
|
120
|
+
end
|
121
|
+
|
122
|
+
def existing_users_columns
|
123
|
+
return [] unless users_table_exists?
|
124
|
+
ActiveRecord::Base.connection.columns(:users).map(&:name)
|
125
|
+
end
|
126
|
+
|
127
|
+
def existing_users_indexes
|
128
|
+
return [] unless users_table_exists?
|
129
|
+
ActiveRecord::Base.connection.indexes(:users).map(&:name)
|
130
|
+
end
|
131
|
+
|
132
|
+
# for generating a timestamp when using `create_migration`
|
133
|
+
def self.next_migration_number(dir)
|
134
|
+
ActiveRecord::Generators::Base.next_migration_number(dir)
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Authenticate.configure do |config|
|
2
|
+
# config.user_model = 'User'
|
3
|
+
# config.cookie_name = 'authenticate_session_token'
|
4
|
+
# config.cookie_expiration = { 1.month.from_now.utc }
|
5
|
+
# config.cookie_domain = nil
|
6
|
+
# config.cookie_path = '/'
|
7
|
+
# config.secure_cookie = false # set to true in production https environments
|
8
|
+
# config.cookie_http_only = false # set to true if you can
|
9
|
+
|
10
|
+
# config.mailer_sender = 'reply@example.com'
|
11
|
+
# config.crypto_provider = Authenticate::Model::BCrypt
|
12
|
+
# config.timeout_in = 45.minutes
|
13
|
+
# config.max_session_lifetime = 8.hours
|
14
|
+
# config.max_consecutive_bad_logins_allowed = 4
|
15
|
+
# config.bad_login_lockout_period = 10.minutes
|
16
|
+
# config.authentication_strategy = :email
|
17
|
+
# config.redirect_url = '/'
|
18
|
+
# config.allow_sign_up = true
|
19
|
+
# config.routes = true
|
20
|
+
# config.reset_password_within = 2.days
|
21
|
+
# config.modules = []
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class AddAuthenticateToUsers < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
change_table :users do |t|
|
4
|
+
<% config[:new_columns].values.each do |column| -%>
|
5
|
+
<%= column %>
|
6
|
+
<% end -%>
|
7
|
+
end
|
8
|
+
|
9
|
+
<% config[:new_indexes].values.each do |index| -%>
|
10
|
+
<%= index %>
|
11
|
+
<% end -%>
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.down
|
15
|
+
change_table :users do |t|
|
16
|
+
<% if config[:new_columns].any? -%>
|
17
|
+
t.remove <%= new_columns.keys.map { |column| ":#{column}" }.join(", ") %>
|
18
|
+
<% end -%>
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateUsers < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
|
4
|
+
create_table :users do |t|
|
5
|
+
<% config[:new_columns].values.each do |column| -%>
|
6
|
+
<%= column %>
|
7
|
+
<% end -%>
|
8
|
+
end
|
9
|
+
|
10
|
+
<% config[:new_indexes].values.each do |index| -%>
|
11
|
+
<%= index %>
|
12
|
+
<% end -%>
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module Authenticate
|
4
|
+
module Generators
|
5
|
+
class RoutesGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
def add_authenticate_routes
|
9
|
+
route(authenticate_routes)
|
10
|
+
end
|
11
|
+
|
12
|
+
def disable_authenticate_internal_routes
|
13
|
+
inject_into_file(
|
14
|
+
'config/initializers/authenticate.rb',
|
15
|
+
" config.routes = false \n",
|
16
|
+
after: "Authenticate.configure do |config|\n",
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def authenticate_routes
|
23
|
+
File.read(routes_file_path)
|
24
|
+
end
|
25
|
+
|
26
|
+
def routes_file_path
|
27
|
+
File.expand_path(find_in_source_paths('routes.rb'))
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
resource :session, controller: 'authenticate/sessions', only: [:create, :new, :destroy]
|
2
|
+
resources :passwords, controller: 'authenticate/passwords', only: [:new, :create]
|
3
|
+
|
4
|
+
resource :users, controller: 'authenticate/users', only: [:new, :create] do
|
5
|
+
resources :passwords, controller: 'authenticate/passwords', only: [:edit, :update]
|
6
|
+
end
|
7
|
+
|
8
|
+
get '/sign_up', to: 'authenticate/users#new', as: 'sign_up'
|
9
|
+
get '/sign_in', to: 'authenticate/sessions#new', as: 'sign_in'
|
10
|
+
get '/sign_out', to: 'authenticate/sessions#destroy', as: 'sign_out'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Description:
|
2
|
+
Override the default authenticate views. This generator will copy all of the
|
3
|
+
base authenticate views into your project.
|
4
|
+
|
5
|
+
Examples:
|
6
|
+
rails generate authenticate:views
|
7
|
+
|
8
|
+
View: app/views/authenticate_mailer/change_password.html.erb
|
9
|
+
View: app/views/layouts/application.html.erb
|
10
|
+
View: app/views/passwords/edit.html.erb
|
11
|
+
View: app/views/passwords/new.html.erb
|
12
|
+
View: app/views/sessions/new.html.erb
|
13
|
+
View: app/views/users/new.html.erb
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
#
|
4
|
+
# deploy view and locale assets
|
5
|
+
#
|
6
|
+
module Authenticate
|
7
|
+
module Generators
|
8
|
+
class ViewsGenerator < Rails::Generators::Base
|
9
|
+
source_root File.expand_path("../../../../..", __FILE__)
|
10
|
+
|
11
|
+
def create_views
|
12
|
+
directory 'app/views'
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_locales
|
16
|
+
directory 'config/locales'
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,7 +1,14 @@
|
|
1
|
-
puts '************************** initializer start'
|
2
1
|
Authenticate.configure do |config|
|
3
|
-
config.
|
4
|
-
config.
|
5
|
-
config.
|
2
|
+
# config.user_model = 'User'
|
3
|
+
# config.cookie_name = 'authenticate_session_token'
|
4
|
+
# config.cookie_expiration = { 1.month.from_now.utc }
|
5
|
+
# config.cookie_domain = nil
|
6
|
+
# config.cookie_path = '/'
|
7
|
+
# config.secure_cookie = false # set to true in production https environments
|
8
|
+
# config.http_only = false # set to true if you can
|
9
|
+
# config.timeout_in = 45.minutes
|
10
|
+
# config.max_session_lifetime = 8.hours
|
11
|
+
config.max_consecutive_bad_logins_allowed = 1
|
12
|
+
config.bad_login_lockout_period = 2.minutes
|
13
|
+
# config.authentication_strategy = :email
|
6
14
|
end
|
7
|
-
puts '************************** initializer finished'
|
Binary file
|