sorcery 0.6.1 → 0.7.10

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 (205) hide show
  1. data/.travis.yml +2 -0
  2. data/Gemfile +2 -23
  3. data/Gemfile.lock +105 -77
  4. data/README.rdoc +32 -59
  5. data/Rakefile +29 -1
  6. data/VERSION +1 -1
  7. data/lib/generators/sorcery/USAGE +22 -0
  8. data/lib/generators/sorcery/install_generator.rb +77 -0
  9. data/lib/generators/sorcery/templates/initializer.rb +406 -0
  10. data/lib/generators/sorcery/templates/migration/activity_logging.rb +17 -0
  11. data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +13 -0
  12. data/lib/generators/{sorcery_migration/templates → sorcery/templates/migration}/core.rb +3 -3
  13. data/lib/generators/{sorcery_migration/templates → sorcery/templates/migration}/external.rb +1 -1
  14. data/lib/generators/sorcery/templates/migration/remember_me.rb +15 -0
  15. data/lib/generators/sorcery/templates/migration/reset_password.rb +17 -0
  16. data/lib/generators/sorcery/templates/migration/user_activation.rb +17 -0
  17. data/lib/sorcery/controller/submodules/activity_logging.rb +24 -10
  18. data/lib/sorcery/controller/submodules/brute_force_protection.rb +3 -2
  19. data/lib/sorcery/controller/submodules/external/protocols/certs/ca-bundle.crt +5182 -0
  20. data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +28 -9
  21. data/lib/sorcery/controller/submodules/external/providers/facebook.rb +12 -4
  22. data/lib/sorcery/controller/submodules/external/providers/github.rb +89 -0
  23. data/lib/sorcery/controller/submodules/external/providers/google.rb +90 -0
  24. data/lib/sorcery/controller/submodules/external/providers/liveid.rb +91 -0
  25. data/lib/sorcery/controller/submodules/external/providers/twitter.rb +8 -2
  26. data/lib/sorcery/controller/submodules/external.rb +17 -4
  27. data/lib/sorcery/controller/submodules/http_basic_auth.rb +1 -1
  28. data/lib/sorcery/controller/submodules/remember_me.rb +26 -15
  29. data/lib/sorcery/controller/submodules/session_timeout.rb +4 -4
  30. data/lib/sorcery/controller.rb +61 -38
  31. data/lib/sorcery/crypto_providers/aes256.rb +7 -3
  32. data/lib/sorcery/engine.rb +1 -0
  33. data/lib/sorcery/model/adapters/active_record.rb +17 -1
  34. data/lib/sorcery/model/adapters/mongo_mapper.rb +54 -0
  35. data/lib/sorcery/model/adapters/mongoid.rb +22 -4
  36. data/lib/sorcery/model/submodules/activity_logging.rb +4 -4
  37. data/lib/sorcery/model/submodules/brute_force_protection.rb +53 -14
  38. data/lib/sorcery/model/submodules/remember_me.rb +10 -3
  39. data/lib/sorcery/model/submodules/reset_password.rb +26 -11
  40. data/lib/sorcery/model/submodules/user_activation.rb +28 -10
  41. data/lib/sorcery/model/temporary_token.rb +8 -1
  42. data/lib/sorcery/model.rb +51 -19
  43. data/lib/sorcery/test_helpers/internal/rails.rb +1 -1
  44. data/lib/sorcery/test_helpers/rails.rb +2 -2
  45. data/lib/sorcery.rb +8 -7
  46. data/sorcery.gemspec +110 -223
  47. data/spec/Gemfile +1 -1
  48. data/spec/Gemfile.lock +26 -26
  49. data/spec/README.md +31 -0
  50. data/spec/rails3/Gemfile +5 -3
  51. data/spec/rails3/Gemfile.lock +74 -48
  52. data/spec/rails3/app/controllers/application_controller.rb +70 -23
  53. data/spec/rails3/app/mailers/sorcery_mailer.rb +7 -0
  54. data/spec/rails3/app/views/application/index.html.erb +17 -0
  55. data/spec/rails3/app/views/sorcery_mailer/send_unlock_token_email.text.erb +1 -0
  56. data/spec/rails3/config/environments/in_memory.rb +35 -0
  57. data/spec/rails3/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +2 -0
  58. data/spec/rails3/spec/controller_activity_logging_spec.rb +33 -3
  59. data/spec/rails3/spec/controller_brute_force_protection_spec.rb +25 -3
  60. data/spec/rails3/spec/controller_oauth2_spec.rb +170 -25
  61. data/spec/rails3/spec/controller_remember_me_spec.rb +37 -6
  62. data/spec/rails3/spec/controller_session_timeout_spec.rb +4 -4
  63. data/spec/rails3/spec/controller_spec.rb +60 -2
  64. data/spec/rails3/spec/integration_spec.rb +23 -0
  65. data/spec/rails3/spec/spec_helper.rb +6 -5
  66. data/spec/rails3_mongo_mapper/.gitignore +4 -0
  67. data/spec/rails3_mongo_mapper/.rspec +1 -0
  68. data/spec/{sinatra_modular → rails3_mongo_mapper}/Gemfile +6 -5
  69. data/spec/rails3_mongo_mapper/Gemfile.lock +154 -0
  70. data/spec/{sinatra → rails3_mongo_mapper}/Rakefile +3 -3
  71. data/spec/rails3_mongo_mapper/app/controllers/application_controller.rb +108 -0
  72. data/spec/rails3_mongo_mapper/app/helpers/application_helper.rb +2 -0
  73. data/spec/rails3_mongo_mapper/app/models/authentication.rb +6 -0
  74. data/spec/rails3_mongo_mapper/app/models/user.rb +5 -0
  75. data/spec/rails3_mongo_mapper/app/views/layouts/application.html.erb +14 -0
  76. data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/activation_email.html.erb +17 -0
  77. data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/activation_email.text.erb +9 -0
  78. data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
  79. data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
  80. data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
  81. data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
  82. data/spec/rails3_mongo_mapper/config/application.rb +51 -0
  83. data/spec/rails3_mongo_mapper/config/boot.rb +13 -0
  84. data/spec/rails3_mongo_mapper/config/environment.rb +5 -0
  85. data/spec/rails3_mongo_mapper/config/environments/development.rb +30 -0
  86. data/spec/rails3_mongo_mapper/config/environments/in_memory.rb +0 -0
  87. data/spec/rails3_mongo_mapper/config/environments/production.rb +49 -0
  88. data/spec/rails3_mongo_mapper/config/environments/test.rb +35 -0
  89. data/spec/rails3_mongo_mapper/config/initializers/backtrace_silencers.rb +7 -0
  90. data/spec/rails3_mongo_mapper/config/initializers/inflections.rb +10 -0
  91. data/spec/rails3_mongo_mapper/config/initializers/mime_types.rb +5 -0
  92. data/spec/rails3_mongo_mapper/config/initializers/mongo.rb +2 -0
  93. data/spec/rails3_mongo_mapper/config/initializers/secret_token.rb +7 -0
  94. data/spec/rails3_mongo_mapper/config/initializers/session_store.rb +8 -0
  95. data/spec/rails3_mongo_mapper/config/locales/en.yml +5 -0
  96. data/spec/rails3_mongo_mapper/config/routes.rb +59 -0
  97. data/spec/rails3_mongo_mapper/config.ru +4 -0
  98. data/spec/rails3_mongo_mapper/db/schema.rb +23 -0
  99. data/spec/rails3_mongo_mapper/db/seeds.rb +7 -0
  100. data/spec/rails3_mongo_mapper/lib/tasks/.gitkeep +0 -0
  101. data/spec/rails3_mongo_mapper/public/404.html +26 -0
  102. data/spec/rails3_mongo_mapper/public/422.html +26 -0
  103. data/spec/rails3_mongo_mapper/public/500.html +26 -0
  104. data/spec/rails3_mongo_mapper/public/favicon.ico +0 -0
  105. data/spec/rails3_mongo_mapper/public/images/rails.png +0 -0
  106. data/spec/rails3_mongo_mapper/public/javascripts/application.js +2 -0
  107. data/spec/rails3_mongo_mapper/public/javascripts/controls.js +965 -0
  108. data/spec/rails3_mongo_mapper/public/javascripts/dragdrop.js +974 -0
  109. data/spec/rails3_mongo_mapper/public/javascripts/effects.js +1123 -0
  110. data/spec/rails3_mongo_mapper/public/javascripts/prototype.js +6001 -0
  111. data/spec/rails3_mongo_mapper/public/javascripts/rails.js +175 -0
  112. data/spec/rails3_mongo_mapper/public/robots.txt +5 -0
  113. data/spec/rails3_mongo_mapper/public/stylesheets/.gitkeep +0 -0
  114. data/spec/rails3_mongo_mapper/script/rails +6 -0
  115. data/spec/rails3_mongo_mapper/spec/controller_spec.rb +163 -0
  116. data/spec/rails3_mongo_mapper/spec/spec_helper.orig.rb +27 -0
  117. data/spec/rails3_mongo_mapper/spec/spec_helper.rb +55 -0
  118. data/spec/rails3_mongo_mapper/spec/user_activation_spec.rb +9 -0
  119. data/spec/rails3_mongo_mapper/spec/user_activity_logging_spec.rb +8 -0
  120. data/spec/rails3_mongo_mapper/spec/user_brute_force_protection_spec.rb +8 -0
  121. data/spec/rails3_mongo_mapper/spec/user_oauth_spec.rb +8 -0
  122. data/spec/rails3_mongo_mapper/spec/user_remember_me_spec.rb +8 -0
  123. data/spec/rails3_mongo_mapper/spec/user_reset_password_spec.rb +8 -0
  124. data/spec/rails3_mongo_mapper/spec/user_spec.rb +37 -0
  125. data/spec/rails3_mongo_mapper/vendor/plugins/.gitkeep +0 -0
  126. data/spec/rails3_mongoid/Gemfile +2 -1
  127. data/spec/rails3_mongoid/Gemfile.lock +46 -45
  128. data/spec/rails3_mongoid/app/controllers/application_controller.rb +5 -0
  129. data/spec/rails3_mongoid/config/mongoid.yml +1 -1
  130. data/spec/rails3_mongoid/script/rails +0 -0
  131. data/spec/rails3_mongoid/spec/controller_activity_logging_spec.rb +105 -0
  132. data/spec/rails3_mongoid/spec/controller_spec.rb +174 -0
  133. data/spec/rails3_mongoid/spec/user_spec.rb +1 -0
  134. data/spec/shared_examples/user_activation_shared_examples.rb +72 -42
  135. data/spec/shared_examples/user_remember_me_shared_examples.rb +2 -1
  136. data/spec/shared_examples/user_reset_password_shared_examples.rb +81 -28
  137. data/spec/shared_examples/user_shared_examples.rb +36 -8
  138. data/spec/sorcery_crypto_providers_spec.rb +5 -1
  139. metadata +239 -346
  140. data/lib/generators/sorcery_migration/sorcery_migration_generator.rb +0 -24
  141. data/lib/generators/sorcery_migration/templates/activity_logging.rb +0 -17
  142. data/lib/generators/sorcery_migration/templates/brute_force_protection.rb +0 -11
  143. data/lib/generators/sorcery_migration/templates/remember_me.rb +0 -15
  144. data/lib/generators/sorcery_migration/templates/reset_password.rb +0 -13
  145. data/lib/generators/sorcery_migration/templates/user_activation.rb +0 -17
  146. data/lib/sorcery/controller/adapters/sinatra.rb +0 -104
  147. data/lib/sorcery/initializers/initializer.rb +0 -178
  148. data/lib/sorcery/sinatra.rb +0 -4
  149. data/lib/sorcery/test_helpers/internal/sinatra.rb +0 -74
  150. data/lib/sorcery/test_helpers/internal/sinatra_modular.rb +0 -74
  151. data/lib/sorcery/test_helpers/sinatra.rb +0 -88
  152. data/spec/rails3/Rakefile.unused +0 -7
  153. data/spec/rails3/public/index.html +0 -239
  154. data/spec/sinatra/Gemfile +0 -15
  155. data/spec/sinatra/Gemfile.lock +0 -117
  156. data/spec/sinatra/authentication.rb +0 -3
  157. data/spec/sinatra/db/migrate/activation/20101224223622_add_activation_to_users.rb +0 -17
  158. data/spec/sinatra/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +0 -17
  159. data/spec/sinatra/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +0 -11
  160. data/spec/sinatra/db/migrate/core/20101224223620_create_users.rb +0 -16
  161. data/spec/sinatra/db/migrate/external/20101224223628_create_authentications.rb +0 -14
  162. data/spec/sinatra/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +0 -15
  163. data/spec/sinatra/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +0 -13
  164. data/spec/sinatra/filters.rb +0 -27
  165. data/spec/sinatra/modular.rb +0 -157
  166. data/spec/sinatra/myapp.rb +0 -133
  167. data/spec/sinatra/spec/controller_activity_logging_spec.rb +0 -85
  168. data/spec/sinatra/spec/controller_brute_force_protection_spec.rb +0 -70
  169. data/spec/sinatra/spec/controller_http_basic_auth_spec.rb +0 -53
  170. data/spec/sinatra/spec/controller_oauth2_spec.rb +0 -99
  171. data/spec/sinatra/spec/controller_oauth_spec.rb +0 -100
  172. data/spec/sinatra/spec/controller_remember_me_spec.rb +0 -64
  173. data/spec/sinatra/spec/controller_session_timeout_spec.rb +0 -57
  174. data/spec/sinatra/spec/controller_spec.rb +0 -120
  175. data/spec/sinatra/spec/spec_helper.rb +0 -45
  176. data/spec/sinatra/user.rb +0 -6
  177. data/spec/sinatra/views/test_login.erb +0 -4
  178. data/spec/sinatra_modular/Gemfile.lock +0 -117
  179. data/spec/sinatra_modular/Rakefile +0 -11
  180. data/spec/sinatra_modular/authentication.rb +0 -3
  181. data/spec/sinatra_modular/db/migrate/activation/20101224223622_add_activation_to_users.rb +0 -17
  182. data/spec/sinatra_modular/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +0 -17
  183. data/spec/sinatra_modular/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +0 -11
  184. data/spec/sinatra_modular/db/migrate/core/20101224223620_create_users.rb +0 -16
  185. data/spec/sinatra_modular/db/migrate/external/20101224223628_create_authentications.rb +0 -14
  186. data/spec/sinatra_modular/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +0 -15
  187. data/spec/sinatra_modular/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +0 -13
  188. data/spec/sinatra_modular/filters.rb +0 -27
  189. data/spec/sinatra_modular/modular.rb +0 -157
  190. data/spec/sinatra_modular/myapp.rb +0 -133
  191. data/spec/sinatra_modular/sorcery_mailer.rb +0 -25
  192. data/spec/sinatra_modular/spec_modular/controller_activity_logging_spec.rb +0 -85
  193. data/spec/sinatra_modular/spec_modular/controller_brute_force_protection_spec.rb +0 -70
  194. data/spec/sinatra_modular/spec_modular/controller_http_basic_auth_spec.rb +0 -53
  195. data/spec/sinatra_modular/spec_modular/controller_oauth2_spec.rb +0 -99
  196. data/spec/sinatra_modular/spec_modular/controller_oauth_spec.rb +0 -100
  197. data/spec/sinatra_modular/spec_modular/controller_remember_me_spec.rb +0 -64
  198. data/spec/sinatra_modular/spec_modular/controller_session_timeout_spec.rb +0 -57
  199. data/spec/sinatra_modular/spec_modular/controller_spec.rb +0 -116
  200. data/spec/sinatra_modular/spec_modular/spec.opts +0 -2
  201. data/spec/sinatra_modular/spec_modular/spec_helper.rb +0 -51
  202. data/spec/sinatra_modular/user.rb +0 -6
  203. data/spec/sinatra_modular/views/test_login.erb +0 -4
  204. /data/spec/{sinatra → rails3_mongo_mapper/app/mailers}/sorcery_mailer.rb +0 -0
  205. /data/spec/{sinatra → rails3_mongo_mapper}/spec/spec.opts +0 -0
