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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/README.md +5 -38
  4. data/VERSION +1 -1
  5. data/app/controllers/sessions_controller.rb +11 -10
  6. data/app/models/authorization.rb +2 -0
  7. data/lib/challah/audit.rb +38 -36
  8. data/lib/challah/authenticators/api_key.rb +4 -2
  9. data/lib/challah/authenticators/password.rb +3 -1
  10. data/lib/challah/authenticators.rb +5 -3
  11. data/lib/challah/concerns/authorizeable.rb +4 -0
  12. data/lib/challah/concerns/user/attributeable.rb +35 -33
  13. data/lib/challah/concerns/user/authenticateable.rb +2 -0
  14. data/lib/challah/concerns/user/authorizable.rb +16 -12
  15. data/lib/challah/concerns/user/findable.rb +13 -10
  16. data/lib/challah/concerns/user/passwordable.rb +5 -3
  17. data/lib/challah/concerns/user/provideable.rb +22 -20
  18. data/lib/challah/concerns/user/statusable.rb +3 -21
  19. data/lib/challah/concerns/user/validateable.rb +3 -1
  20. data/lib/challah/concerns/userable.rb +1 -3
  21. data/lib/challah/controller.rb +69 -65
  22. data/lib/challah/cookie_store.rb +7 -5
  23. data/lib/challah/encrypter.rb +4 -2
  24. data/lib/challah/engine.rb +5 -18
  25. data/lib/challah/providers/password_provider.rb +9 -7
  26. data/lib/challah/providers.rb +3 -1
  27. data/lib/challah/random.rb +6 -4
  28. data/lib/challah/routes.rb +6 -6
  29. data/lib/challah/session.rb +27 -25
  30. data/lib/challah/signup.rb +5 -3
  31. data/lib/challah/simple_cookie_store.rb +82 -80
  32. data/lib/challah/techniques/api_key_technique.rb +2 -2
  33. data/lib/challah/techniques/password_technique.rb +2 -1
  34. data/lib/challah/techniques/token_technique.rb +1 -1
  35. data/lib/challah/techniques.rb +2 -0
  36. data/lib/challah/test.rb +6 -0
  37. data/lib/challah/validators/email_validator.rb +2 -0
  38. data/lib/challah/validators/password_validator.rb +5 -3
  39. data/lib/challah/version.rb +3 -1
  40. data/lib/challah.rb +2 -5
  41. data/lib/generators/challah_generator.rb +2 -8
  42. data/lib/generators/templates/{migration.rb → migration.erb} +3 -6
  43. metadata +42 -19
  44. 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
- def find_by_authorization(uid)
19
- authorization = self.authorization_model
20
- result = authorization.where(provider: :password, uid: uid).first
21
- if result
22
- result.user
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 or @username_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
- def clear_cached_providers_after_save
80
- @providers = nil
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
- # Save any other providers
94
- Challah.custom_providers.each do |name, klass|
95
- custom_provider_attributes = provider_attributes[name]
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
- if custom_provider_attributes.respond_to?(:fetch)
98
- if klass.valid?(self)
99
- klass.save(self)
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
- end
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
@@ -1,5 +1,6 @@
1
1
  module Challah
2
2
  module UserValidateable
3
+
3
4
  extend ActiveSupport::Concern
4
5
 
5
6
  included do
@@ -17,5 +18,6 @@ module Challah
17
18
 
18
19
  validates_with Challah.options[:password_validator], force: false
19
20
  end
21
+
20
22
  end
21
- end
23
+ end
@@ -1,5 +1,6 @@
1
1
  module Challah
2
2
  module Userable
3
+
3
4
  extend ActiveSupport::Concern
4
5
 
5
6
  include UserAttributeable
@@ -14,8 +15,5 @@ module Challah
14
15
  include UserValidateable
15
16
  end
16
17
 
17
- included do
18
- Challah.include_user_plugins!
19
- end
20
18
  end
21
19
  end
@@ -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
- # Is there currently a logged in user? Returns true if it is safe to use
47
- # the {#current_user current_user} method.
48
- #
49
- # @note This method is also available as a helper in your views.
50
- #
51
- # @see #current_user current_user
52
- #
53
- # @return [Boolean] Is there a user logged in?
54
- def current_user?
55
- !!current_user
56
- end
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
- # Alias for current_user?
59
- def signed_in?
60
- current_user?
61
- end
62
- alias_method :logged_in?, :signed_in?
61
+ # Alias for current_user?
62
+ def signed_in?
63
+ current_user?
64
+ end
65
+ alias_method :logged_in?, :signed_in?
63
66
 
64
- # The user that is currently logged into this session. If there is no
65
- # user logged in, nil will be returned.
66
- #
67
- # @note This method is also available as a helper in your views.
68
- #
69
- # @return [User, nil] The current authenticated user.
70
- def current_user
71
- @current_user ||= current_user_session.user
72
- end
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
- # The current authentication session, if one exists. A {Session} object will be
75
- # returned regardless of its valid status. If an invalid session is returned, the
76
- # {Session#user user} attribute will be nil.
77
- #
78
- # @return [Session] The current browser session.
79
- def current_user_session
80
- @current_user_session ||= Challah::Session.find(request, params, user_model)
81
- end
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
- # Restrict a controller to only authenticated users. If someone tries to access
84
- # a restricted action and is not logged in, they will be redirected to the
85
- # login page.
86
- #
87
- # This method is an alias for:
88
- #
89
- # restrict_to_authenticated
90
- #
91
- # @example
92
- # class YourController < ApplicationController
93
- # before_action :login_required
94
- #
95
- # # ...
96
- # end
97
- #
98
- # @example Specifing certain actions.
99
- # class YourOtherController < ApplicationController
100
- # before_action :login_required, :only => [ :create, :update, :destroy ]
101
- #
102
- # # ...
103
- # end
104
- #
105
- # @see Controller::ClassMethods#restrict_to_authenticated restrict_to_authenticated
106
- def signin_required
107
- unless signed_in?
108
- session[:return_to] = request.url
109
- redirect_to signin_path and return
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
@@ -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
- def validation_cookie_value(value = nil)
19
- value = session_cookie_value unless value
20
- Encrypter.md5(value, request.user_agent, request.remote_ip)
21
- end
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
@@ -1,9 +1,10 @@
1
- require 'digest/sha2'
2
- require 'bcrypt'
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
@@ -1,17 +1,17 @@
1
1
  module Challah
2
2
  class Engine < ::Rails::Engine
3
3
 
4
- initializer 'challah.router' do |app|
5
- app.routes_reloader.paths.insert(0, File.expand_path(File.join(File.dirname(__FILE__), 'routes.rb')))
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 'challah.active_record' do
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 'challah.action_controller' do
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