sorcery 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sorcery might be problematic. Click here for more details.

Files changed (93) hide show
  1. data/Gemfile +5 -2
  2. data/Gemfile.lock +12 -0
  3. data/README.rdoc +12 -7
  4. data/VERSION +1 -1
  5. data/lib/sorcery/controller/submodules/brute_force_protection.rb +1 -1
  6. data/lib/sorcery/crypto_providers/common.rb +2 -2
  7. data/lib/sorcery/engine.rb +0 -4
  8. data/lib/sorcery/initializers/initializer.rb +1 -0
  9. data/lib/sorcery/model/adapters/active_record.rb +28 -0
  10. data/lib/sorcery/model/adapters/mongoid.rb +59 -0
  11. data/lib/sorcery/model/submodules/activity_logging.rb +12 -3
  12. data/lib/sorcery/model/submodules/brute_force_protection.rb +6 -1
  13. data/lib/sorcery/model/submodules/external.rb +1 -0
  14. data/lib/sorcery/model/submodules/remember_me.rb +15 -1
  15. data/lib/sorcery/model/submodules/reset_password.rb +10 -3
  16. data/lib/sorcery/model/submodules/user_activation.rb +11 -1
  17. data/lib/sorcery/model/temporary_token.rb +1 -1
  18. data/lib/sorcery/model.rb +15 -7
  19. data/lib/sorcery/sinatra.rb +0 -1
  20. data/lib/sorcery/test_helpers/internal/sinatra.rb +6 -54
  21. data/lib/sorcery/test_helpers/internal.rb +2 -1
  22. data/lib/sorcery/test_helpers/sinatra.rb +4 -1
  23. data/lib/sorcery.rb +22 -1
  24. data/sorcery.gemspec +107 -10
  25. data/spec/Gemfile.lock +1 -1
  26. data/spec/rails3/Gemfile.lock +5 -5
  27. data/spec/rails3/spec/user_reset_password_spec.rb +2 -2
  28. data/spec/rails3/spec/user_spec.rb +0 -1
  29. data/spec/rails3_mongoid/.gitignore +4 -0
  30. data/spec/rails3_mongoid/.rspec +1 -0
  31. data/spec/rails3_mongoid/Gemfile +14 -0
  32. data/spec/rails3_mongoid/Gemfile.lock +146 -0
  33. data/spec/rails3_mongoid/Rakefile +11 -0
  34. data/spec/rails3_mongoid/app/controllers/application_controller.rb +108 -0
  35. data/spec/rails3_mongoid/app/helpers/application_helper.rb +2 -0
  36. data/spec/rails3_mongoid/app/mailers/sorcery_mailer.rb +25 -0
  37. data/spec/rails3_mongoid/app/models/authentication.rb +7 -0
  38. data/spec/rails3_mongoid/app/models/user.rb +5 -0
  39. data/spec/rails3_mongoid/app/views/layouts/application.html.erb +14 -0
  40. data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_email.html.erb +17 -0
  41. data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_email.text.erb +9 -0
  42. data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
  43. data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
  44. data/spec/rails3_mongoid/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
  45. data/spec/rails3_mongoid/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
  46. data/spec/rails3_mongoid/config/application.rb +51 -0
  47. data/spec/rails3_mongoid/config/boot.rb +13 -0
  48. data/spec/rails3_mongoid/config/environment.rb +5 -0
  49. data/spec/rails3_mongoid/config/environments/development.rb +26 -0
  50. data/spec/rails3_mongoid/config/environments/in_memory.rb +0 -0
  51. data/spec/rails3_mongoid/config/environments/production.rb +49 -0
  52. data/spec/rails3_mongoid/config/environments/test.rb +35 -0
  53. data/spec/rails3_mongoid/config/initializers/backtrace_silencers.rb +7 -0
  54. data/spec/rails3_mongoid/config/initializers/inflections.rb +10 -0
  55. data/spec/rails3_mongoid/config/initializers/mime_types.rb +5 -0
  56. data/spec/rails3_mongoid/config/initializers/secret_token.rb +7 -0
  57. data/spec/rails3_mongoid/config/initializers/session_store.rb +8 -0
  58. data/spec/rails3_mongoid/config/locales/en.yml +5 -0
  59. data/spec/rails3_mongoid/config/mongoid.yml +7 -0
  60. data/spec/rails3_mongoid/config/routes.rb +59 -0
  61. data/spec/rails3_mongoid/config.ru +4 -0
  62. data/spec/rails3_mongoid/db/schema.rb +23 -0
  63. data/spec/rails3_mongoid/db/seeds.rb +7 -0
  64. data/spec/rails3_mongoid/lib/tasks/.gitkeep +0 -0
  65. data/spec/rails3_mongoid/public/404.html +26 -0
  66. data/spec/rails3_mongoid/public/422.html +26 -0
  67. data/spec/rails3_mongoid/public/500.html +26 -0
  68. data/spec/rails3_mongoid/public/favicon.ico +0 -0
  69. data/spec/rails3_mongoid/public/images/rails.png +0 -0
  70. data/spec/rails3_mongoid/public/javascripts/application.js +2 -0
  71. data/spec/rails3_mongoid/public/javascripts/controls.js +965 -0
  72. data/spec/rails3_mongoid/public/javascripts/dragdrop.js +974 -0
  73. data/spec/rails3_mongoid/public/javascripts/effects.js +1123 -0
  74. data/spec/rails3_mongoid/public/javascripts/prototype.js +6001 -0
  75. data/spec/rails3_mongoid/public/javascripts/rails.js +175 -0
  76. data/spec/rails3_mongoid/public/robots.txt +5 -0
  77. data/spec/rails3_mongoid/public/stylesheets/.gitkeep +0 -0
  78. data/spec/rails3_mongoid/script/rails +6 -0
  79. data/spec/rails3_mongoid/spec/spec.opts +2 -0
  80. data/spec/rails3_mongoid/spec/spec_helper.orig.rb +27 -0
  81. data/spec/rails3_mongoid/spec/spec_helper.rb +55 -0
  82. data/spec/rails3_mongoid/spec/user_activation_spec.rb +178 -0
  83. data/spec/rails3_mongoid/spec/user_activity_logging_spec.rb +31 -0
  84. data/spec/rails3_mongoid/spec/user_brute_force_protection_spec.rb +41 -0
  85. data/spec/rails3_mongoid/spec/user_oauth_spec.rb +34 -0
  86. data/spec/rails3_mongoid/spec/user_remember_me_spec.rb +51 -0
  87. data/spec/rails3_mongoid/spec/user_reset_password_spec.rb +174 -0
  88. data/spec/rails3_mongoid/spec/user_spec.rb +329 -0
  89. data/spec/rails3_mongoid/vendor/plugins/.gitkeep +0 -0
  90. data/spec/sinatra/Gemfile.lock +5 -5
  91. data/spec/sinatra/spec/spec_helper.rb +0 -1
  92. metadata +150 -37
  93. data/spec/untitled folder +0 -18