@@ -20,7 +20,13 @@ module Sorcery
20
20
  :activation_token_expiration_period, # how many seconds before the activation code
21
21
  # expires. nil for never expires.
22
22
 
23
- :user_activation_mailer, # your mailer class. Required.
23
+ :user_activation_mailer, # your mailer class. Required when
24
+ # activation_mailer_disabled == false.
25
+
26
+ :activation_mailer_disabled, # when true sorcery will not automatically
27
+ # email activation details and allow you to
28
+ # manually handle how and when email is sent
29
+
24
30
  :activation_needed_email_method_name, # activation needed email method on your
25
31
  # mailer class.
26
32
 
@@ -37,6 +43,7 @@ module Sorcery
37
43
  :@activation_token_expires_at_attribute_name => :activation_token_expires_at,
38
44
  :@activation_token_expiration_period => nil,
39
45
  :@user_activation_mailer => nil,
46
+ :@activation_mailer_disabled => false,
40
47
  :@activation_needed_email_method_name => :activation_needed_email,
41
48
  :@activation_success_email_method_name => :activation_success_email,
42
49
  :@prevent_non_active_users_to_login => true)
@@ -47,15 +54,17 @@ module Sorcery
47
54
  # don't setup activation if no password supplied - this user is created automatically
48
55
  before_create :setup_activation, :if => Proc.new { |user| user.send(sorcery_config.password_attribute_name).present? }
