sorcery 0.3.0 → 0.4.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.
Files changed (140) hide show
  1. data/Gemfile +3 -2
  2. data/Gemfile.lock +13 -11
  3. data/README.rdoc +99 -33
  4. data/Rakefile +4 -4
  5. data/VERSION +1 -1
  6. data/lib/generators/sorcery_migration/templates/core.rb +2 -2
  7. data/lib/generators/sorcery_migration/templates/{oauth.rb → external.rb} +1 -1
  8. data/lib/sorcery/controller/submodules/external/protocols/oauth1.rb +35 -0
  9. data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +26 -0
  10. data/lib/sorcery/controller/submodules/{oauth → external}/providers/facebook.rb +24 -6
  11. data/lib/sorcery/controller/submodules/{oauth → external}/providers/twitter.rb +31 -6
  12. data/lib/sorcery/controller/submodules/{oauth.rb → external.rb} +18 -30
  13. data/lib/sorcery/controller/submodules/http_basic_auth.rb +1 -1
  14. data/lib/sorcery/controller.rb +21 -21
  15. data/lib/sorcery/crypto_providers/bcrypt.rb +1 -1
  16. data/lib/sorcery/crypto_providers/common.rb +35 -0
  17. data/lib/sorcery/crypto_providers/md5.rb +3 -23
  18. data/lib/sorcery/crypto_providers/sha1.rb +4 -16
  19. data/lib/sorcery/crypto_providers/sha256.rb +3 -23
  20. data/lib/sorcery/crypto_providers/sha512.rb +3 -23
  21. data/lib/sorcery/engine.rb +4 -0
  22. data/lib/sorcery/initializers/initializer.rb +86 -0
  23. data/lib/sorcery/model/submodules/{oauth.rb → external.rb} +3 -3
  24. data/lib/sorcery/model.rb +13 -8
  25. data/lib/sorcery/railties/tasks.rake +10 -0
  26. data/lib/sorcery/sinatra.rb +0 -9
  27. data/lib/sorcery/test_helpers/rails.rb +6 -9
  28. data/lib/sorcery/test_helpers/sinatra.rb +6 -9
  29. data/lib/sorcery/test_helpers.rb +12 -0
  30. data/lib/sorcery.rb +10 -7
  31. data/sorcery.gemspec +146 -153
  32. data/spec/Gemfile +2 -2
  33. data/spec/Gemfile.lock +10 -10
  34. data/spec/Rakefile +1 -0
  35. data/spec/rails3/.rspec +1 -1
  36. data/spec/rails3/{app_root/Gemfile → Gemfile} +4 -4
  37. data/spec/rails3/{app_root/Gemfile.lock → Gemfile.lock} +20 -20
  38. data/spec/rails3/{app_root/Rakefile → Rakefile} +1 -0
  39. data/spec/rails3/{app_root/app → app}/controllers/application_controller.rb +11 -11
  40. data/spec/rails3/config/database.yml +27 -0
  41. data/spec/rails3/{app_root/spec → spec}/controller_brute_force_protection_spec.rb +3 -2
  42. data/spec/rails3/{app_root/spec → spec}/controller_oauth2_spec.rb +23 -22
  43. data/spec/rails3/{app_root/spec → spec}/controller_oauth_spec.rb +17 -17
  44. data/spec/rails3/{app_root/spec → spec}/controller_session_timeout_spec.rb +8 -4
  45. data/spec/rails3/spec/spec.opts +2 -0
  46. data/spec/rails3/spec/spec_helper.rb +70 -0
  47. data/spec/rails3/{app_root/spec → spec}/user_activation_spec.rb +5 -1
  48. data/spec/{sinatra → rails3}/spec/user_oauth_spec.rb +7 -7
  49. data/spec/rails3/{app_root/spec → spec}/user_reset_password_spec.rb +7 -3
  50. data/spec/rails3/{app_root/spec → spec}/user_spec.rb +5 -11
  51. data/spec/sinatra/Gemfile +3 -3
  52. data/spec/sinatra/Gemfile.lock +17 -17
  53. data/spec/sinatra/Rakefile +1 -0
  54. data/spec/sinatra/myapp.rb +11 -11
  55. data/spec/sinatra/spec/controller_brute_force_protection_spec.rb +3 -2
  56. data/spec/sinatra/spec/controller_oauth2_spec.rb +23 -22
  57. data/spec/sinatra/spec/controller_oauth_spec.rb +17 -17
  58. data/spec/sinatra/spec/controller_session_timeout_spec.rb +8 -4
  59. data/spec/sinatra/spec/spec.opts +2 -4
  60. data/spec/sinatra/spec/spec_helper.rb +2 -1
  61. data/spec/sorcery_crypto_providers_spec.rb +5 -4
  62. data/spec/spec.opts +2 -0
  63. data/spec/spec_helper.rb +3 -4
  64. metadata +157 -156
  65. data/lib/sorcery/controller/submodules/oauth/oauth1.rb +0 -33
  66. data/lib/sorcery/controller/submodules/oauth/oauth2.rb +0 -24
  67. data/spec/rails3/app_root/.rspec +0 -1
  68. data/spec/rails3/app_root/config/database.yml +0 -27
  69. data/spec/rails3/app_root/spec/spec_helper.rb +0 -62
  70. data/spec/rails3/app_root/spec/user_oauth_spec.rb +0 -39
  71. data/spec/sinatra/spec/user_activation_spec.rb +0 -188
  72. data/spec/sinatra/spec/user_activity_logging_spec.rb +0 -36
  73. data/spec/sinatra/spec/user_brute_force_protection_spec.rb +0 -76
  74. data/spec/sinatra/spec/user_remember_me_spec.rb +0 -66
  75. data/spec/sinatra/spec/user_reset_password_spec.rb +0 -178
  76. data/spec/sinatra/spec/user_spec.rb +0 -317
  77. /data/spec/rails3/{app_root/.gitignore → .gitignore} +0 -0
  78. /data/spec/rails3/{app_root/README → README} +0 -0
  79. /data/spec/rails3/{app_root/Rakefile.unused → Rakefile.unused} +0 -0
  80. /data/spec/rails3/{app_root/app → app}/helpers/application_helper.rb +0 -0
  81. /data/spec/rails3/{app_root/app → app}/mailers/sorcery_mailer.rb +0 -0
  82. /data/spec/rails3/{app_root/app → app}/models/authentication.rb +0 -0
  83. /data/spec/rails3/{app_root/app → app}/models/user.rb +0 -0
  84. /data/spec/rails3/{app_root/app → app}/views/layouts/application.html.erb +0 -0
  85. /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_email.html.erb +0 -0
  86. /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_email.text.erb +0 -0
  87. /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_success_email.html.erb +0 -0
  88. /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_success_email.text.erb +0 -0
  89. /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/reset_password_email.html.erb +0 -0
  90. /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/reset_password_email.text.erb +0 -0
  91. /data/spec/rails3/{app_root/config → config}/application.rb +0 -0
  92. /data/spec/rails3/{app_root/config → config}/boot.rb +0 -0
  93. /data/spec/rails3/{app_root/config → config}/environment.rb +0 -0
  94. /data/spec/rails3/{app_root/config → config}/environments/development.rb +0 -0
  95. /data/spec/rails3/{app_root/config → config}/environments/in_memory.rb +0 -0
  96. /data/spec/rails3/{app_root/config → config}/environments/production.rb +0 -0
  97. /data/spec/rails3/{app_root/config → config}/environments/test.rb +0 -0
  98. /data/spec/rails3/{app_root/config → config}/initializers/backtrace_silencers.rb +0 -0
  99. /data/spec/rails3/{app_root/config → config}/initializers/inflections.rb +0 -0
  100. /data/spec/rails3/{app_root/config → config}/initializers/mime_types.rb +0 -0
  101. /data/spec/rails3/{app_root/config → config}/initializers/secret_token.rb +0 -0
  102. /data/spec/rails3/{app_root/config → config}/initializers/session_store.rb +0 -0
  103. /data/spec/rails3/{app_root/config → config}/locales/en.yml +0 -0
  104. /data/spec/rails3/{app_root/config → config}/routes.rb +0 -0
  105. /data/spec/rails3/{app_root/config.ru → config.ru} +0 -0
  106. /data/spec/rails3/{app_root/db → db}/migrate/activation/20101224223622_add_activation_to_users.rb +0 -0
  107. /data/spec/rails3/{app_root/db → db}/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +0 -0
  108. /data/spec/rails3/{app_root/db → db}/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +0 -0
  109. /data/spec/rails3/{app_root/db → db}/migrate/core/20101224223620_create_users.rb +0 -0
  110. /data/spec/rails3/{app_root/db/migrate/oauth → db/migrate/external}/20101224223628_create_authentications.rb +0 -0
  111. /data/spec/rails3/{app_root/db → db}/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +0 -0
  112. /data/spec/rails3/{app_root/db → db}/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +0 -0
  113. /data/spec/rails3/{app_root/db → db}/schema.rb +0 -0
  114. /data/spec/rails3/{app_root/db → db}/seeds.rb +0 -0
  115. /data/spec/rails3/{app_root/lib → lib}/tasks/.gitkeep +0 -0
  116. /data/spec/rails3/{app_root/public → public}/404.html +0 -0
  117. /data/spec/rails3/{app_root/public → public}/422.html +0 -0
  118. /data/spec/rails3/{app_root/public → public}/500.html +0 -0
  119. /data/spec/rails3/{app_root/public → public}/favicon.ico +0 -0
  120. /data/spec/rails3/{app_root/public → public}/images/rails.png +0 -0
  121. /data/spec/rails3/{app_root/public → public}/index.html +0 -0
  122. /data/spec/rails3/{app_root/public → public}/javascripts/application.js +0 -0
  123. /data/spec/rails3/{app_root/public → public}/javascripts/controls.js +0 -0
  124. /data/spec/rails3/{app_root/public → public}/javascripts/dragdrop.js +0 -0
  125. /data/spec/rails3/{app_root/public → public}/javascripts/effects.js +0 -0
  126. /data/spec/rails3/{app_root/public → public}/javascripts/prototype.js +0 -0
  127. /data/spec/rails3/{app_root/public → public}/javascripts/rails.js +0 -0
  128. /data/spec/rails3/{app_root/public → public}/robots.txt +0 -0
  129. /data/spec/rails3/{app_root/public → public}/stylesheets/.gitkeep +0 -0
  130. /data/spec/rails3/{app_root/script → script}/rails +0 -0
  131. /data/spec/rails3/{app_root/spec → spec}/controller_activity_logging_spec.rb +0 -0
  132. /data/spec/rails3/{app_root/spec → spec}/controller_http_basic_auth_spec.rb +0 -0
  133. /data/spec/rails3/{app_root/spec → spec}/controller_remember_me_spec.rb +0 -0
  134. /data/spec/rails3/{app_root/spec → spec}/controller_spec.rb +0 -0
  135. /data/spec/rails3/{app_root/spec → spec}/spec_helper.orig.rb +0 -0
  136. /data/spec/rails3/{app_root/spec → spec}/user_activity_logging_spec.rb +0 -0
  137. /data/spec/rails3/{app_root/spec → spec}/user_brute_force_protection_spec.rb +0 -0
  138. /data/spec/rails3/{app_root/spec → spec}/user_remember_me_spec.rb +0 -0
  139. /data/spec/rails3/{app_root/vendor → vendor}/plugins/.gitkeep +0 -0
  140. /data/spec/sinatra/db/migrate/{oauth → external}/20101224223628_create_authentications.rb +0 -0