data/Gemfile CHANGED
@@ -2,13 +2,16 @@ source "http://rubygems.org"
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
- gem "rails", ">= 3.0.0"
6
- gem 'json', ">= 1.5.1"
7
5
  gem 'oauth', ">= 0.4.4"
8
6
  gem 'oauth2', ">= 0.1.1"
7
+
9
8
  # Add dependencies to develop your gem here.
10
9
  # Include everything needed to run rake, tests, features, etc.
11
10
  group :development do
11
+ gem "rails", ">= 3.0.0"
12
+ gem 'json', ">= 1.5.1"
13
+ gem "mongoid", "~> 2.0"
14
+ gem "bson_ext", "~> 1.3"
12
15
  gem "rspec", "~> 2.5.0"
13
16
  gem 'rspec-rails', "~> 2.5.0"
14
17
  gem 'ruby-debug19'
data/Gemfile.lock CHANGED
@@ -31,6 +31,8 @@ GEM
31
31
  addressable (2.2.4)
32
32
  archive-tar-minitar (0.5.2)
33
33
  arel (2.0.6)
34
+ bson (1.3.0)
35
+ bson_ext (1.3.0)
34
36
  builder (2.1.2)
35
37
  columnize (0.3.2)
36
38
  diff-lcs (1.1.2)
@@ -55,6 +57,13 @@ GEM
55
57
  mime-types (~> 1.16)
56
58
  treetop (~> 1.4.8)
57
59
  mime-types (1.16)