49
56
  # don't send activation needed email if no crypted password created - this user is external (OAuth etc.)
50
- after_create :send_activation_needed_email!, :if => Proc.new { |user| !user.external?}
57
+ after_create :send_activation_needed_email!, :if => Proc.new { |user| !user.external? }
51
58
  end
52
59
 
53
60
  base.sorcery_config.after_config << :validate_mailer_defined
54
61
  base.sorcery_config.after_config << :define_user_activation_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
62
+ if defined?(MongoMapper) and base.ancestors.include?(MongoMapper::Document)
63
+ base.sorcery_config.after_config << :define_user_activation_mongo_mapper_fields
64
+ end
55
65
  base.sorcery_config.before_authenticate << :prevent_non_active_login
56
66
 
57
67
  base.extend(ClassMethods)
58
- base.send(:include, TemporaryToken)
59
68
  base.send(:include, InstanceMethods)
60
69
 
61
70
 
@@ -72,17 +81,26 @@ module Sorcery
72
81
 
73
82
  protected
74
83
 
75
- # This submodule requires the developer to define his own mailer class to be used by it.
84
+ # This submodule requires the developer to define his own mailer class to be used by it
85
+ # when activation_mailer_disabled is false
76
86
  def validate_mailer_defined
77
87
  msg = "To use user_activation submodule, you must define a mailer (config.user_activation_mailer = YourMailerClass)."