@@ -2,28 +2,17 @@ module Sorcery
2
2
  module Controller
3
3
  def self.included(klass)
4
4
  klass.class_eval do
5
- extend ClassMethods
6
5
  include InstanceMethods
7
6
  Config.submodules.each do |mod|
8
- begin # FIXME: is this protection needed?
7
+ begin
9
8
  include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
10
9
  rescue NameError
11
10
  # don't stop on a missing submodule.
12
11
  end
13
12
  end
14
- Config.update!
15
- end
16
- end
17
-
18
- module ClassMethods
19
- def activate_sorcery!(&block)
20
- yield Config if block_given?
21
- after_config!
22
- end
23
-
24
- def after_config!
25
- Config.after_config.each {|c| send(c)}
26
13
  end
14
+ Config.update!
15
+ Config.configure!
27
16
  end
28
17
 
29
18
  module InstanceMethods
@@ -73,12 +62,14 @@ module Sorcery
73
62
  @current_user ||= login_from_session || login_from_other_sources unless @current_user == false
74
63
  end
75
64
 
76
- def return_or_redirect_to(url, flash_hash = {})
65
+ # used when a user tries to access a page while logged out, is asked to login, and we want to return him back to the page he originally wanted.
66
+ def redirect_back_or_to(url, flash_hash = {})
77
67
  redirect_to(session[:return_to_url] || url, :flash => flash_hash)
