challah 1.1.1 → 1.2.0.rc

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -1
  3. data/README.md +3 -3
  4. data/app/models/authorization.rb +2 -2
  5. data/app/models/user.rb +2 -2
  6. data/lib/challah.rb +60 -53
  7. data/lib/challah/active_record_extensions.rb +23 -0
  8. data/lib/challah/{authorization.rb → concerns/authorizeable.rb} +14 -19
  9. data/lib/challah/concerns/user/attributeable.rb +73 -0
  10. data/lib/challah/{user/authentication.rb → concerns/user/authenticateable.rb} +2 -2
  11. data/lib/challah/concerns/user/authorizable.rb +32 -0
  12. data/lib/challah/concerns/user/findable.rb +45 -0
  13. data/lib/challah/{user/password.rb → concerns/user/passwordable.rb} +2 -2
  14. data/lib/challah/{user/providers.rb → concerns/user/provideable.rb} +46 -6
  15. data/lib/challah/concerns/user/validateable.rb +21 -0
  16. data/lib/challah/concerns/userable.rb +20 -0
  17. data/lib/challah/engine.rb +1 -2
  18. data/lib/challah/test.rb +52 -32
  19. data/lib/challah/version.rb +1 -1
  20. metadata +14 -76
  21. data/lib/challah/user.rb +0 -128
  22. data/lib/challah/user/attributes.rb +0 -28
  23. data/lib/challah/user/finders.rb +0 -31
  24. data/lib/challah/user/reflector.rb +0 -15
  25. data/test/controllers/controller_test.rb +0 -34
  26. data/test/controllers/restrictions_controller_test.rb +0 -95
  27. data/test/controllers/sessions_controller_test.rb +0 -42
  28. data/test/dummy/README.rdoc +0 -28
  29. data/test/dummy/Rakefile +0 -6
  30. data/test/dummy/app/assets/javascripts/application.js +0 -13
  31. data/test/dummy/app/assets/stylesheets/application.css +0 -13
  32. data/test/dummy/app/controllers/application_controller.rb +0 -5
  33. data/test/dummy/app/controllers/restrictions_controller.rb +0 -25
  34. data/test/dummy/app/helpers/application_helper.rb +0 -2
  35. data/test/dummy/app/models/user.rb +0 -15
  36. data/test/dummy/app/models/widget.rb +0 -3
  37. data/test/dummy/app/views/bakery/templates/layouts/sample.erb +0 -1
  38. data/test/dummy/app/views/bakery/templates/partials/sample.html.haml +0 -1
  39. data/test/dummy/app/views/bakery/templates/themes/sample.haml +0 -1
  40. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  41. data/test/dummy/config.ru +0 -4
  42. data/test/dummy/config/application.rb +0 -24
  43. data/test/dummy/config/boot.rb +0 -5
  44. data/test/dummy/config/database.yml +0 -30
  45. data/test/dummy/config/environment.rb +0 -5
  46. data/test/dummy/config/environments/development.rb +0 -29
  47. data/test/dummy/config/environments/production.rb +0 -80
  48. data/test/dummy/config/environments/test.rb +0 -36
  49. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  50. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  51. data/test/dummy/config/initializers/i18n.rb +0 -1
  52. data/test/dummy/config/initializers/inflections.rb +0 -16
  53. data/test/dummy/config/initializers/mime_types.rb +0 -5
  54. data/test/dummy/config/initializers/secret_token.rb +0 -12
  55. data/test/dummy/config/initializers/session_store.rb +0 -3
  56. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  57. data/test/dummy/config/locales/en.yml +0 -23
  58. data/test/dummy/config/routes.rb +0 -5
  59. data/test/dummy/db/migrate/20140114212939_create_widgets.rb +0 -32
  60. data/test/dummy/db/migrate/20140307205735_create_users.challah_engine.rb +0 -34
  61. data/test/dummy/db/migrate/20140307205736_create_authorizations.challah_engine.rb +0 -21
  62. data/test/dummy/db/schema.rb +0 -81
  63. data/test/dummy/db/test.sqlite3 +0 -0
  64. data/test/dummy/log/test.log +0 -11547
  65. data/test/dummy/public/404.html +0 -58
  66. data/test/dummy/public/422.html +0 -58
  67. data/test/dummy/public/500.html +0 -57
  68. data/test/dummy/public/favicon.ico +0 -0
  69. data/test/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  70. data/test/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  71. data/test/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  72. data/test/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  73. data/test/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  74. data/test/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  75. data/test/factories.rb +0 -8
  76. data/test/models/authorization_test.rb +0 -20
  77. data/test/models/user_test.rb +0 -345
  78. data/test/services/audit_test.rb +0 -107
  79. data/test/services/cookie_store_test.rb +0 -97
  80. data/test/services/encrypter_test.rb +0 -73
  81. data/test/services/plugins_test.rb +0 -65
  82. data/test/services/random_test.rb +0 -22
  83. data/test/services/routes_test.rb +0 -11
  84. data/test/services/session_test.rb +0 -197
  85. data/test/services/signup_test.rb +0 -122
  86. data/test/services/simple_cookie_store_test.rb +0 -122
  87. data/test/support/stubs.rb +0 -88
  88. data/test/test_helper.rb +0 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a04a0045083c40526c41b4bb5e55606a99fb380c