78
- raise ArgumentError, msg if @sorcery_config.user_activation_mailer == nil
88
+ raise ArgumentError, msg if @sorcery_config.user_activation_mailer == nil and @sorcery_config.activation_mailer_disabled == false
79
89
  end
80
90
 
81
91
  def define_user_activation_mongoid_fields
82
92
  self.class_eval do
83
93
  field sorcery_config.activation_state_attribute_name, :type => String
84
94
  field sorcery_config.activation_token_attribute_name, :type => String
85
- field sorcery_config.activation_token_expires_at_attribute_name, :type => DateTime
95
+ field sorcery_config.activation_token_expires_at_attribute_name, :type => Time
96
+ end
97
+ end
98
+
99
+ def define_user_activation_mongo_mapper_fields
100
+ self.class_eval do
101
+ key sorcery_config.activation_state_attribute_name, String
102
+ key sorcery_config.activation_token_attribute_name, String
103
+ key sorcery_config.activation_token_expires_at_attribute_name, Time
86
104
  end
87
105
  end
88
106
  end
@@ -101,19 +119,19 @@ module Sorcery
101
119
 
102
120
  def setup_activation
103
121
  config = sorcery_config
104
- generated_activation_token = generate_random_token
122
+ generated_activation_token = TemporaryToken.generate_random_token
105
123
  self.send(:"#{config.activation_token_attribute_name}=", generated_activation_token)
