challah 1.6.1 → 2.0.0.beta1
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 +14 -0
- data/README.md +5 -38
- data/VERSION +1 -1
- data/app/controllers/sessions_controller.rb +11 -10
- data/app/models/authorization.rb +2 -0
- data/lib/challah/audit.rb +38 -36
- data/lib/challah/authenticators/api_key.rb +4 -2
- data/lib/challah/authenticators/password.rb +3 -1
- data/lib/challah/authenticators.rb +5 -3
- data/lib/challah/concerns/authorizeable.rb +4 -0
- data/lib/challah/concerns/user/attributeable.rb +35 -33
- data/lib/challah/concerns/user/authenticateable.rb +2 -0
- data/lib/challah/concerns/user/authorizable.rb +16 -12
- data/lib/challah/concerns/user/findable.rb +13 -10
- data/lib/challah/concerns/user/passwordable.rb +5 -3
- data/lib/challah/concerns/user/provideable.rb +22 -20
- data/lib/challah/concerns/user/statusable.rb +3 -21
- data/lib/challah/concerns/user/validateable.rb +3 -1
- data/lib/challah/concerns/userable.rb +1 -3
- data/lib/challah/controller.rb +69 -65
- data/lib/challah/cookie_store.rb +7 -5
- data/lib/challah/encrypter.rb +4 -2
- data/lib/challah/engine.rb +5 -18
- data/lib/challah/providers/password_provider.rb +9 -7
- data/lib/challah/providers.rb +3 -1
- data/lib/challah/random.rb +6 -4
- data/lib/challah/routes.rb +6 -6
- data/lib/challah/session.rb +27 -25
- data/lib/challah/signup.rb +5 -3
- data/lib/challah/simple_cookie_store.rb +82 -80
- data/lib/challah/techniques/api_key_technique.rb +2 -2
- data/lib/challah/techniques/password_technique.rb +2 -1
- data/lib/challah/techniques/token_technique.rb +1 -1
- data/lib/challah/techniques.rb +2 -0
- data/lib/challah/test.rb +6 -0
- data/lib/challah/validators/email_validator.rb +2 -0
- data/lib/challah/validators/password_validator.rb +5 -3
- data/lib/challah/version.rb +3 -1
- data/lib/challah.rb +2 -5
- data/lib/generators/challah_generator.rb +2 -8
- data/lib/generators/templates/{migration.rb → migration.erb} +3 -6
- metadata +42 -19
- data/lib/challah/plugins.rb +0 -54
@@ -1,5 +1,6 @@
|
|
1
1
|
module Challah
|
2
2
|
module UserFindable
|
3
|
+
|
3
4
|
extend ActiveSupport::Concern
|
4
5
|
|
5
6
|
module ClassMethods
|
@@ -15,18 +16,20 @@ module Challah
|
|
15
16
|
|
16
17
|
protected
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
def find_by_authorization(uid)
|
20
|
+
authorization = self.authorization_model
|
21
|
+
result = authorization.where(provider: :password, uid: uid).first
|
22
|
+
if result
|
23
|
+
result.user
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_by_email(email)
|
28
|
+
return unless email.include?("@")
|
29
|
+
where(email: email).first
|
23
30
|
end
|
24
|
-
end
|
25
31
|
|
26
|
-
def find_by_email(email)
|
27
|
-
return unless email.include?('@')
|
28
|
-
where(email: email).first
|
29
|
-
end
|
30
32
|
end
|
33
|
+
|
31
34
|
end
|
32
35
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module Challah
|
2
2
|
module UserPasswordable
|
3
|
+
|
3
4
|
# Set the password and password_confirmation in one shortcut method.
|
4
5
|
def password!(new_password)
|
5
6
|
self.password = new_password
|
@@ -7,7 +8,7 @@ module Challah
|
|
7
8
|
end
|
8
9
|
|
9
10
|
def password_provider?
|
10
|
-
return true if @password_updated
|
11
|
+
return true if @password_updated || @username_updated
|
11
12
|
!!providers[:password]
|
12
13
|
end
|
13
14
|
|
@@ -37,12 +38,13 @@ module Challah
|
|
37
38
|
end
|
38
39
|
|
39
40
|
def username
|
40
|
-
@username ||= password_provider? ? password_provider.fetch(:uid,
|
41
|
+
@username ||= password_provider? ? password_provider.fetch(:uid, "") : ""
|
41
42
|
end
|
42
43
|
|
43
44
|
def username=(value)
|
44
45
|
@username_updated = true
|
45
46
|
@username = value.to_s.strip.downcase
|
46
47
|
end
|
48
|
+
|
47
49
|
end
|
48
|
-
end
|
50
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module Challah
|
2
2
|
module UserProvideable
|
3
|
+
|
3
4
|
extend ActiveSupport::Concern
|
4
5
|
|
5
6
|
included do
|
@@ -76,30 +77,31 @@ module Challah
|
|
76
77
|
|
77
78
|
protected
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
# If password or username was changed, update the authorization record
|
84
|
-
def update_modified_providers_after_save
|
85
|
-
# Save password provider
|
86
|
-
if @password_updated or @username_updated
|
87
|
-
Challah.providers[:password].save(self)
|
88
|
-
@password_updated = false
|
89
|
-
@username_updated = false
|
90
|
-
@password = nil
|
80
|
+
def clear_cached_providers_after_save
|
81
|
+
@providers = nil
|
91
82
|
end
|
92
83
|
|
93
|
-
#
|
94
|
-
|
95
|
-
|
84
|
+
# If password or username was changed, update the authorization record
|
85
|
+
def update_modified_providers_after_save
|
86
|
+
# Save password provider
|
87
|
+
if @password_updated || @username_updated
|
88
|
+
Challah.providers[:password].save(self)
|
89
|
+
@password_updated = false
|
90
|
+
@username_updated = false
|
91
|
+
@password = nil
|
92
|
+
end
|
96
93
|
|
97
|
-
|
98
|
-
|
99
|
-
|
94
|
+
# Save any other providers
|
95
|
+
Challah.custom_providers.each do |name, klass|
|
96
|
+
custom_provider_attributes = provider_attributes[name]
|
97
|
+
|
98
|
+
if custom_provider_attributes.respond_to?(:fetch)
|
99
|
+
if klass.valid?(self)
|
100
|
+
klass.save(self)
|
101
|
+
end
|
100
102
|
end
|
101
103
|
end
|
102
104
|
end
|
103
|
-
|
105
|
+
|
104
106
|
end
|
105
|
-
end
|
107
|
+
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module Challah
|
2
2
|
module UserStatusable
|
3
|
+
|
3
4
|
extend ActiveSupport::Concern
|
4
5
|
|
5
6
|
included do
|
6
7
|
begin
|
7
8
|
if columns.map(&:name).include?("status")
|
8
9
|
additional_statuses = Array(Challah.options[:additional_statuses])
|
9
|
-
enum status: [:active, :inactive, *additional_statuses]
|
10
|
+
enum status: [ :active, :inactive, *additional_statuses ].map(&:to_sym)
|
10
11
|
end
|
11
12
|
rescue ActiveRecord::StatementInvalid => exception
|
12
13
|
raise exception unless exception.message =~ /could not find table/i ||
|
@@ -14,26 +15,6 @@ module Challah
|
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
17
|
-
# Fallback to pre-enum active column (pre challah 1.4)
|
18
|
-
def active=(enabled)
|
19
|
-
if self.class.columns.map(&:name).include?("status")
|
20
|
-
self.status = (!!enabled ? :active : :inactive)
|
21
|
-
else
|
22
|
-
write_attribute(:active, !!enabled)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def active?
|
27
|
-
# enum-based status
|
28
|
-
if self.class.columns.map(&:name).include?("status")
|
29
|
-
read_attribute(:status).to_s == "active"
|
30
|
-
|
31
|
-
# support for non-enum status column (pre challah 1.4)
|
32
|
-
else
|
33
|
-
!!read_attribute(:active)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
18
|
def active
|
38
19
|
active?
|
39
20
|
end
|
@@ -41,5 +22,6 @@ module Challah
|
|
41
22
|
def valid_session?
|
42
23
|
active?
|
43
24
|
end
|
25
|
+
|
44
26
|
end
|
45
27
|
end
|
data/lib/challah/controller.rb
CHANGED
@@ -2,6 +2,7 @@ module Challah
|
|
2
2
|
# These methods are added into ActionController::Base and are available in all
|
3
3
|
# of your app's controllers.
|
4
4
|
module Controller
|
5
|
+
|
5
6
|
extend ActiveSupport::Concern
|
6
7
|
|
7
8
|
included do
|
@@ -9,6 +10,7 @@ module Challah
|
|
9
10
|
end
|
10
11
|
|
11
12
|
module ClassMethods
|
13
|
+
|
12
14
|
# Restrict the current controller to only users that have authenticated. All actions
|
13
15
|
# in the controller will be restricted unless otherwise stated. All normal options
|
14
16
|
# for a before_action are observed.
|
@@ -39,80 +41,82 @@ module Challah
|
|
39
41
|
restrict_to_authenticated(*args)
|
40
42
|
end
|
41
43
|
alias_method :login_required, :signin_required
|
44
|
+
|
42
45
|
end
|
43
46
|
|
44
47
|
protected
|
45
48
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
49
|
+
# Is there currently a logged in user? Returns true if it is safe to use
|
50
|
+
# the {#current_user current_user} method.
|
51
|
+
#
|
52
|
+
# @note This method is also available as a helper in your views.
|
53
|
+
#
|
54
|
+
# @see #current_user current_user
|
55
|
+
#
|
56
|
+
# @return [Boolean] Is there a user logged in?
|
57
|
+
def current_user?
|
58
|
+
!!current_user
|
59
|
+
end
|
57
60
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
61
|
+
# Alias for current_user?
|
62
|
+
def signed_in?
|
63
|
+
current_user?
|
64
|
+
end
|
65
|
+
alias_method :logged_in?, :signed_in?
|
63
66
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
67
|
+
# The user that is currently logged into this session. If there is no
|
68
|
+
# user logged in, nil will be returned.
|
69
|
+
#
|
70
|
+
# @note This method is also available as a helper in your views.
|
71
|
+
#
|
72
|
+
# @return [User, nil] The current authenticated user.
|
73
|
+
def current_user
|
74
|
+
@current_user ||= current_user_session.user
|
75
|
+
end
|
73
76
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
# The current authentication session, if one exists. A {Session} object will be
|
78
|
+
# returned regardless of its valid status. If an invalid session is returned, the
|
79
|
+
# {Session#user user} attribute will be nil.
|
80
|
+
#
|
81
|
+
# @return [Session] The current browser session.
|
82
|
+
def current_user_session
|
83
|
+
@current_user_session ||= Challah::Session.find(request, params, user_model)
|
84
|
+
end
|
82
85
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
86
|
+
# Restrict a controller to only authenticated users. If someone tries to access
|
87
|
+
# a restricted action and is not logged in, they will be redirected to the
|
88
|
+
# login page.
|
89
|
+
#
|
90
|
+
# This method is an alias for:
|
91
|
+
#
|
92
|
+
# restrict_to_authenticated
|
93
|
+
#
|
94
|
+
# @example
|
95
|
+
# class YourController < ApplicationController
|
96
|
+
# before_action :login_required
|
97
|
+
#
|
98
|
+
# # ...
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# @example Specifing certain actions.
|
102
|
+
# class YourOtherController < ApplicationController
|
103
|
+
# before_action :login_required, :only => [ :create, :update, :destroy ]
|
104
|
+
#
|
105
|
+
# # ...
|
106
|
+
# end
|
107
|
+
#
|
108
|
+
# @see Controller::ClassMethods#restrict_to_authenticated restrict_to_authenticated
|
109
|
+
def signin_required
|
110
|
+
unless signed_in?
|
111
|
+
session[:return_to] = request.url
|
112
|
+
redirect_to(signin_path) && (return)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
alias_method :login_required, :signin_required
|
116
|
+
|
117
|
+
def user_model
|
118
|
+
@_challah_user_model ||= Challah.user
|
110
119
|
end
|
111
|
-
end
|
112
|
-
alias_method :login_required, :signin_required
|
113
120
|
|
114
|
-
def user_model
|
115
|
-
@_challah_user_model ||= Challah.user
|
116
|
-
end
|
117
121
|
end
|
118
122
|
end
|
data/lib/challah/cookie_store.rb
CHANGED
@@ -9,15 +9,17 @@ module Challah
|
|
9
9
|
# a new class that responds to +read+, +save+ and +destroy+
|
10
10
|
#
|
11
11
|
class CookieStore < SimpleCookieStore
|
12
|
+
|
12
13
|
def inspect
|
13
|
-
"#<CookieStore:0x#{object_id.to_s(16)} valid=#{existing?}>"
|
14
|
+
"#<CookieStore:0x#{ object_id.to_s(16) } valid=#{ existing? }>"
|
14
15
|
end
|
15
16
|
|
16
17
|
protected
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
def validation_cookie_value(value = nil)
|
20
|
+
value = session_cookie_value unless value
|
21
|
+
Encrypter.md5(value, request.user_agent, request.remote_ip)
|
22
|
+
end
|
23
|
+
|
22
24
|
end
|
23
25
|
end
|
data/lib/challah/encrypter.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "digest/sha2"
|
2
|
+
require "bcrypt"
|
3
3
|
|
4
4
|
module Challah
|
5
5
|
# Handles all encryption, hashing and comparison necessary for tokens and passwords.
|
6
6
|
class Encrypter
|
7
|
+
|
7
8
|
attr_accessor :cost, :joiner
|
8
9
|
|
9
10
|
# The number of times to hash the given password.
|
@@ -54,5 +55,6 @@ module Challah
|
|
54
55
|
def self.md5(*args)
|
55
56
|
new().md5(*args)
|
56
57
|
end
|
58
|
+
|
57
59
|
end
|
58
60
|
end
|
data/lib/challah/engine.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
module Challah
|
2
2
|
class Engine < ::Rails::Engine
|
3
3
|
|
4
|
-
initializer
|
5
|
-
app.routes_reloader.paths.insert(0, File.expand_path(File.join(File.dirname(__FILE__),
|
4
|
+
initializer "challah.router" do |app|
|
5
|
+
app.routes_reloader.paths.insert(0, File.expand_path(File.join(File.dirname(__FILE__), "routes.rb")))
|
6
6
|
end
|
7
7
|
|
8
|
-
initializer
|
8
|
+
initializer "challah.active_record" do
|
9
9
|
ActiveSupport.on_load :active_record do
|
10
10
|
Challah::Engine.setup_active_record!
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
initializer
|
14
|
+
initializer "challah.action_controller" do
|
15
15
|
ActiveSupport.on_load :action_controller do
|
16
16
|
Challah::Engine.setup_action_controller!
|
17
17
|
end
|
@@ -33,13 +33,6 @@ module Challah
|
|
33
33
|
if defined?(ActionController::API)
|
34
34
|
ActionController::API.send(:include, Challah::Controller)
|
35
35
|
end
|
36
|
-
|
37
|
-
# Load any ActionController/Challah plugins
|
38
|
-
Challah.plugins.values.each do |plugin|
|
39
|
-
plugin.action_controller.each do |proc|
|
40
|
-
proc.call
|
41
|
-
end
|
42
|
-
end
|
43
36
|
end
|
44
37
|
end
|
45
38
|
|
@@ -49,14 +42,8 @@ module Challah
|
|
49
42
|
Challah.options[:logger] = ActiveRecord::Base.logger
|
50
43
|
|
51
44
|
ActiveRecord::Base.send(:include, Challah::Audit)
|
52
|
-
|
53
|
-
# Load any ActiveRecord/Challah plugins
|
54
|
-
Challah.plugins.values.each do |plugin|
|
55
|
-
plugin.active_record.each do |proc|
|
56
|
-
proc.call
|
57
|
-
end
|
58
|
-
end
|
59
45
|
end
|
60
46
|
end
|
47
|
+
|
61
48
|
end
|
62
49
|
end
|