60
+ mongo (1.3.0)
61
+ bson (>= 1.3.0)
62
+ mongoid (2.0.1)
63
+ activemodel (~> 3.0)
64
+ mongo (~> 1.3)
65
+ tzinfo (~> 0.3.22)
66
+ will_paginate (~> 3.0.pre)
58
67
  multi_json (0.0.5)
59
68
  multipart-post (1.1.0)
60
69
  oauth (0.4.4)
@@ -113,15 +122,18 @@ GEM
113
122
  treetop (1.4.9)
114
123
  polyglot (>= 0.3.1)
115
124
  tzinfo (0.3.23)
125
+ will_paginate (3.0.pre2)
116
126
  yard (0.6.4)
117
127
 
118
128
  PLATFORMS
119
129
  ruby
120
130
 
121
131
  DEPENDENCIES
132
+ bson_ext (~> 1.3)
122
133
  bundler (~> 1.0.0)
123
134
  jeweler (~> 1.5.2)
124
135
  json (>= 1.5.1)
136
+ mongoid (~> 2.0)
125
137
  oauth (>= 0.4.4)
126
138
  oauth2 (>= 0.1.1)
127
139
  rails (>= 3.0.0)
data/README.rdoc CHANGED
@@ -1,5 +1,6 @@
1
1
  = sorcery
2
2
  Magical Authentication for Rails 3 and Sinatra.
3
+ Supports ActiveRecord and Mongoid.
3
4
 
4
5
  Inspired by restful_authentication, Authlogic and Devise.
5
6
  Crypto code taken almost unchanged from Authlogic.
@@ -15,7 +16,7 @@ It was built with a few goals in mind:
15
16
  * Less is more - less than 20 public methods to remember for the entire feature-set make the lib easy to 'get'.
16
17
  * No built-in or generated code - use the library's methods inside *your own* MVC structures, and don't fight to fix someone else's.
17
18
  * Magic yes, Voodoo no - the lib should be easy to hack for most developers.
18
- * Configuration over Confusion - Simple & short configuration as possible, not drowning in syntactic sugar.
19
+ * Configuration over Confusion - Centralized (1 file), Simple & short configuration as possible, not drowning in syntactic sugar.
19
20
  * Keep MVC cleanly separated - DB is for models, sessions are for controllers. Models stay unaware of sessions.
20
21
 
21
22
  Hopefully, I've achieved this. If not, let me know.
@@ -28,7 +29,7 @@ Example Rails 3 app using sorcery: https://github.com/NoamB/sorcery-example-app
28
29
 
29
30
  Example Sinatra app using sorcery: https://github.com/NoamB/sorcery-example-app-sinatra
30
31
 
31
- Documentation: http://rubydoc.info/gems/sorcery/0.4.2/frames
32
+ Documentation: http://rubydoc.info/gems/sorcery/0.5.0/frames
32
33
 
33
34
  Check out the tutorials in the github wiki!
34
35
 
@@ -66,7 +67,7 @@ Below is a summary of the library methods. Most method names are self explaining
66
67
  # reset password
67
68
  User.load_from_reset_password_token(token)
68
69
  @user.deliver_reset_password_instructions!
69
- @user.reset_password!(params)
70
+ @user.change_password!(new_password)
70
71
 
71
72
  # user activation
72
73
  User.load_from_activation_token(token)
@@ -193,19 +194,23 @@ External (see lib/sorcery/controller/submodules/external.rb):
193
194
  == Next Planned Features:
194
195
 
195
196
 
196
- I've got many plans which include (by priority):
197
+ I've got some thoughts which include (unordered):
198
+ * Passing a block to encrypt, allowing the developer to define his own mix of salting and encrypting
197
199
  * Forgot username, maybe as part of the reset_password module
198
200
  * Scoping logins (to a subdomain or another arbitrary field)
199
- * Mongoid support
201
+ * Allowing storing the salt and crypted password in the same DB field for extra security
200
202
  * Other reset password strategies (security questions?)
201
203
  * Other brute force protection strategies (captcha)
202
- * Have an idea? Let me know, and it might get into the gem!
204
+
205
+
206
+ Have an idea? Let me know, and it might get into the gem!
207
+
203
208
 
204
209
  Other stuff:
205
210
  * Improve specs speed
206
211
  * Provide an easy way to run specs after install
207
212
  * Improve documentation
208
- * Tty to reduce the number of library methods, and find better names to some
213
+ * Try to reduce the number of library methods, and find better names to some
209
214
 