106
124
  self.send(:"#{config.activation_state_attribute_name}=", "pending")
107
- self.send(:"#{config.activation_token_expires_at_attribute_name}=", Time.now.utc + config.activation_token_expiration_period) if config.activation_token_expiration_period
125
+ self.send(:"#{config.activation_token_expires_at_attribute_name}=", Time.now.in_time_zone + config.activation_token_expiration_period) if config.activation_token_expiration_period
108
126
  end
109
127
 
110
128
  # called automatically after user initial creation.
111
129
  def send_activation_needed_email!
112
- generic_send_email(:activation_needed_email_method_name, :user_activation_mailer) unless sorcery_config.activation_needed_email_method_name.nil?
130
+ generic_send_email(:activation_needed_email_method_name, :user_activation_mailer) unless sorcery_config.activation_needed_email_method_name.nil? or sorcery_config.activation_mailer_disabled == true
113
131
  end
114
132
 
115
133
  def send_activation_success_email!
116
- generic_send_email(:activation_success_email_method_name, :user_activation_mailer) unless sorcery_config.activation_success_email_method_name.nil?
134
+ generic_send_email(:activation_success_email_method_name, :user_activation_mailer) unless sorcery_config.activation_success_email_method_name.nil? or sorcery_config.activation_mailer_disabled == true
117
135
  end
118
136
 
119
137
  def prevent_non_active_login
@@ -1,3 +1,5 @@
1
+ require 'securerandom'
2
+
1
3
  module Sorcery
2
4
  module Model
3
5
  # This module encapsulates the logic for temporary token.
@@ -8,12 +10,17 @@ module Sorcery
8
10
  base.extend(ClassMethods)