78
68
  end
79
69
 
80
70
  # The default action for denying non-authenticated users.
81
- # You can override this method in your controllers.
71
+ # You can override this method in your controllers,
72
+ # or provide a different method in the configuration.
82
73
  def not_authenticated
83
74
  redirect_to root_path
84
75
  end
@@ -124,7 +115,7 @@ module Sorcery
124
115
  class << self
125
116
  attr_accessor :submodules,
126
117
 
127
- :user_class, # what class to use as the user class. Set automatically when you call activate_sorcery! in the User class.
118
+ :user_class, # what class to use as the user class. Set automatically when you call authenticates_with_sorcery! in the User class.
128
119
 
129
120
  :not_authenticated_action, # what controller action to call for non-authenticated users.
130
121
 
@@ -135,9 +126,7 @@ module Sorcery
135
126
  :after_login,
136
127
  :after_failed_login,
137
128
  :before_logout,
138
- :after_logout,
139
- :after_config
140
-
129
+ :after_logout
141
130
 
142
131
  def init!
143
132
  @defaults = {
@@ -149,7 +138,6 @@ module Sorcery
149
138
  :@after_failed_login => [],
150
139
  :@before_logout => [],
151
140
  :@after_logout => [],
152
- :@after_config => [],
153
141
  :@save_return_to_url => true
154
142
  }