210
215
 
211
216
  == Backward compatibility
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.2
1
+ 0.5.0
@@ -19,7 +19,7 @@ module Sorcery
19
19
  # Increments the failed logins counter on every failed login.
20
20
  # Runs as a hook after a failed login.
21
21
  def update_failed_logins_count!(credentials)
22
- user = Config.user_class.where("#{Config.user_class.sorcery_config.username_attribute_name} = ?", credentials[0]).first
22
+ user = Config.user_class.find_by_credentials(credentials)
23
23
  user.register_failed_login! if user
24
24
  end
25
25
 
@@ -13,14 +13,14 @@ module Sorcery
13
13
  attr_writer :stretches
14
14
 
15
15
  def encrypt(*tokens)
16
- digest = tokens.flatten.join(join_token)
16
+ digest = tokens.flatten.compact.join(join_token)
17
17
  stretches.times { digest = secure_digest(digest) }
18
18
  digest
19
19
  end
20
20
 
21
21
  # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
22
22
  def matches?(crypted, *tokens)
23
- encrypt(*tokens) == crypted
23
+ encrypt(*tokens.compact) == crypted
24
24
  end
25
25
 
26
26
  def reset!
@@ -7,10 +7,6 @@ module Sorcery
7
7
  class Engine < Rails::Engine
8
8
  config.sorcery = ::Sorcery::Controller::Config
9
9
 
10
- initializer "extend Model with sorcery" do |app|
11
- ActiveRecord::Base.send(:include, Sorcery::Model) if defined?(ActiveRecord)
12
- end
13
-
14
10
  initializer "extend Controller with sorcery" do |app|
15
11
  ActionController::Base.send(:include, Sorcery::Controller)
16
12
  ActionController::Base.helper_method :current_user
@@ -45,6 +45,7 @@ Rails.application.config.sorcery.configure do |config|
45
45
  # user.encryption_key = nil # encryption key used to encrypt reversible encryptions such as AES256.
46
46
  # user.custom_encryption_provider = nil # use an external encryption class.
47
47
  # user.encryption_algorithm = :bcrypt # encryption algorithm name. See 'encryption_algorithm=' for available options.
48
+ # user.subclasses_inherit_config = false # make this configuration inheritable for subclasses. Useful for ActiveRecord's STI.
48
49
 
49
50
  # -- user_activation --
50
51
  # user.activation_state_attribute_name = :activation_state # the attribute name to hold activation state (active/pending).
@@ -0,0 +1,28 @@
1
+ module Sorcery
2
+ module Model
3
+ module Adapters
4
+ module ActiveRecord
5
+ def self.included(klass)
6
+ klass.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def find_by_credentials(credentials)
11
+ where("#{@sorcery_config.username_attribute_name} = ?", credentials[0]).first
12
+ end
13
+
14
+ def find_by_token(token_attr_name, token)
15
+ where("#{token_attr_name} = ?", token).first
16
+ end
17
+
18
+ def get_current_users
19
+ config = sorcery_config
20
+ where("#{config.last_activity_at_attribute_name} IS NOT NULL") \
21
+ .where("#{config.last_logout_at_attribute_name} IS NULL OR #{config.last_activity_at_attribute_name} > #{config.last_logout_at_attribute_name}") \
22
+ .where("#{config.last_activity_at_attribute_name} > ? ", config.activity_timeout.seconds.ago.utc.to_s(:db))
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,59 @@
1
+ module Sorcery
2
+ module Model
3
+ module Adapters
4
+ module Mongoid
5
+ def self.included(klass)
6
+ klass.extend ClassMethods
7
+ klass.send(:include, InstanceMethods)
8
+ end
9
+
10
+ module InstanceMethods
11
+ def increment(attr)
12
+ self.inc(attr,1)
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def find_by_credentials(credentials)
18
+ where(@sorcery_config.username_attribute_name => credentials[0]).first
19
+ end
20
+
21
+ def find_by_provider_and_uid(provider, uid)
22
+ where(:provider => provider, :uid => uid).first
23
+ end
24
+
25
+ def find_by_id(id)
26
+ find(id)
27
+ end
28
+
29
+ def find_by_activation_token(token)
30
+ where(:activation_token => token).first
31
+ end
32
+
33
+ def find_by_remember_me_token(token)
34
+ where(:remember_me_token => token).first
35
+ end
36
+
37
+ def find_by_username(username)
38
+ where(:username => username).first
39
+ end
40
+
41
+ def transaction(&blk)
42
+ tap(&blk)
43
+ end
44
+
45
+ def find_by_token(token_attr_name, token)
46
+ where(token_attr_name => token).first
47
+ end
48
+
49
+ def get_current_users
50
+ config = sorcery_config
51
+ where(config.last_activity_at_attribute_name.ne => nil) \
52
+ .any_of({config.last_logout_at_attribute_name => nil},{config.last_activity_at_attribute_name.gt => config.last_logout_at_attribute_name}) \
53
+ .and(config.last_activity_at_attribute_name.gt => config.activity_timeout.seconds.ago.utc.to_s(:db)).order_by([:_id,:asc])
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -9,6 +9,7 @@ module Sorcery
9
9
  module ActivityLogging