9
11
  end
10
12
 
13
+ # Random code, used for salt and temporary tokens.
14
+ def self.generate_random_token
15
+ SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
16
+ end
17
+
11
18
  module ClassMethods
12
19
  def load_from_token(token, token_attr_name, token_expiration_date_attr)
13
20
  return nil if token.blank?
14
21
  user = find_by_sorcery_token(token_attr_name,token)
15
22
  if !user.blank? && !user.send(token_expiration_date_attr).nil?
16
- return Time.now.utc < user.send(token_expiration_date_attr) ? user : nil
23
+ return Time.now.in_time_zone < user.send(token_expiration_date_attr) ? user : nil
17
24
  end
18
25
  user
19
26
  end
data/lib/sorcery/model.rb CHANGED
@@ -3,8 +3,8 @@ module Sorcery
3
3
  # It should be included into the ORM base class.
4
4
  # In the case of Rails this is usually ActiveRecord (actually, in that case, the plugin does this automatically).
5
5
  #
6
- # When included it defines a single method: 'activate_sorcery!' which when called adds the other capabilities
7
- # to the class.
6
+ # When included it defines a single method: 'authenticates_with_sorcery!'
7
+ # which when called adds the other capabilities to the class.
8
8
  # This method is also the place to configure the plugin in the Model layer.
9
9
  module Model
10
10
  def self.included(klass)
@@ -15,6 +15,7 @@ module Sorcery
15
15
  self.class_eval do
16
16
  extend ClassMethods # included here, before submodules, so they can be overriden by them.
17
17
  include InstanceMethods
18
+ include TemporaryToken
18
19
  end
19
20
 
20
21
  include_required_submodules!
@@ -23,6 +24,7 @@ module Sorcery
23
24
  ::Sorcery::Controller::Config.user_config.tap{|blk| blk.call(@sorcery_config) if blk}
24
25
 
25
26
  init_mongoid_support! if defined?(Mongoid) and self.ancestors.include?(Mongoid::Document)
27
+ init_mongo_mapper_support! if defined?(MongoMapper) and self.ancestors.include?(MongoMapper::Document)
26
28
 
27
29
  init_orm_hooks!
28
30
 
@@ -52,20 +54,38 @@ module Sorcery
52
54
  # using 1.8.x hash syntax to perserve compatibility.
53
55
  def init_mongoid_support!
54
56
  self.class_eval do
55
- field sorcery_config.username_attribute_name, :type => String
56
- field sorcery_config.email_attribute_name, :type => String unless sorcery_config.username_attribute_name == sorcery_config.email_attribute_name
57
+ sorcery_config.username_attribute_names.each do |username|
58
+ field username, :type => String
59
+ end
60
+ field sorcery_config.email_attribute_name, :type => String unless sorcery_config.username_attribute_names.include?(sorcery_config.email_attribute_name)
57
61
  field sorcery_config.crypted_password_attribute_name, :type => String
58
62
  field sorcery_config.salt_attribute_name, :type => String
59
63
  end
60
64
  end
61
65
 
66
+ # defines mongo_mapper fields on the model class,
67
+ def init_mongo_mapper_support!
68
+ self.class_eval do
69
+ sorcery_config.username_attribute_names.each do |username|
70
+ key username, String
71
+ end
72
+ key sorcery_config.email_attribute_name, String unless sorcery_config.username_attribute_names.include?(sorcery_config.email_attribute_name)
73
+ key sorcery_config.crypted_password_attribute_name, String
74
+ key sorcery_config.salt_attribute_name, String
75
+ end
76
+ end
77
+
62
78
  # add virtual password accessor and ORM callbacks.
63
79
  def init_orm_hooks!
64
80
  self.class_eval do
65
81
  attr_accessor @sorcery_config.password_attribute_name
66
82
  attr_protected @sorcery_config.crypted_password_attribute_name, @sorcery_config.salt_attribute_name
67
- before_save :encrypt_password, :if => Proc.new { |record| record.send(sorcery_config.password_attribute_name).present? }
68
- after_save :clear_virtual_password, :if => Proc.new { |record| record.send(sorcery_config.password_attribute_name).present? }
83
+ before_save :encrypt_password, :if => Proc.new { |record|
84
+ record.send(sorcery_config.password_attribute_name).present?
85
+ }
86
+ after_save :clear_virtual_password, :if => Proc.new { |record|
87
+ record.send(sorcery_config.password_attribute_name).present?
88
+ }
69
89
  end