155
143
  end
@@ -166,6 +154,18 @@ module Sorcery
166
154
  instance_variable_set(k,v) if !instance_variable_defined?(k)
167
155
  end
168
156
  end
157
+
158
+ def user_config(&blk)
159
+ block_given? ? @user_config = blk : @user_config
160
+ end
161
+
162
+ def configure(&blk)
163
+ @configure_blk = blk
164
+ end
165
+
166
+ def configure!
167
+ @configure_blk.call(self) if @configure_blk
168
+ end
169
169
  end
170
170
  init!
171
171
  reset!
@@ -42,7 +42,7 @@ module Sorcery
42
42
  # This is the :cost option for the BCrpyt library. The higher the cost the more secure it is and the longer is take the generate a hash. By default this is 10.
43
43
  # Set this to whatever you want, play around with it to get that perfect balance between security and performance.
44
44
  def cost
45
- @cost ||= 1
45
+ @cost ||= 10
46
46
  end
47
47
  attr_writer :cost
48
48
  alias :stretches= :cost=
@@ -0,0 +1,35 @@
1
+ module Sorcery
2
+ module CryptoProviders
3
+ module Common
4
+ def self.included(base)
5
+ base.class_eval do
6
+ class << self
7
+ attr_accessor :join_token
8
+
9
+ # The number of times to loop through the encryption.
10
+ def stretches
11
+ @stretches ||= 1
12
+ end
13
+ attr_writer :stretches
14
+
15
+ def encrypt(*tokens)
16
+ digest = tokens.flatten.join(join_token)
17
+ stretches.times { digest = secure_digest(digest) }
18
+ digest
19
+ end
20
+
21
+ # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
22
+ def matches?(crypted, *tokens)
23
+ encrypt(*tokens) == crypted
24
+ end
25
+
26
+ def reset!
27
+ @stretches = 1
28
+ @join_token = nil
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -8,30 +8,10 @@ module Sorcery
8
8
  #
9
9
  # Please use any other provider offered by Sorcery.
10
10
  class MD5
11
+ include Common
11
12
  class << self
12
- attr_accessor :join_token
13
-
14
- # The number of times to loop through the encryption.
15
- def stretches
16
- @stretches ||= 1
17
- end
18
- attr_writer :stretches
19
-
20
- # Turns your raw password into a MD5 hash.
21
- def encrypt(*tokens)
22
- digest = tokens.flatten.join(join_token)
23
- stretches.times { digest = Digest::MD5.hexdigest(digest) }
24
- digest
25
- end
26
-
27
- # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
28
- def matches?(crypted, *tokens)
29
- encrypt(*tokens) == crypted
30
- end
31
-
32
- def reset!
33
- @stretches = 1
34
- @join_token = nil
13
+ def secure_digest(digest)
14
+ Digest::MD5.hexdigest(digest)
35
15
  end
36
16
  end
37
17
  end
@@ -5,34 +5,22 @@ module Sorcery
5
5
  # This class was made for the users transitioning from restful_authentication. I highly discourage using this
6
6
  # crypto provider as it inferior to your other options. Please use any other provider offered by Sorcery.
7
7
  class SHA1
8
+ include Common
8
9
  class << self
9
10
  def join_token
10
11
  @join_token ||= "--"
11
12
  end
12
- attr_writer :join_token
13
-
14
- # The number of times to loop through the encryption. This is ten because that is what restful_authentication defaults to.
15
- def stretches
16
- @stretches ||= 10
17
- end
18
- attr_writer :stretches
19
13
 
20
14
  # Turns your raw password into a Sha1 hash.
21
15
  def encrypt(*tokens)
22
16
  tokens = tokens.flatten
23
17
  digest = tokens.shift
24
- stretches.times { digest = Digest::SHA1.hexdigest([digest, *tokens].join(join_token)) }
18
+ stretches.times { digest = secure_digest([digest, *tokens].join(join_token)) }
25
19
  digest
26
20
  end
27
21
 
28
- # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
29
- def matches?(crypted, *tokens)
30
- encrypt(*tokens) == crypted
31
- end
32
-
33
- def reset!
34
- @stretches = 10
35
- @join_token = nil
22
+ def secure_digest(digest)
23
+ Digest::SHA1.hexdigest(digest)
36
24
  end