10
10
  def self.included(base)
11
11
  base.extend(ClassMethods)
12
+
12
13
  base.sorcery_config.class_eval do
13
14
  attr_accessor :last_login_at_attribute_name, # last login attribute name.
14
15
  :last_logout_at_attribute_name, # last logout attribute name.
@@ -23,15 +24,23 @@ module Sorcery
23
24
  :@activity_timeout => 10 * 60)
24
25
  reset!
25
26
  end
27
+
28
+ base.sorcery_config.after_config << :define_activity_logging_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
26
29
  end
27
30
 
28
31
  module ClassMethods
29
32
  # get all users with last_activity within timeout
30
33
  def current_users
31
34
  config = sorcery_config
32
- where("#{config.last_activity_at_attribute_name} IS NOT NULL") \
33
- .where("#{config.last_logout_at_attribute_name} IS NULL OR #{config.last_activity_at_attribute_name} > #{config.last_logout_at_attribute_name}") \
34
- .where("#{config.last_activity_at_attribute_name} > ? ", config.activity_timeout.seconds.ago.utc.to_s(:db))
35
+ get_current_users
36
+ end
37
+
38
+ protected
39
+
40
+ def define_activity_logging_mongoid_fields
41
+ field sorcery_config.last_login_at_attribute_name, type: DateTime
42
+ field sorcery_config.last_logout_at_attribute_name, type: DateTime
43
+ field sorcery_config.last_activity_at_attribute_name, type: DateTime
35
44
  end
36
45
  end
37
46
  end
@@ -21,13 +21,18 @@ module Sorcery
21
21
  end
22
22
 
23
23
  base.sorcery_config.before_authenticate << :prevent_locked_user_login
24
+ base.sorcery_config.after_config << :define_brute_force_protection_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
24
25
  base.extend(ClassMethods)
25
26
  base.send(:include, InstanceMethods)
26
27
  end
27
28
 
28
29
  module ClassMethods
29
30
  protected
30
-
31
+
32
+ def define_brute_force_protection_mongoid_fields
33
+ field sorcery_config.failed_logins_count_attribute_name, type: Integer
34
+ field sorcery_config.lock_expires_at_attribute_name, type: DateTime
35
+ end
31
36
  end
32
37
 
33
38
  module InstanceMethods
@@ -32,6 +32,7 @@ module Sorcery
32
32
 
33
33
  base.send(:include, InstanceMethods)
34
34
  base.extend(ClassMethods)
35
+
35
36
  end
36
37
 
37
38
  module ClassMethods
@@ -21,8 +21,22 @@ module Sorcery
21
21
  end
22
22
 
23
23
  base.send(:include, InstanceMethods)
24
+
25
+ base.sorcery_config.after_config << :define_remember_me_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
26
+
27
+ base.extend(ClassMethods)
28
+ end
29
+
30
+ module ClassMethods
31
+ protected
32
+
33
+ def define_remember_me_mongoid_fields
34
+ field sorcery_config.remember_me_token_attribute_name, type: String
35
+ field sorcery_config.remember_me_token_expires_at_attribute_name, type: DateTime
36
+ end
37
+
24
38
  end
25
-
39
+
26
40
  module InstanceMethods
27
41
  # You shouldn't really use this one yourself - it's called by the controller's 'remember_me!' method.
28
42
  def remember_me!
@@ -34,10 +34,12 @@ module Sorcery
34
34
  end