4
- data.tar.gz: 192237d8884a972ac4a9fcdc97bf413814d8a378
3
+ metadata.gz: 7f5f10d1f9752cdc2f931499b2fe600a8ba6486a
4
+ data.tar.gz: b017bd1018d5e4cebe7d21074d718c0d41653eab
5
5
  SHA512:
6
- metadata.gz: 99461c5009e3db27fa353fb0abb551b1a25e0012c0622144f5c1a9f45fc30334e651c8820d8efdfc423021407a9aa809f90b238d3ff0b32ace267f7c63e63bdf
7
- data.tar.gz: a5b91063515c94e25d33189fbaa94866e66592eadcbd50cbc5459267ab499145f83c5b6366c259367348f0dc2c1903635e8891e5ad275cb66ff6368427f125f4
6
+ metadata.gz: f6a938dda2a821281f14832ba8225f5e3a711bec8b2fe8e62eae2564304d214d4dd78fd36e192cea36ff90abda58fbc002bb78b071a2fa9fb25fdf065a8b3ade
7
+ data.tar.gz: d73118e85864d9112c865b926b69e35324ee489ce7aa55ee667c3222d198d538b6bc2a204fb59daf22beef4c01d7b4f5726f6b3f54888fe1143dd78476ac4317
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## Challah (Not Released)
2
+
3
+ * Convert tests to RSpec
4
+ * Remove use of `challah_user` and replace with concerns
5
+ * Internal clean up of included modules
6
+
7
+ ## Challah 1.1.1
8
+
9
+ * Internal clean up of tests and gem dependencies
10
+ * Enable compatibility with Rails 4.1.0.rc1
11
+
1
12
  ## Challah 1.1.0
2
13
 
3
14
  * Allow challah to authenticate with User and Authorization tables that using namespaces
@@ -131,4 +142,4 @@
131
142
 
132
143
  ## Challah 0.2.0
133
144
 