37
25
  end
38
26
  end
@@ -24,30 +24,10 @@ module Sorcery
24
24
  #
25
25
  # Uses the Sha256 hash algorithm to encrypt passwords.
26
26
  class SHA256
27
+ include Common
27
28
  class << self
28
- attr_accessor :join_token
29
-
30
- # The number of times to loop through the encryption.
31
- def stretches
32
- @stretches ||= 20
33
- end
34
- attr_writer :stretches
35
-
36
- # Turns your raw password into a Sha256 hash.
37
- def encrypt(*tokens)
38
- digest = tokens.flatten.join(join_token)
39
- stretches.times { digest = Digest::SHA256.hexdigest(digest) }
40
- digest
41
- end
42
-
43
- # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
44
- def matches?(crypted, *tokens)
45
- encrypt(*tokens) == crypted
46
- end
47
-
48
- def reset!
49
- @stretches = 20
50
- @join_token = nil
29
+ def secure_digest(digest)
30
+ Digest::SHA256.hexdigest(digest)
51
31
  end
52
32
  end
53
33
  end
@@ -24,30 +24,10 @@ module Sorcery
24
24
  #
25
25
  # Uses the Sha512 hash algorithm to encrypt passwords.
26
26
  class SHA512
27
+ include Common
27
28
  class << self
28
- attr_accessor :join_token
29
-
30
- # The number of times to loop through the encryption.
31
- def stretches
32
- @stretches ||= 20
33
- end
34
- attr_writer :stretches
35
-
36
- # Turns your raw password into a Sha512 hash.
37
- def encrypt(*tokens)
38
- digest = tokens.flatten.join(join_token)
39
- stretches.times { digest = Digest::SHA512.hexdigest(digest) }
40
- digest
41
- end
42
-
43
- # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
44
- def matches?(crypted, *tokens)
45
- encrypt(*tokens) == crypted
46
- end
47
-
48
- def reset!
49
- @stretches = 20
50
- @join_token = nil
29
+ def secure_digest(digest)
30
+ Digest::SHA512.hexdigest(digest)
51
31
  end
52
32
  end
53
33
  end
@@ -23,5 +23,9 @@ module Sorcery
23
23
  end
24
24
  end
25
25
 
26
+ rake_tasks do
27
+ load "sorcery/railties/tasks.rake"
28
+ end
29
+
26
30
  end
27
31
  end