70
90
  end
71
91
  end
@@ -84,7 +104,11 @@ module Sorcery
84
104
  # returns the user if success, nil otherwise.
85
105
  def authenticate(*credentials)
86
106
  raise ArgumentError, "at least 2 arguments required" if credentials.size < 2
107
+ credentials[0].downcase! if @sorcery_config.downcase_username_before_authenticating
87
108
  user = find_by_credentials(credentials)
109
+
110
+ set_encryption_attributes()
111
+
88
112
  _salt = user.send(@sorcery_config.salt_attribute_name) if user && !@sorcery_config.salt_attribute_name.nil? && !@sorcery_config.encryption_provider.nil?
89
113
  user if user && @sorcery_config.before_authenticate.all? {|c| user.send(c)} && credentials_match?(user.send(@sorcery_config.crypted_password_attribute_name),credentials[1],_salt)
90
114
  end
@@ -93,14 +117,19 @@ module Sorcery
93
117
  def encrypt(*tokens)
94
118
  return tokens.first if @sorcery_config.encryption_provider.nil?
95
119
 
96
- @sorcery_config.encryption_provider.stretches = @sorcery_config.stretches if @sorcery_config.encryption_provider.respond_to?(:stretches) && @sorcery_config.stretches
97
- @sorcery_config.encryption_provider.join_token = @sorcery_config.salt_join_token if @sorcery_config.encryption_provider.respond_to?(:join_token) && @sorcery_config.salt_join_token
98
- CryptoProviders::AES256.key = @sorcery_config.encryption_key if @sorcery_config.encryption_algorithm == :aes256
120
+ set_encryption_attributes()
121
+
122
+ CryptoProviders::AES256.key = @sorcery_config.encryption_key
99
123
  @sorcery_config.encryption_provider.encrypt(*tokens)
100
124
  end
101
125
 
102
126
  protected
103
-
127
+
128
+ def set_encryption_attributes()
129
+ @sorcery_config.encryption_provider.stretches = @sorcery_config.stretches if @sorcery_config.encryption_provider.respond_to?(:stretches) && @sorcery_config.stretches
130
+ @sorcery_config.encryption_provider.join_token = @sorcery_config.salt_join_token if @sorcery_config.encryption_provider.respond_to?(:join_token) && @sorcery_config.salt_join_token
131
+ end
132
+
104
133
  # Calls the configured encryption provider to compare the supplied password with the encrypted one.
105
134
  def credentials_match?(crypted, *tokens)
106
135
  return crypted == tokens.join if @sorcery_config.encryption_provider.nil?
@@ -141,7 +170,7 @@ module Sorcery
141
170
  # encrypts password with salt and saves it.
142
171
  def encrypt_password
143
172
  config = sorcery_config
144
- self.send(:"#{config.salt_attribute_name}=", new_salt = generate_random_token) if !config.salt_attribute_name.nil?
173
+ self.send(:"#{config.salt_attribute_name}=", new_salt = TemporaryToken.generate_random_token) if !config.salt_attribute_name.nil?
145
174
  self.send(:"#{config.crypted_password_attribute_name}=", self.class.encrypt(self.send(config.password_attribute_name),new_salt))
146
175
  end
147
176
 
@@ -159,11 +188,6 @@ module Sorcery
159
188
  mail.deliver
160
189
  end
161
190
  end
162
-
163
- # Random code, used for salt and temporary tokens.
164
- def generate_random_token
165
- Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
166
- end
167
191
  end
168
192
 
169
193
  # Each class which calls 'activate_sorcery!' receives an instance of this class.
@@ -171,13 +195,16 @@ module Sorcery
171
195
  # options will be configured from a single place.
172
196
  class Config
173
197
 
174
- attr_accessor :username_attribute_name, # change default username attribute, for example, to use :email
198
+ attr_accessor :username_attribute_names, # change default username attribute, for example, to use :email
175
199
  # as the login.
176
200
 
177
201
  :password_attribute_name, # change *virtual* password attribute, the one which is used
178
202
  # until an encrypted one is generated.
179
203
 
180
204
  :email_attribute_name, # change default email attribute.
205
+
206
+ :downcase_username_before_authenticating, # downcase the username before trying to authenticate, default is false
207
+
181
208
  :crypted_password_attribute_name, # change default crypted_password attribute.
182
209
  :salt_join_token, # what pattern to use to join the password with the salt
183
210
  :salt_attribute_name, # change default salt attribute.