134
- * Initial build. Basic functionality for session persistence and authentication.
145
+ * Initial build. Basic functionality for session persistence and authentication.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Challah
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/jdtornow/challah.png)](http://travis-ci.org/jdtornow/challah) [![Dependency Status](https://gemnasium.com/jdtornow/challah.png?travis)](https://gemnasium.com/jdtornow/challah)
3
+ [![Build Status](https://secure.travis-ci.org/jdtornow/challah.png)](http://travis-ci.org/jdtornow/challah) [![Code Climate](https://codeclimate.com/github/jdtornow/challah.png)](https://codeclimate.com/github/jdtornow/challah) [![Dependency Status](https://gemnasium.com/jdtornow/challah.png?travis)](https://gemnasium.com/jdtornow/challah) [![Gem Version](https://badge.fury.io/rb/challah.png)](http://badge.fury.io/rb/challah)
4
4
 
5
5
  Challah (pronounced HAH-lah) is a simple Rails authentication gem that provides users a way to authenticate with your app. Most of the functionality within the gem lives within a Rails engine and tries to stay out of the way of your app.
6
6
 
@@ -144,9 +144,9 @@ If you have any issues or find bugs running Challah, please [report them on Gith
144
144
 
145
145
  ### Testing
146
146
 
147
- Challah is fully tested using Test Unit, Shoulda and Mocha. To run the test suite, `bundle install` then run:
147
+ Challah is fully tested using RSpec. To run the test suite, `bundle install` then run:
148
148
 
149
- rake test
149
+ rspec
150
150
 
151
151
  ## License
152
152
 
@@ -1,3 +1,3 @@
1
1
  class Authorization < ActiveRecord::Base
2
- challah_authorization
3
- end
2
+ include Challah::Authorizeable
3
+ end
data/app/models/user.rb CHANGED
@@ -11,5 +11,5 @@ class User < ActiveRecord::Base
11
11
  # For a list of all methods included into User, see:
12
12
  #
13
13
  # http://rubydoc.info/gems/challah
14
- challah_user
15
- end
14
+ include Challah::Userable
15
+ end
data/lib/challah.rb CHANGED
@@ -1,59 +1,66 @@
1
- require 'challah/version'
1
+ require "challah/version"
2
2
 
3
3
  module Challah
4
- autoload :Audit, 'challah/audit'
5
-
6
- autoload :CookieStore, 'challah/cookie_store'
7
- autoload :SimpleCookieStore, 'challah/simple_cookie_store'
8
-
9
- autoload :Authenticators, 'challah/authenticators'
10
- autoload :Controller, 'challah/controller'
11
- autoload :Encrypter, 'challah/encrypter'
12
- autoload :Plugins, 'challah/plugins'
13
- autoload :Providers, 'challah/providers'
14
- autoload :Random, 'challah/random'
15
- autoload :Session, 'challah/session'
16
- autoload :Signup, 'challah/signup'
17
- autoload :Techniques, 'challah/techniques'
18
- autoload :Techniques, 'challah/techniques'
19
-
20
- autoload :EmailValidator, 'challah/validators/email_validator'
21
- autoload :PasswordValidator, 'challah/validators/password_validator'
22
-
23
- autoload :Authorization, 'challah/authorization'
24
- autoload :User, 'challah/user'
25
-
26
- autoload :PasswordProvider, 'challah/providers/password_provider'
4
+ autoload :Audit, "challah/audit"
5
+
6
+ autoload :CookieStore, "challah/cookie_store"
7
+ autoload :SimpleCookieStore, "challah/simple_cookie_store"
8
+
9
+ autoload :Authenticators, "challah/authenticators"
10
+ autoload :Controller, "challah/controller"
11
+ autoload :Encrypter, "challah/encrypter"
12
+ autoload :Plugins, "challah/plugins"
13
+ autoload :Providers, "challah/providers"
14
+ autoload :Random, "challah/random"
15
+ autoload :Session, "challah/session"
16
+ autoload :Signup, "challah/signup"
17
+ autoload :Techniques, "challah/techniques"
18
+ autoload :Techniques, "challah/techniques"
19
+
20
+ autoload :EmailValidator, "challah/validators/email_validator"
21
+ autoload :PasswordValidator, "challah/validators/password_validator"
22
+
23
+ autoload :PasswordProvider, "challah/providers/password_provider"
24
+
25
+ autoload :ActiveRecordExtensions, "challah/active_record_extensions"
26
+
27
+ autoload :Authorizeable, "challah/concerns/authorizeable"
28
+ autoload :Userable, "challah/concerns/userable"
29
+ autoload :UserAttributeable, "challah/concerns/user/attributeable"
30
+ autoload :UserAuthenticateable, "challah/concerns/user/authenticateable"
31
+ autoload :UserAuthorizable, "challah/concerns/user/authorizable"
32
+ autoload :UserFindable, "challah/concerns/user/findable"
33
+ autoload :UserPasswordable, "challah/concerns/user/passwordable"
34
+ autoload :UserProvideable, "challah/concerns/user/provideable"
35
+ autoload :UserValidateable, "challah/concerns/user/validateable"
27
36
 
28
37
  # Configuration options
29
- class << self
30
- # Get or set options for the current Challah instance. In most cases these should be
31
- # changed within a config/initializers/ file in your app.
32
- #
33
- # @param [Hash] options The options to get or set
34
- # @option options [String] :cookie_prefix ('challah') A prefix to put in the names of the cookies that will be set.
35
- # @option options [String] :access_denied_view ('challah/sessions/access_denied')Relative path to the view that will be used to show access denied method.
36
- # @option options [Class] :storage_class (SimpleCookieStore) The class to use for persistence of sessions.
37
- # @option options [Boolean] :skip_routes (false) Pass in true to not add any routes into your Rails app by default.
38
- # @option options [String] :email_validator ('challah/email') Pass in a string name of the class to use for email validation. Class should inherit from ActiveModel::EachValidator
39
- # @option options [Class] :password_validator (Challah::PasswordValidator) Pass in a class to use for password validation.
40
- def options
41
- @options ||= {
42
- access_denied_view: 'sessions/access_denied',
43
- api_key_enabled: false,
44
- cookie_prefix: 'challah',
45
- email_validator: 'challah/email',
46
- password_validator: PasswordValidator,
47
- skip_routes: false,
48
- skip_user_validations: false,
49
- storage_class: SimpleCookieStore,
50
- user: :User
51
- }
52
- end
53
-
54
- def user
55
- @user ||= options[:user].to_s.safe_constantize
56
- end
38
+ # Get or set options for the current Challah instance. In most cases these should be
39
+ # changed within a config/initializers/ file in your app.
40
+ #
41
+ # @param [Hash] options The options to get or set
42
+ # @option options [String] :cookie_prefix ("challah") A prefix to put in the names of the cookies that will be set.
43
+ # @option options [String] :access_denied_view ("challah/sessions/access_denied")Relative path to the view that will be used to show access denied method.
44
+ # @option options [Class] :storage_class (SimpleCookieStore) The class to use for persistence of sessions.
45
+ # @option options [Boolean] :skip_routes (false) Pass in true to not add any routes into your Rails app by default.
46
+ # @option options [String] :email_validator ("challah/email") Pass in a string name of the class to use for email validation. Class should inherit from ActiveModel::EachValidator
47
+ # @option options [Class] :password_validator (Challah::PasswordValidator) Pass in a class to use for password validation.
48
+ def self.options
49
+ @options ||= {
50
+ access_denied_view: "sessions/access_denied",
51
+ api_key_enabled: false,
52
+ cookie_prefix: "challah",
53
+ email_validator: "challah/email",
54
+ password_validator: PasswordValidator,
55
+ skip_routes: false,
56
+ skip_user_validations: false,
57
+ storage_class: SimpleCookieStore,
58
+ user: :User
59
+ }
60
+ end
61
+
62
+ def self.user
63
+ @user ||= options[:user].to_s.safe_constantize
57
64
  end
58
65
 
59
66
  # Set up techniques engines
@@ -83,4 +90,4 @@ module Challah
83
90
  register_provider :password, PasswordProvider
84
91
  end
85
92
 
86
- require 'challah/engine' if defined?(Rails)
93
+ require "challah/engine" if defined?(Rails)
@@ -0,0 +1,23 @@
1
+ module Challah
2
+ # Included for backwards compatibility. These methods are deprecated
3
+ # and will be removed in future versions
4
+ module ActiveRecordExtensions
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ extend ClassMethods
9
+ end
10
+
11
+ module ClassMethods
12
+ def challah_authorization
13
+ ActiveSupport::Deprecation.warn("#{ self.to_s }.challah_authorization is deprecated and will be removed in future versions, use `include Challah::Authorizeable` instead")
14
+ self.send(:include, Challah::Authorizeable)
15
+ end
16
+
17
+ def challah_user
18
+ ActiveSupport::Deprecation.warn("#{ self.to_s }.challah_user is deprecated and will be removed in future versions, use `include Challah::Userable` instead")
19
+ self.send(:include, Challah::Userable)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,18 +1,14 @@
1
1
  module Challah
2
- module Authorization
2
+ module Authorizeable
3
+ extend ActiveSupport::Concern
3
4
 
4
- def challah_authorization
5
- unless included_modules.include?(InstanceMethods)
6
- include InstanceMethods
7
- extend ClassMethods
8
- end
5
+ included do
6
+ extend ClassMethods
9
7
  end
10
8
 
11
- module InstanceMethods
12
- def user
13
- return nil unless self.user_id
14
- @user ||= self.class.user_model.where(id: self.user_id).first
15
- end
9
+ def user
10
+ return nil unless self.user_id
11
+ @user ||= self.class.user_model.where(id: self.user_id).first
16
12
  end
17
13
 
18
14
  module ClassMethods
@@ -59,15 +55,14 @@ module Challah
59
55
  record.save!
60
56
  record
61
57
  end
62
- end
63
58
 
64
- def users_table_name
65
- @users_table_name ||= user_model.table_name
66
- end
59
+ def users_table_name
60
+ @users_table_name ||= user_model.table_name
61
+ end
67
62
 
68
- def user_model
69
- @user_model ||= Challah.user
63
+ def user_model
64
+ @user_model ||= Challah.user
65
+ end
70
66
  end
71
-
72
67
  end
73
- end
68
+ end
@@ -0,0 +1,73 @@
1
+ module Challah
2
+ module UserAttributeable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attr_reader :password
7
+ attr_reader :password_confirmation
8
+ attr_reader :password_updated
9
+
10
+ before_save :ensure_user_tokens
11
+ end
12
+
13
+ # Returns true if this user is active, and should be able to log in. If
14
+ # the active column is false, the user will not be able to authenticate
15
+ def active?
16
+ !!self.active
17
+ end
18
+
19
+ # First name and last name together
20
+ def name
21
+ "#{ first_name } #{ last_name }".strip
22
+ end
23
+
24
+ # shortened name, just includes the first name and last initial
25
+ def small_name
26
+ "#{ first_name.to_s.titleize } #{ last_name.to_s.first.upcase }."
27
+ end
28
+
29
+ # Is this user valid and ready for a user session?
30
+ #
31
+ # Override this method if you need to check for a particular configuration on each page request.
32
+ def valid_session?
33
+ self.active?
34
+ end
35
+
36
+ protected
37
+
38
+ # Ensure that all system-generated columns aren't blank on each save
39
+ def ensure_user_tokens
40
+ ensure_api_key_presence
41
+ ensure_email_hash_presence
42
+ ensure_persistence_token_presence
43
+ end
44
+
45
+ # Store a random seed for this user's api key
46
+ def ensure_api_key_presence
47
+ if respond_to?("api_key=")
48
+ if self.api_key.to_s.blank?
49
+ self.api_key = Random.token(50)
50
+ end
51
+ end
52
+ end
53
+
54
+ # Store a hashed email if the column exists
55
+ def ensure_email_hash_presence
56
+ if respond_to?("email_hash=")
57
+ if email_changed?
58
+ self.email_hash = Encrypter.md5(email.to_s.downcase.strip)
59
+ end
60
+ end
61
+ end
62
+
63
+ # Store a random token to identify user in persisted objects
64
+ def ensure_persistence_token_presence
65
+ if respond_to?("persistence_token=")
66
+ if self.persistence_token.to_s.blank?
67
+ self.persistence_token = Random.token(125)
68
+ end
69
+ end
70
+ end
71
+
72
+ end
73
+ end
@@ -1,5 +1,5 @@
1
- module Challah::User
2
- module Authentication
1
+ module Challah
2
+ module UserAuthenticateable
3
3
  # Generic authentication method. By default, this just checks to see if the password
4
4
  # given matches this user. You can also pass in the first parameter as the method
5
5
  # to use for a different type of authentication.
@@ -0,0 +1,32 @@
1
+ module Challah
2
+ module UserAuthorizable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ extend ClassMethods
7
+
8
+ before_destroy :clear_authorizations_before_destroy
9
+ end
10
+
11
+ protected
12
+
13
+ def authorizations
14
+ return [] if new_record?
15
+ self.class.authorization_model.where(user_id: self.id)
16
+ end
17
+
18
+ def clear_authorizations_before_destroy
19
+ authorizations.destroy_all
20
+ end
21
+
22
+ module ClassMethods
23
+ def authorizations_table_name
24
+ @authorizations_table_name ||= authorization_model.table_name
25
+ end
26
+
27
+ def authorization_model
28
+ @authorization_model ||= ::Authorization
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ module Challah
2
+ module UserFindable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def active
11
+ where(active: true)
12
+ end
13
+
14
+ # Find a user instance by username first, or email address if needed.
15
+ # If no user is found matching, return nil
16
+ def find_for_session(username_or_email)
17
+ return nil if username_or_email.to_s.blank?
18
+
19
+ result = nil
20
+
21
+ if username_or_email.to_s.include?('@')
22
+ result = where(email: username_or_email).first
23
+ end
24
+
25
+ if !result
26
+ uid = username_or_email.to_s.downcase.strip
27
+
28
+ authorization = self.authorization_model
29
+ authorization = authorization.where(provider: :password, uid: uid)
30
+ authorization = authorization.first
31
+
32
+ if authorization
33
+ result = authorization.user
34
+ end
35
+ end
36
+
37
+ result
38
+ end
39
+
40
+ def inactive
41
+ where.not(active: true)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,5 +1,5 @@
1
- module Challah::User
2
- module Password
1
+ module Challah
2
+ module UserPasswordable
3
3
  # Set the password and password_confirmation in one shortcut method.
4
4
  def password!(new_password)
5
5
  self.password = new_password
@@ -1,9 +1,22 @@
1
- module Challah::User
2
- module Providers
1
+ module Challah
2
+ module UserProvideable
3
+ extend ActiveSupport::Concern
3
4
 
4
- def authorizations
5
- return [] if new_record?
6
- self.class.authorization_model.where(user_id: self.id)
5
+ included do
6
+ after_save :update_modified_providers_after_save
7
+ after_save :clear_cached_providers_after_save
8
+ end
9
+
10
+ def method_missing(method, *args)
11
+ method_name = method.to_s
12
+
13
+ if method_name =~ /^([a-z]*)_provider\?$/
14
+ return provider?($1)
15
+ elsif method_name =~ /^([a-z]*)_provider$/
16
+ return provider($1)
17
+ end
18
+
19
+ super
7
20
  end
8
21
 
9
22
  def providers
@@ -60,6 +73,33 @@ module Challah::User
60
73
  false
61
74
  end
62
75
  end
63
- end
64
76
 
77
+ protected
78
+
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
91
+ end
92
+
93
+ # Save any other providers
94
+ Challah.custom_providers.each do |name, klass|
95
+ custom_provider_attributes = provider_attributes[name]
96
+
97
+ if custom_provider_attributes.respond_to?(:fetch)
98
+ if klass.valid?(self)
99
+ klass.save(self)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
65
105
  end