35
35
 
36
36
  base.sorcery_config.after_config << :validate_mailer_defined
37
-
37
+ base.sorcery_config.after_config << :define_reset_password_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
38
+
38
39
  base.extend(ClassMethods)
39
40
  base.send(:include, TemporaryToken)
40
41
  base.send(:include, InstanceMethods)
42
+
41
43
  end
42
44
 
43
45
  module ClassMethods
@@ -57,6 +59,11 @@ module Sorcery
57
59
  raise ArgumentError, msg if @sorcery_config.reset_password_mailer == nil
58
60
  end
59
61
 
62
+ def define_reset_password_mongoid_fields
63
+ field sorcery_config.reset_password_token_attribute_name, type: String
64
+ field sorcery_config.reset_password_token_expires_at_attribute_name, type: DateTime
65
+ field sorcery_config.reset_password_email_sent_at_attribute_name, type: DateTime
66
+ end
60
67
  end
61
68
 
62
69
  module InstanceMethods
@@ -75,9 +82,9 @@ module Sorcery
75
82
  end
76
83
 
77
84
  # Clears token and tries to update the new password for the user.
78
- def reset_password!(params)
85
+ def change_password!(new_password)
79
86
  clear_reset_password_token
80
- update_attributes(params)
87
+ update_attributes(sorcery_config.password_attribute_name => new_password)
81
88
  end
82
89
 
83
90
  protected
@@ -38,12 +38,14 @@ module Sorcery
38
38
  end
39
39
 
40
40
  base.sorcery_config.after_config << :validate_mailer_defined
41
-
41
+ base.sorcery_config.after_config << :define_user_activation_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
42
42
  base.sorcery_config.before_authenticate << :prevent_non_active_login
43
43
 
44
44
  base.extend(ClassMethods)
45
45
  base.send(:include, TemporaryToken)
46
46
  base.send(:include, InstanceMethods)
47
+
48
+
47
49
  end
48
50
 
49
51
  module ClassMethods
@@ -62,6 +64,14 @@ module Sorcery
62
64
  msg = "To use user_activation submodule, you must define a mailer (config.user_activation_mailer = YourMailerClass)."
63
65
  raise ArgumentError, msg if @sorcery_config.user_activation_mailer == nil
64
66
  end
67
+
68
+ def define_user_activation_mongoid_fields
69
+ self.class_eval do
70
+ field sorcery_config.activation_state_attribute_name, type: String
71
+ field sorcery_config.activation_token_attribute_name, type: String
72
+ field sorcery_config.activation_token_expires_at_attribute_name, type: DateTime
73
+ end
74
+ end
65
75
  end
66
76
 
67
77
  module InstanceMethods
@@ -10,7 +10,7 @@ module Sorcery
10
10
  module ClassMethods
11
11
  def load_from_token(token, token_attr_name, token_expiration_date_attr)
12
12
  return nil if token.blank?
13
- user = where("#{token_attr_name} = ?", token).first
13
+ user = find_by_token(token_attr_name,token)
14
14
  if !user.blank? && !user.send(token_expiration_date_attr).nil?
15
15
  return Time.now.utc < user.send(token_expiration_date_attr) ? user : nil
16
16
  end
data/lib/sorcery/model.rb CHANGED
@@ -26,10 +26,18 @@ module Sorcery
26
26
  end
27
27
  end
28
28
  end
29
-
29
+
30
30
  # This runs the options block set in the initializer on the model class.
31
31
  ::Sorcery::Controller::Config.user_config.tap{|blk| blk.call(@sorcery_config) if blk}
32
-
32
+
33
+ self.class_eval do
34
+ field sorcery_config.username_attribute_name, type: String
35
+ field sorcery_config.password_attribute_name, type: String
36
+ field sorcery_config.email_attribute_name, type: String unless sorcery_config.username_attribute_name == sorcery_config.email_attribute_name
37
+ field sorcery_config.crypted_password_attribute_name, type: String
38
+ field sorcery_config.salt_attribute_name, type: String
39
+ end if defined?(Mongoid) and self.ancestors.include?(Mongoid::Document)
40
+
33
41
  # add virtual password accessor and ORM callbacks
34
42
  self.class_eval do
35
43
  attr_accessor @sorcery_config.password_attribute_name