@@ -203,8 +230,9 @@ module Sorcery
203
230
  def initialize
204
231
  @defaults = {
205
232
  :@submodules => [],
206
- :@username_attribute_name => :username,
233
+ :@username_attribute_names => [:username],
207
234
  :@password_attribute_name => :password,
235
+ :@downcase_username_before_authenticating => false,
208
236
  :@email_attribute_name => :email,
209
237
  :@crypted_password_attribute_name => :crypted_password,
210
238
  :@encryption_algorithm => :bcrypt,
@@ -228,6 +256,10 @@ module Sorcery
228
256
  end
229
257
  end
230
258
 
259
+ def username_attribute_names=(fields)
260
+ @username_attribute_names = fields.kind_of?(Array) ? fields : [fields]
261
+ end
262
+
231
263
  def custom_encryption_provider=(provider)
232
264
  @custom_encryption_provider = @encryption_provider = provider
233
265
  end
@@ -249,4 +281,4 @@ module Sorcery
249
281
  end
250
282
 
251
283
  end
252
- end
284
+ end
@@ -12,7 +12,7 @@ module Sorcery
12
12
 
13
13
  def sorcery_reload!(submodules = [], options = {})
14
14
  reload_user_class
15
-
15
+
16
16
  # return to no-module configuration
17
17
  ::Sorcery::Controller::Config.init!
18
18
  ::Sorcery::Controller::Config.reset!
@@ -4,8 +4,8 @@ module Sorcery
4
4
  # logins a user and calls all callbacks
5
5
  def login_user(user = nil)
6
6
  user ||= @user
7
- @controller.send(:login_user,user)
8
- @controller.send(:after_login!,user,[user.send(user.sorcery_config.username_attribute_name),'secret'])
7
+ @controller.send(:auto_login,user)
8
+ @controller.send(:after_login!,user,[user.send(user.sorcery_config.username_attribute_names.first),'secret'])
9
9
  end
10
10
 
11
11
  def logout_user
data/lib/sorcery.rb CHANGED
@@ -5,6 +5,7 @@ module Sorcery
5
5
  module Adapters
6
6
  autoload :ActiveRecord, 'sorcery/model/adapters/active_record'
7
7
  autoload :Mongoid, 'sorcery/model/adapters/mongoid'
8
+ autoload :MongoMapper, 'sorcery/model/adapters/mongo_mapper'
8
9
  end
9
10
  module Submodules
10
11
  autoload :UserActivation, 'sorcery/model/submodules/user_activation'
@@ -32,12 +33,12 @@ module Sorcery
32
33
  module Providers
33
34
  autoload :Twitter, 'sorcery/controller/submodules/external/providers/twitter'
34
35
  autoload :Facebook, 'sorcery/controller/submodules/external/providers/facebook'
36
+ autoload :Github, 'sorcery/controller/submodules/external/providers/github'
37
+ autoload :Google, 'sorcery/controller/submodules/external/providers/google'
38
+ autoload :Liveid, 'sorcery/controller/submodules/external/providers/liveid'
35
39
  end
36
40
  end
37
41
  end
38
- module Adapters
39
- autoload :Sinatra, 'sorcery/controller/adapters/sinatra'
40
- end
41
42
  end
42
43
  module CryptoProviders
43
44
  autoload :Common, 'sorcery/crypto_providers/common'
@@ -51,12 +52,9 @@ module Sorcery
51
52
  autoload :TestHelpers, 'sorcery/test_helpers'
52
53
  module TestHelpers
53
54
  autoload :Rails, 'sorcery/test_helpers/rails'
54
- autoload :Sinatra, 'sorcery/test_helpers/sinatra'
55
55
  autoload :Internal, 'sorcery/test_helpers/internal'
56
56
  module Internal
57
57
  autoload :Rails, 'sorcery/test_helpers/internal/rails'
58
- autoload :Sinatra, 'sorcery/test_helpers/internal/sinatra'
59
- autoload :SinatraModular, 'sorcery/test_helpers/internal/sinatra_modular'
60
58
  end
61
59
 
62
60
  end
@@ -76,6 +74,9 @@ module Sorcery
76
74
  end
77
75
  end
78
76
 
77
+ if defined?(MongoMapper)
78
+ MongoMapper::Document.send(:plugin, Sorcery::Model::Adapters::MongoMapper)
79
+ end
80
+
79
81
  require 'sorcery/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
80
- require 'sorcery/sinatra' if defined?(Sinatra)
81
82
  end