@@ -0,0 +1,86 @@
1
+ # The first thing you need to configure is which modules you need in your app.
2
+ # The default is nothing which will include only core features (password encryption, login/logout).
3
+ # Available submodules are: :user_activation, :http_basic_auth, :remember_me, :reset_password, :session_timeout, :brute_force_protection, :activity_logging, :external
4
+ Collaboration::Application.config.sorcery.submodules = []
5
+
6
+ # Here you can configure each submodule's features.
7
+ Collaboration::Application.config.sorcery.configure do |config|
8
+ # -- core --
9
+ # config.not_authenticated_action = :not_authenticated # what controller action to call for non-authenticated users. You can also override 'not_authenticated' instead.
10
+ # config.save_return_to_url = true # when a non logged in user tries to enter a page that requires login, save the URL he wanted to reach,
11
+ # and send him there after login, using 'redirect_back_or_to'.
12
+
13
+ # -- session timeout --
14
+ # config.session_timeout = 3600 # how long in seconds to keep the session alive.
15
+ # config.session_timeout_from_last_action = false # use the last action as the beginning of session timeout.
16
+
17
+ # -- http_basic_auth --
18
+ # config.controller_to_realm_map = {"application" => "Application"} # What realm to display for which controller name.
19
+ # For example {"My App" => "Application"}
20
+
21
+ # -- external --
22
+ # config.external_providers = [] # What providers are supported by this app, i.e. [:twitter, :facebook] .
23
+ #
24
+ # config.twitter.key = "eYVNBjBDi33aa9GkA3w"
25
+ # config.twitter.secret = "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8"
26
+ # config.twitter.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=twitter"
27
+ # config.twitter.user_info_mapping = {:email => "screen_name"}
28
+ #
29
+ # config.facebook.key = "34cebc81c08a521bc66e212f947d73ec"
30
+ # config.facebook.secret = "5b458d179f61d4f036ee66a497ffbcd0"
31
+ # config.facebook.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=facebook"
32
+ # config.facebook.user_info_mapping = {:email => "name"}
33
+
34
+ # --- user config ---
35
+ config.user_config do |user|
36
+ # -- core --
37
+ # user.username_attribute_name = # change default username attribute, for example, to use :email as the login.
38
+ # user.password_attribute_name = # change *virtual* password attribute, the one which is used until an encrypted one is generated.
39
+ # user.email_attribute_name = # change default email attribute.
40
+ # user.crypted_password_attribute_name = # change default crypted_password attribute.
41
+ # user.salt_join_token = # what pattern to use to join the password with the salt
42
+ # user.salt_attribute_name = # change default salt attribute.
43
+ # user.stretches = # how many times to apply encryption to the password.
44
+ # user.encryption_key = # encryption key used to encrypt reversible encryptions such as AES256.
45
+ # user.encryption_provider = # change default encryption_provider.
46
+ # user.custom_encryption_provider = # use an external encryption class.
47
+ # user.encryption_algorithm = # encryption algorithm name. See 'encryption_algorithm=' for available options.
48
+
49
+ # -- user_activation --
50
+ # user.activation_state_attribute_name = # the attribute name to hold activation state (active/pending).
51
+ # user.activation_token_attribute_name = # the attribute name to hold activation code (sent by email).
52
+ # user.activation_token_expires_at_attribute_name = # the attribute name to hold activation code expiration date.
53
+ # user.activation_token_expiration_period = # how many seconds before the activation code expires. nil for never expires.
54
+ # user.user_activation_mailer = # your mailer class. Required.
55
+ # user.activation_needed_email_method_name = # activation needed email method on your mailer class.
56
+ # user.activation_success_email_method_name = # activation success email method on your mailer class.
57
+ # user.prevent_non_active_users_to_login = # do you want to prevent or allow users that did not activate by email to login?
58
+
59
+ # -- reset_password --
60
+ # user.reset_password_token_attribute_name = # reset password code attribute name.
61
+ # user.reset_password_token_expires_at_attribute_name = # expires at attribute name.
62
+ # user.reset_password_email_sent_at_attribute_name = # when was email sent, used for hammering protection.
63
+ # user.reset_password_mailer = # mailer class. Needed.
64
+ # user.reset_password_email_method_name = # reset password email method on your mailer class.
65
+ # user.reset_password_expiration_period = # how many seconds before the reset request expires. nil for never expires.
66
+ # user.reset_password_time_between_emails = # hammering protection, how long to wait before allowing another email to be sent.
67
+
68
+ # -- brute_force_protection --
69
+ # user.failed_logins_count_attribute_name = # failed logins attribute name.
70
+ # user.lock_expires_at_attribute_name = # this field indicates whether user is banned and when it will be active again.
71
+ # user.consecutive_login_retries_amount_limit = # how many failed logins allowed.
72
+ # user.login_lock_time_period = # how long the user should be banned. in seconds. 0 for permanent.
73
+
74
+ # -- activity logging --
75
+ # user.last_login_at_attribute_name = # last login attribute name.
76
+ # user.last_logout_at_attribute_name = # last logout attribute name.
77
+ # user.last_activity_at_attribute_name = # last activity attribute name.
78
+ # user.activity_timeout = # how long since last activity is the user defined logged out?
79
+
80
+ # -- external --
81
+ # user.authentications_class = # class which holds the various external provider data for this user.
82
+ # user.authentications_user_id_attribute_name = # user's identifier in authentications class.
83
+ # user.provider_attribute_name = # provider's identifier in authentications class.
84
+ # user.provider_uid_attribute_name = # user's external unique identifier in authentications class.
85
+ end
86
+ end
@@ -1,9 +1,9 @@
1
1
  module Sorcery
2
2
  module Model
3
3
  module Submodules
4
- # This submodule helps you login users from OAuth providers such as Twitter.
4
+ # This submodule helps you login users from external providers such as Twitter.
5
5
  # This is the model part which handles finding the user using access tokens.
6
- # For the controller options see Sorcery::Controller::Oauth.
6
+ # For the controller options see Sorcery::Controller::External.
7
7
  #
8
8
  # Socery assumes (read: requires) you will create external users in the same table where you keep your regular users,
9
9
  # but that you will have a separate table for keeping their external authentication data,
@@ -11,7 +11,7 @@ module Sorcery
11
11
  #
12
12
  # External users will have a null crypted_password field, since we do not hold their password.
13
13
  # They will not be sent activation emails on creation.
14
- module Oauth
14
+ module External
15
15
  def self.included(base)
16
16
  base.sorcery_config.class_eval do
17
17
  attr_accessor :authentications_class,
data/lib/sorcery/model.rb CHANGED
@@ -9,11 +9,13 @@ module Sorcery
9
9
  def self.included(klass)