@@ -38,7 +46,7 @@ module Sorcery
38
46
  after_save :clear_virtual_password, :if => Proc.new { |record| record.send(sorcery_config.password_attribute_name).present? }
39
47
  end
40
48
 
41
- @sorcery_config.after_config << :add_config_inheritence if @sorcery_config.subclasses_inherit_config
49
+ @sorcery_config.after_config << :add_config_inheritance if @sorcery_config.subclasses_inherit_config
42
50
  @sorcery_config.after_config.each { |c| send(c) }
43
51
  end
44
52
  end
@@ -57,7 +65,7 @@ module Sorcery
57
65
  # returns the user if success, nil otherwise.
58
66
  def authenticate(*credentials)
59
67
  raise ArgumentError, "at least 2 arguments required" if credentials.size < 2
60
- user = where("#{@sorcery_config.username_attribute_name} = ?", credentials[0]).first
68
+ user = find_by_credentials(credentials)
61
69
  _salt = user.send(@sorcery_config.salt_attribute_name) if user && !@sorcery_config.salt_attribute_name.nil? && !@sorcery_config.encryption_provider.nil?
62
70
  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)
63
71
  end
@@ -80,7 +88,7 @@ module Sorcery
80
88
  @sorcery_config.encryption_provider.matches?(crypted, *tokens)
81
89
  end
82
90
 
83
- def add_config_inheritence
91
+ def add_config_inheritance
84
92
  self.class_eval do
85
93
  def self.inherited(subclass)
86
94
  subclass.class_eval do
@@ -111,7 +119,7 @@ module Sorcery
111
119
  protected
112
120
 
113
121
  # creates new salt and saves it.
114
- # encrypts password with salt and save it.
122
+ # encrypts password with salt and saves it.
115
123
  def encrypt_password
116
124
  config = sorcery_config
117
125
  new_salt = self.send(:"#{config.salt_attribute_name}=", generate_random_token) if !config.salt_attribute_name.nil?
@@ -135,7 +143,7 @@ module Sorcery
135
143
 
136
144
  # Random code, used for salt and temporary tokens.
137
145
  def generate_random_token
138
- return Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
146
+ Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
139
147
  end
140
148
  end
141
149
 
@@ -1,4 +1,3 @@
1
- ActiveRecord::Base.send(:include, Sorcery::Model) if defined?(ActiveRecord)
2
1
  if defined?(Sinatra::Base)
3
2
  Sinatra::Base.send(:include, Sorcery::Controller::Adapters::Sinatra)
4
3
  Sinatra::Base.send(:include, Sorcery::Controller)
@@ -2,6 +2,8 @@ module Sorcery
2
2
  module TestHelpers
3
3
  module Internal
4
4
  module Sinatra
5
+ include ::Sorcery::TestHelpers::Sinatra::CookieSessionMethods
6
+ include ::Sorcery::TestHelpers::Sinatra::InstanceMethods
5
7
 
6
8
  class ::Sinatra::Application
7
9
  class << self
@@ -24,64 +26,14 @@ module Sorcery
24
26
  end
25
27
  end
26
28
 
27
- def get_sinatra_app(app)
28
- while app.class != ::Sinatra::Application do
29
- app = app.instance_variable_get(:@app)
30
- end
31
- app
32
- end
33
-
34
- def login_user(user=nil)
35
- user ||= @user
36
- get_sinatra_app(subject).send(:login_user,user)
37
- get_sinatra_app(subject).send(:after_login!,user,[user.username,'secret'])
38
- end
39
-
40
- def logout_user
41
- get_sinatra_app(subject).send(:logout)
42
- end
43
-
44
29
  def clear_user_without_logout
45
- get_sinatra_app(subject).instance_variable_set(:@current_user,nil)
30
+ get_sinatra_app(subject).instance_variable_set(:@current_user, nil)
46
31
  end
47
32
 
48
33
  def assigns
49
34
  ::Sinatra::Application.sorcery_vars
50
35
  end
51
36
 