10
10
  klass.class_eval do
11
11
  class << self
12
- def activate_sorcery!
12
+ def authenticates_with_sorcery!
13
13
  @sorcery_config = Config.new
14
14
  self.class_eval do
15
15
  extend ClassMethods # included here, before submodules, so they can be overriden by them.
16
16
  include InstanceMethods
17
+
18
+ # set the user_class for the controller methods which call it
17
19
  ::Sorcery::Controller::Config.user_class = self
18
20
  @sorcery_config.submodules = ::Sorcery::Controller::Config.submodules
19
21
  @sorcery_config.submodules.each do |mod|
@@ -25,7 +27,7 @@ module Sorcery
25
27
  end
26
28
  end
27
29
 
28
- yield @sorcery_config if block_given?
30
+ ::Sorcery::Controller::Config.user_config.tap{|blk| blk.call(@sorcery_config) if blk}
29
31
 
30
32
  self.class_eval do
31
33
  attr_accessor @sorcery_config.password_attribute_name
@@ -56,12 +58,6 @@ module Sorcery
56
58
  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)
57
59
  end
58
60
 
59
- # Calls the configured encryption provider to compare the supplied password with the encrypted one.
60
- def credentials_match?(crypted, *tokens)
61
- return crypted == tokens.join if @sorcery_config.encryption_provider.nil?
62
- @sorcery_config.encryption_provider.matches?(crypted, *tokens)
63
- end
64
-
65
61
  # encrypt tokens using current encryption_provider.
66
62
  def encrypt(*tokens)
67
63
  return tokens.first if @sorcery_config.encryption_provider.nil?
@@ -71,6 +67,15 @@ module Sorcery
71
67
  CryptoProviders::AES256.key = @sorcery_config.encryption_key if @sorcery_config.encryption_algorithm == :aes256
72
68
  @sorcery_config.encryption_provider.encrypt(*tokens)
73
69
  end
70
+
71
+ protected
72
+
73
+ # Calls the configured encryption provider to compare the supplied password with the encrypted one.
74
+ def credentials_match?(crypted, *tokens)
75
+ return crypted == tokens.join if @sorcery_config.encryption_provider.nil?
76
+ @sorcery_config.encryption_provider.matches?(crypted, *tokens)
77
+ end
78
+
74
79
  end
75
80
 
76
81
  module InstanceMethods
@@ -0,0 +1,10 @@
1
+ require 'fileutils'
2
+
3
+ namespace :sorcery do
4
+ desc "Adds sorcery's initializer file"
5
+ task :bootstrap do
6
+ src = File.join(File.dirname(__FILE__), '..', 'initializers', 'initializer.rb')
7
+ target = File.join(Rails.root, "config", "initializers", "sorcery.rb")
8
+ FileUtils.cp(src, target)
9
+ end
10
+ end
@@ -2,13 +2,4 @@ ActiveRecord::Base.send(:include, Sorcery::Model) if defined?(ActiveRecord)
2
2
  if defined?(Sinatra::Base)
3
3
  Sinatra::Base.send(:include, Sorcery::Controller::Adapters::Sinatra)
4
4
  Sinatra::Base.send(:include, Sorcery::Controller)
5
- # Sorcery::Controller::Config.class_eval do
6
- # class << self
7
- # def submodules=(mods)
8
- # @submodules = mods
9
- # Sinatra::Base.send(:include, Sorcery::Controller::Adapters::Sinatra)
10
- # Sinatra::Base.send(:include, Sorcery::Controller)
11
- # end
12
- # end
13
- # end
14
5
  end
@@ -20,23 +20,20 @@ module Sorcery
20
20
  ::Sorcery::Controller::Config.user_class = nil
21
21
  ActionController::Base.send(:include,::Sorcery::Controller)
22
22
 
23
- User.activate_sorcery! do |config|
23
+ ::Sorcery::Controller::Config.user_config do |user|
24
24
  options.each do |property,value|
25
- config.send(:"#{property}=", value)
25
+ user.send(:"#{property}=", value)
26
26
  end
27
27
  end
28
+ User.authenticates_with_sorcery!
28
29
  end
29
30
 
30
31
  def sorcery_controller_property_set(property, value)
31
- ApplicationController.activate_sorcery! do |config|
32
- config.send(:"#{property}=", value)
33
- end
32
+ ::Sorcery::Controller::Config.send(:"#{property}=", value)
34
33
  end
35
34
 
36
- def sorcery_controller_oauth_property_set(provider, property, value)
37
- ApplicationController.activate_sorcery! do |config|
38
- config.send(provider).send(:"#{property}=", value)
39
- end
35
+ def sorcery_controller_external_property_set(provider, property, value)
36
+ ::Sorcery::Controller::Config.send(provider).send(:"#{property}=", value)
40
37
  end