52
- class SessionData
53
- def initialize(cookies)
54
- @cookies = cookies
55
- @data = cookies['rack.session']
56
- if @data
57
- @data = @data.unpack("m*").first
58
- @data = Marshal.load(@data)
59
- else
60
- @data = {}
61
- end
62
- end
63
-
64
- def [](key)
65
- @data[key]
66
- end
67
-
68
- def []=(key, value)
69
- @data[key] = value
70
- session_data = Marshal.dump(@data)
71
- session_data = [session_data].pack("m*")
72
- @cookies.merge("rack.session=#{Rack::Utils.escape(session_data)}", URI.parse("//example.org//"))
73
- raise "session variable not set" unless @cookies['rack.session'] == session_data
74
- end
75
- end
76
-
77
- def session
78
- SessionData.new(rack_test_session.instance_variable_get(:@rack_mock_session).cookie_jar)
79
- end
80
-
81
- def cookies
82
- rack_test_session.instance_variable_get(:@rack_mock_session).cookie_jar
83
- end
84
-
85
37
  def sorcery_reload!(submodules = [], options = {})
86
38
  reload_user_class
87
39
 
@@ -90,9 +42,9 @@ module Sorcery
90
42
  ::Sorcery::Controller::Config.reset!
91
43
 
92
44
  # clear all filters
93
- ::Sinatra::Application.instance_variable_set(:@filters,{:before => [],:after => []})
45
+ ::Sinatra::Application.instance_variable_set(:@filters, {:before => [], :after => []})
94
46
  ::Sinatra::Application.class_eval do
95
- load File.join(File.dirname(__FILE__),'..','..','..','..','spec','sinatra','filters.rb')
47
+ load File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'spec', 'sinatra', 'filters.rb')
96
48
  end
97
49
 
98
50
  # configure
@@ -102,7 +54,7 @@ module Sorcery
102
54
  ::Sinatra::Application.send(:include, Sorcery::Controller)
103
55
 
104
56
  ::Sorcery::Controller::Config.user_config do |user|
105
- options.each do |property,value|
57
+ options.each do |property, value|
106
58
  user.send(:"#{property}=", value)
107
59
  end
108
60
  end
@@ -30,9 +30,10 @@ module Sorcery
30
30
  end
31
31
 
32
32
  def create_new_external_user(provider, attributes_hash = nil)
33
- user_attributes_hash = attributes_hash || {:username => 'gizmo', :authentications_attributes => [{:provider => provider, :uid => 123}]}
33
+ user_attributes_hash = attributes_hash || {:username => 'gizmo'}
34
34
  @user = User.new(user_attributes_hash)
35
35
  @user.save!
36
+ @user.authentications.create!({:provider => provider, :uid => 123})
36
37
  @user
37
38
  end
38
39
 
@@ -76,9 +76,12 @@ module Sorcery
76
76
  end
77
77
 
78
78
  def session
79
- SessionData.new(rack_test_session.instance_variable_get(:@rack_mock_session).cookie_jar)
79
+ SessionData.new(cookies)
80
80
  end
81
81
 
82
+ def cookies
83
+ rack_test_session.instance_variable_get(:@rack_mock_session).cookie_jar
84
+ end
82
85
  end
83
86
  end
84
87
  end
data/lib/sorcery.rb CHANGED
@@ -2,6 +2,10 @@ module Sorcery
2
2
  autoload :Model, 'sorcery/model'
3
3
  module Model
4
4
  autoload :TemporaryToken, 'sorcery/model/temporary_token'
5
+ module Adapters
6
+ autoload :ActiveRecord, 'sorcery/model/adapters/active_record'
7
+ autoload :Mongoid, 'sorcery/model/adapters/mongoid'
8
+ end
5
9
  module Submodules
6
10
  autoload :UserActivation, 'sorcery/model/submodules/user_activation'
7
11
  autoload :ResetPassword, 'sorcery/model/submodules/reset_password'
@@ -56,7 +60,24 @@ module Sorcery
56
60
 
57
61
  end
58
62
 
59
-
63
+ if defined?(ActiveRecord)
64
+ ActiveRecord::Base.send(:include, Sorcery::Model)
65
+ ActiveRecord::Base.send(:include, ::Sorcery::Model::Adapters::ActiveRecord)
66
+ end
67
+
68
+ if defined?(Mongoid)
69
+ Mongoid::Document.module_eval do
70
+ included do
71
+ attr_reader :new_record
72
+ include Sorcery::Model::Adapters::Mongoid
73
+ include Sorcery::Model
74
+ end
75
+ end
76
+ end
77
+
60
78
  require 'sorcery/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
61
79
  require 'sorcery/sinatra' if defined?(Sinatra)
80
+
81
+
82
+
62
83
  end