41
38
 
42
39
  def login_user(user = nil)
@@ -108,23 +108,20 @@ module Sorcery
108
108
  ::Sinatra::Application.send(:include, Sorcery::Controller::Adapters::Sinatra)
109
109
  ::Sinatra::Application.send(:include, Sorcery::Controller)
110
110
 
111
- User.activate_sorcery! do |config|
111
+ ::Sorcery::Controller::Config.user_config do |user|
112
112
  options.each do |property,value|
113
- config.send(:"#{property}=", value)
113
+ user.send(:"#{property}=", value)
114
114
  end
115
115
  end
116
+ User.authenticates_with_sorcery!
116
117
  end
117
118
 
118
119
  def sorcery_controller_property_set(property, value)
119
- ::Sinatra::Application.activate_sorcery! do |config|
120
- config.send(:"#{property}=", value)
121
- end
120
+ ::Sorcery::Controller::Config.send(:"#{property}=", value)
122
121
  end
123
122
 
124
- def sorcery_controller_oauth_property_set(provider, property, value)
125
- ::Sinatra::Application.activate_sorcery! do |config|
126
- config.send(provider).send(:"#{property}=", value)
127
- end
123
+ def sorcery_controller_external_property_set(provider, property, value)
124
+ ::Sorcery::Controller::Config.send(provider).send(:"#{property}=", value)
128
125
  end
129
126
  end
130
127
  end
@@ -1,5 +1,17 @@
1
1
  module Sorcery
2
+ # This file will be included in the spec_helper file.
2
3
  module TestHelpers
4
+ def self.included(base)
5
+ # reducing default cost for specs speed
6
+ CryptoProviders::BCrypt.class_eval do
7
+ class << self
8
+ def cost
9
+ 1
10
+ end
11
+ end
12
+ end
13
+ end
14
+
3
15
  # a patch to fix a bug in testing that happens when you 'destroy' a session twice.
4
16
  # After the first destroy, the session is an ordinary hash, and then when destroy is called again there's an exception.
5
17
  class ::Hash
data/lib/sorcery.rb CHANGED
@@ -8,7 +8,7 @@ module Sorcery
8
8
  autoload :RememberMe, 'sorcery/model/submodules/remember_me'
9
9
  autoload :ActivityLogging, 'sorcery/model/submodules/activity_logging'
10
10
  autoload :BruteForceProtection, 'sorcery/model/submodules/brute_force_protection'
11
- autoload :Oauth, 'sorcery/model/submodules/oauth'
11
+ autoload :External, 'sorcery/model/submodules/external'
12
12
  end
13
13
  end
14
14
  autoload :Controller, 'sorcery/controller'
@@ -19,13 +19,15 @@ module Sorcery
19
19
  autoload :BruteForceProtection, 'sorcery/controller/submodules/brute_force_protection'
20
20
  autoload :HttpBasicAuth, 'sorcery/controller/submodules/http_basic_auth'
21
21
  autoload :ActivityLogging, 'sorcery/controller/submodules/activity_logging'
22
- autoload :Oauth, 'sorcery/controller/submodules/oauth'
23
- module Oauth
24
- autoload :Oauth1, 'sorcery/controller/submodules/oauth/oauth1'
25
- autoload :Oauth2, 'sorcery/controller/submodules/oauth/oauth2'
22
+ autoload :External, 'sorcery/controller/submodules/external'
23
+ module External
24
+ module Protocols
25
+ autoload :Oauth1, 'sorcery/controller/submodules/external/protocols/oauth1'
26
+ autoload :Oauth2, 'sorcery/controller/submodules/external/protocols/oauth2'
27
+ end
26
28
  module Providers
27
- autoload :Twitter, 'sorcery/controller/submodules/oauth/providers/twitter'
28
- autoload :Facebook, 'sorcery/controller/submodules/oauth/providers/facebook'
29
+ autoload :Twitter, 'sorcery/controller/submodules/external/providers/twitter'
30
+ autoload :Facebook, 'sorcery/controller/submodules/external/providers/facebook'
29
31
  end
30
32
  end
31
33
  end
@@ -34,6 +36,7 @@ module Sorcery
34
36
  end
35
37
  end
36
38
  module CryptoProviders
39
+ autoload :Common, 'sorcery/crypto_providers/common'
37
40
  autoload :AES256, 'sorcery/crypto_providers/aes256'
38
41
  autoload :BCrypt, 'sorcery/crypto_providers/bcrypt'
39
42
  autoload :MD5, 'sorcery/crypto_providers/md5'