sorcery 0.2.1 → 0.3.1

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 (79) hide show
  1. data/README.rdoc +129 -61
  2. data/VERSION +1 -1
  3. data/lib/generators/sorcery_migration/sorcery_migration_generator.rb +24 -0
  4. data/lib/generators/sorcery_migration/templates/activity_logging.rb +17 -0
  5. data/lib/generators/sorcery_migration/templates/brute_force_protection.rb +11 -0
  6. data/lib/generators/sorcery_migration/templates/core.rb +16 -0
  7. data/lib/generators/sorcery_migration/templates/external.rb +14 -0
  8. data/lib/generators/sorcery_migration/templates/remember_me.rb +15 -0
  9. data/lib/generators/sorcery_migration/templates/reset_password.rb +13 -0
  10. data/lib/generators/sorcery_migration/templates/user_activation.rb +17 -0
  11. data/lib/sorcery/controller/adapters/sinatra.rb +97 -0
  12. data/lib/sorcery/controller/submodules/email.rb +44 -0
  13. data/lib/sorcery/controller/submodules/external/protocols/oauth1.rb +35 -0
  14. data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +26 -0
  15. data/lib/sorcery/controller/submodules/{oauth → external}/providers/facebook.rb +24 -6
  16. data/lib/sorcery/controller/submodules/{oauth → external}/providers/twitter.rb +31 -6
  17. data/lib/sorcery/controller/submodules/external.rb +83 -0
  18. data/lib/sorcery/controller/submodules/http_basic_auth.rb +10 -6
  19. data/lib/sorcery/controller/submodules/oauth.rb +6 -3
  20. data/lib/sorcery/controller.rb +5 -3
  21. data/lib/sorcery/model/submodules/activity_logging.rb +1 -1
  22. data/lib/sorcery/model/submodules/brute_force_protection.rb +0 -4
  23. data/lib/sorcery/model/submodules/{oauth.rb → external.rb} +3 -3
  24. data/lib/sorcery/model.rb +9 -6
  25. data/lib/sorcery/sinatra.rb +14 -0
  26. data/lib/sorcery/test_helpers/rails.rb +57 -0
  27. data/lib/sorcery/test_helpers/sinatra.rb +131 -0
  28. data/lib/sorcery/test_helpers.rb +8 -52
  29. data/lib/sorcery.rb +17 -7
  30. data/sorcery.gemspec +86 -10
  31. data/spec/Gemfile +1 -1
  32. data/spec/Gemfile.lock +2 -2
  33. data/spec/rails3/app_root/Gemfile +2 -4
  34. data/spec/rails3/app_root/Gemfile.lock +2 -5
  35. data/spec/rails3/app_root/app/controllers/application_controller.rb +11 -11
  36. data/spec/rails3/app_root/spec/controller_oauth2_spec.rb +15 -13
  37. data/spec/rails3/app_root/spec/controller_oauth_spec.rb +18 -13
  38. data/spec/rails3/app_root/spec/controller_session_timeout_spec.rb +2 -2
  39. data/spec/rails3/app_root/spec/spec_helper.rb +1 -0
  40. data/spec/rails3/app_root/spec/user_oauth_spec.rb +4 -4
  41. data/spec/rails3/app_root/spec/user_spec.rb +2 -2
  42. data/spec/sinatra/Gemfile +12 -0
  43. data/spec/sinatra/Gemfile.lock +134 -0
  44. data/spec/sinatra/Rakefile +10 -0
  45. data/spec/sinatra/authentication.rb +3 -0
  46. data/spec/sinatra/db/migrate/activation/20101224223622_add_activation_to_users.rb +17 -0
  47. data/spec/sinatra/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +17 -0
  48. data/spec/sinatra/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +11 -0
  49. data/spec/sinatra/db/migrate/core/20101224223620_create_users.rb +16 -0
  50. data/spec/sinatra/db/migrate/external/20101224223628_create_authentications.rb +14 -0
  51. data/spec/sinatra/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
  52. data/spec/sinatra/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
  53. data/spec/sinatra/filters.rb +21 -0
  54. data/spec/sinatra/myapp.rb +133 -0
  55. data/spec/sinatra/sorcery_mailer.rb +25 -0
  56. data/spec/sinatra/spec/controller_activity_logging_spec.rb +85 -0
  57. data/spec/sinatra/spec/controller_brute_force_protection_spec.rb +69 -0
  58. data/spec/sinatra/spec/controller_http_basic_auth_spec.rb +53 -0
  59. data/spec/sinatra/spec/controller_oauth2_spec.rb +119 -0
  60. data/spec/sinatra/spec/controller_oauth_spec.rb +121 -0
  61. data/spec/sinatra/spec/controller_remember_me_spec.rb +64 -0
  62. data/spec/sinatra/spec/controller_session_timeout_spec.rb +52 -0
  63. data/spec/sinatra/spec/controller_spec.rb +120 -0
  64. data/spec/sinatra/spec/spec.opts +4 -0
  65. data/spec/sinatra/spec/spec_helper.rb +44 -0
  66. data/spec/sinatra/spec/user_activation_spec.rb +188 -0
  67. data/spec/sinatra/spec/user_activity_logging_spec.rb +36 -0
  68. data/spec/sinatra/spec/user_brute_force_protection_spec.rb +76 -0
  69. data/spec/sinatra/spec/user_oauth_spec.rb +39 -0
  70. data/spec/sinatra/spec/user_remember_me_spec.rb +66 -0
  71. data/spec/sinatra/spec/user_reset_password_spec.rb +178 -0
  72. data/spec/sinatra/spec/user_spec.rb +317 -0
  73. data/spec/sinatra/user.rb +6 -0
  74. data/spec/sinatra/views/test_login.erb +4 -0
  75. data/spec/untitled folder +18 -0
  76. metadata +85 -9
  77. data/lib/sorcery/controller/submodules/oauth/oauth1.rb +0 -26
  78. data/lib/sorcery/controller/submodules/oauth/oauth2.rb +0 -24
  79. /data/spec/rails3/app_root/db/migrate/{oauth → external}/20101224223628_create_authentications.rb +0 -0
@@ -1,7 +1,7 @@
1
1
  module Sorcery
2
2
  module Controller
3
3
  module Submodules
4
- module Oauth
4
+ module External
5
5
  module Providers
6
6
  # This module adds support for OAuth with Twitter.com.
7
7
  # When included in the 'config.providers' option, it adds a new option, 'config.twitter'.
@@ -15,7 +15,10 @@ module Sorcery
15
15
  def self.included(base)
16
16
  base.module_eval do
17
17
  class << self
18
- attr_reader :twitter # access to twitter_client.
18
+ attr_reader :twitter
19
+ # def twitter(&blk) # allows block syntax.
20
+ # yield @twitter
21
+ # end
19
22
 
20
23
  def merge_twitter_defaults!
21
24
  @defaults.merge!(:@twitter => TwitterClient)
@@ -25,7 +28,7 @@ module Sorcery
25
28
  update!
26
29
  end
27
30
  end
28
-
31
+
29
32
  module TwitterClient
30
33
  class << self
31
34
  attr_accessor :key,
@@ -35,7 +38,7 @@ module Sorcery
35
38
  :user_info_path,
36
39
  :user_info_mapping
37
40
 
38
- include Oauth1
41
+ include Protocols::Oauth1
39
42
 
40
43
  def init
41
44
  @site = "https://api.twitter.com"
@@ -43,13 +46,35 @@ module Sorcery
43
46
  @user_info_mapping = {}
44
47
  end
45
48
 
46
- def get_user_hash(access_token)
49
+ def get_user_hash
47
50
  user_hash = {}
48
- response = access_token.get(@user_info_path)
51
+ response = @access_token.get(@user_info_path)
49
52
  user_hash[:user_info] = JSON.parse(response.body)
50
53
  user_hash[:uid] = user_hash[:user_info]['id']
51
54
  user_hash
52
55
  end
56
+
57
+ def has_callback?
58
+ true
59
+ end
60
+
61
+ # calculates and returns the url to which the user should be redirected,
62
+ # to get authenticated at the external provider's site.
63
+ def login_url(params,session)
64
+ req_token = self.get_request_token
65
+ session[:request_token] = req_token.token
66
+ session[:request_token_secret] = req_token.secret
67
+ self.authorize_url({:request_token => req_token.token, :request_token_secret => req_token.secret})
68
+ end
69
+
70
+ # tries to login the user from access token
71
+ def process_callback(params,session)
72
+ args = {}
73
+ args.merge!({:oauth_verifier => params[:oauth_verifier], :request_token => session[:request_token], :request_token_secret => session[:request_token_secret]})
74
+ args.merge!({:code => params[:code]}) if params[:code]
75
+ @access_token = self.get_access_token(args)
76
+ end
77
+
53
78
  end
54
79
  init
55
80
  end
@@ -0,0 +1,83 @@
1
+ module Sorcery
2
+ module Controller
3
+ module Submodules
4
+ # This submodule helps you login users from external auth providers such as Twitter.
5
+ # This is the controller part which handles the http requests and tokens passed between the app and the provider.
6
+ module External
7
+ def self.included(base)
8
+ base.send(:include, InstanceMethods)
9
+ Config.module_eval do
10
+ class << self
11
+ attr_reader :external_providers # external providers like twitter.
12
+
13
+ def merge_external_defaults!
14
+ @defaults.merge!(:@external_providers => [])
15
+ end
16
+
17
+ def external_providers=(providers)
18
+ providers.each do |provider|
19
+ include Providers.const_get(provider.to_s.split("_").map {|p| p.capitalize}.join(""))
20
+ end
21
+ end
22
+ end
23
+ merge_external_defaults!
24
+ end
25
+ end
26
+
27
+ module InstanceMethods
28
+ protected
29
+
30
+ # sends user to authenticate at the provider's website.
31
+ # after authentication the user is redirected to the callback defined in the provider config
32
+ def login_at(provider, args = {})
33
+ @provider = Config.send(provider)
34
+ if @provider.has_callback?
35
+ redirect_to @provider.login_url(params,session)
36
+ else
37
+ #@provider.login(args)
38
+ end
39
+ end
40
+
41
+ # tries to login the user from provider's callback
42
+ def login_from(provider)
43
+ @provider = Config.send(provider)
44
+ @provider.process_callback(params,session)
45
+ @user_hash = @provider.get_user_hash
46
+ if user = Config.user_class.load_from_provider(provider,@user_hash[:uid])
47
+ reset_session
48
+ login_user(user)
49
+ user
50
+ end
51
+ end
52
+
53
+ # this method automatically creates a new user from the data in the external user hash.
54
+ # The mappings from user hash fields to user db fields are set at controller config.
55
+ # If the hash field you would like to map is nested, use slashes. For example, Given a hash like:
56
+ #
57
+ # "user" => {"name"=>"moishe"}
58
+ #
59
+ # You will set the mapping:
60
+ #
61
+ # {:username => "user/name"}
62
+ #
63
+ # And this will cause 'moishe' to be set as the value of :username field.
64
+ def create_from(provider)
65
+ provider = provider.to_sym
66
+ @provider = Config.send(provider)
67
+ @user_hash = @provider.get_user_hash
68
+ config = Config.user_class.sorcery_config
69
+ attrs = {}
70
+ @provider.user_info_mapping.each do |k,v|
71
+ (varr = v.split("/")).size > 1 ? attrs.merge!(k => varr.inject(@user_hash[:user_info]) {|hsh,v| hsh[v] }) : attrs.merge!(k => @user_hash[:user_info][v])
72
+ end
73
+ Config.user_class.transaction do
74
+ @user = Config.user_class.create!(attrs)
75
+ Config.user_class.sorcery_config.authentications_class.create!({config.authentications_user_id_attribute_name => @user.id, config.provider_attribute_name => provider, config.provider_uid_attribute_name => @user_hash[:uid]})
76
+ end
77
+ @user
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -48,13 +48,17 @@ module Sorcery
48
48
 
49
49
  # Sets the realm name by searching the controller name in the hash given at configuration time.
50
50
  def realm_name_by_controller
51
- current_controller = self.class
52
- while current_controller != ActionController::Base
53
- result = Config.controller_to_realm_map[current_controller.controller_name]
54
- return result if result
55
- current_controller = self.class.superclass
51
+ if defined?(ActionController::Base)
52
+ current_controller = self.class
53
+ while current_controller != ActionController::Base
54
+ result = Config.controller_to_realm_map[current_controller.controller_name]
55
+ return result if result
56
+ current_controller = self.class.superclass
57
+ end
58
+ nil
59
+ else
60
+ Config.controller_to_realm_map["application"]
56
61
  end
57
- nil
58
62
  end
59
63
 
60
64
  end
@@ -32,9 +32,12 @@ module Sorcery
32
32
  # after authentication the user is redirected to the callback defined in the provider config
33
33
  def auth_at_provider(provider)
34
34
  @provider = Config.send(provider)
35
+ args = {}
35
36
  if @provider.respond_to?(:get_request_token)
36
- args = {:request_token => @provider.get_request_token}
37
- session[:request_token] = args[:request_token]
37
+ req_token = @provider.get_request_token
38
+ session[:request_token] = req_token.token
39
+ session[:request_token_secret] = req_token.secret
40
+ args.merge!({:request_token => req_token.token, :request_token_secret => req_token.secret})
38
41
  end
39
42
  redirect_to @provider.authorize_url(args)
40
43
  end
@@ -43,7 +46,7 @@ module Sorcery
43
46
  def login_from_access_token(provider)
44
47
  @provider = Config.send(provider)
45
48
  args = {}
46
- args.merge!({:oauth_verifier => params[:oauth_verifier], :request_token => session[:request_token]}) if @provider.respond_to?(:get_request_token)
49
+ args.merge!({:oauth_verifier => params[:oauth_verifier], :request_token => session[:request_token], :request_token_secret => session[:request_token_secret]}) if @provider.respond_to?(:get_request_token)
47
50
  args.merge!({:code => params[:code]}) if params[:code]
48
51
  @access_token = @provider.get_access_token(args)
49
52
  @user_hash = @provider.get_user_hash(@access_token)
@@ -5,7 +5,7 @@ module Sorcery
5
5
  extend ClassMethods
6
6
  include InstanceMethods
7
7
  Config.submodules.each do |mod|
8
- begin # FIXME: is this protection needed?
8
+ begin
9
9
  include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
10
10
  rescue NameError
11
11
  # don't stop on a missing submodule.
@@ -73,12 +73,14 @@ module Sorcery
73
73
  @current_user ||= login_from_session || login_from_other_sources unless @current_user == false
74
74
  end
75
75
 
76
- def return_or_redirect_to(url, flash_hash = {})
76
+ # 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.
77
+ def redirect_back_or_to(url, flash_hash = {})
77
78
  redirect_to(session[:return_to_url] || url, :flash => flash_hash)
78
79
  end
79
80
 
80
81
  # The default action for denying non-authenticated users.
81
- # You can override this method in your controllers.
82
+ # You can override this method in your controllers,
83
+ # or provide a different method in the configuration.
82
84
  def not_authenticated
83
85
  redirect_to root_path
84
86
  end
@@ -31,7 +31,7 @@ module Sorcery
31
31
  config = sorcery_config
32
32
  where("#{config.last_activity_at_attribute_name} IS NOT NULL") \
33
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)
34
+ .where("#{config.last_activity_at_attribute_name} > ? ", config.activity_timeout.seconds.ago.utc.to_s(:db))
35
35
  end
36
36
  end
37
37
  end
@@ -20,10 +20,6 @@ module Sorcery
20
20
  reset!
21
21
  end
22
22
 
23
- base.class_eval do
24
-
25
- end
26
-
27
23
  base.sorcery_config.before_authenticate << :prevent_locked_user_login
28
24
  base.extend(ClassMethods)
29
25
  base.send(:include, InstanceMethods)
@@ -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
@@ -56,12 +56,6 @@ module Sorcery
56
56
  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
57
  end
58
58
 
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
59
  # encrypt tokens using current encryption_provider.
66
60
  def encrypt(*tokens)
67
61
  return tokens.first if @sorcery_config.encryption_provider.nil?
@@ -71,6 +65,15 @@ module Sorcery
71
65
  CryptoProviders::AES256.key = @sorcery_config.encryption_key if @sorcery_config.encryption_algorithm == :aes256
72
66
  @sorcery_config.encryption_provider.encrypt(*tokens)
73
67
  end
68
+
69
+ protected
70
+
71
+ # Calls the configured encryption provider to compare the supplied password with the encrypted one.
72
+ def credentials_match?(crypted, *tokens)
73
+ return crypted == tokens.join if @sorcery_config.encryption_provider.nil?
74
+ @sorcery_config.encryption_provider.matches?(crypted, *tokens)
75
+ end
76
+
74
77
  end
75
78
 
76
79
  module InstanceMethods
@@ -0,0 +1,14 @@
1
+ ActiveRecord::Base.send(:include, Sorcery::Model) if defined?(ActiveRecord)
2
+ if defined?(Sinatra::Base)
3
+ Sinatra::Base.send(:include, Sorcery::Controller::Adapters::Sinatra)
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
+ end
@@ -0,0 +1,57 @@
1
+ module Sorcery
2
+ module TestHelpers
3
+ module Rails
4
+ SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS = [:register_last_activity_time_to_db, :deny_banned_user, :validate_session]
5
+
6
+ def sorcery_reload!(submodules = [], options = {})
7
+ reload_user_class
8
+
9
+ # return to no-module configuration
10
+ ::Sorcery::Controller::Config.init!
11
+ ::Sorcery::Controller::Config.reset!
12
+
13
+ # remove all plugin before_filters so they won't fail other tests.
14
+ # I don't like this way, but I didn't find another.
15
+ # hopefully it won't break until Rails 4.
16
+ ApplicationController._process_action_callbacks.delete_if {|c| SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) }
17
+
18
+ # configure
19
+ ::Sorcery::Controller::Config.submodules = submodules
20
+ ::Sorcery::Controller::Config.user_class = nil
21
+ ActionController::Base.send(:include,::Sorcery::Controller)
22
+
23
+ User.activate_sorcery! do |config|
24
+ options.each do |property,value|
25
+ config.send(:"#{property}=", value)
26
+ end
27
+ end
28
+ end
29
+
30
+ def sorcery_controller_property_set(property, value)
31
+ ApplicationController.activate_sorcery! do |config|
32
+ config.send(:"#{property}=", value)
33
+ end
34
+ end
35
+
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
40
+ end
41
+
42
+ def login_user(user = nil)
43
+ user ||= @user
44
+ subject.send(:login_user,user)
45
+ subject.send(:after_login!,user,[user.username,'secret'])
46
+ end
47
+
48
+ def logout_user
49
+ subject.send(:logout)
50
+ end
51
+
52
+ def clear_user_without_logout
53
+ subject.instance_variable_set(:@current_user,nil)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,131 @@
1
+ module Sorcery
2
+ module TestHelpers
3
+ module Sinatra
4
+
5
+ class MyApp
6
+ class << self
7
+ def new
8
+ return this
9
+ end
10
+ end
11
+ end
12
+
13
+ class ::Sinatra::Application
14
+ class << self
15
+ attr_accessor :sorcery_vars
16
+ end
17
+ @sorcery_vars = {}
18
+
19
+ # NOTE: see before and after test filters in filters.rb
20
+
21
+ def save_instance_vars
22
+ instance_variables.each do |var|
23
+ self.class.sorcery_vars[:"#{var.to_s.delete("@")}"] = instance_variable_get(var)
24
+ end
25
+ end
26
+ end
27
+
28
+ ::RSpec::Matchers.define :redirect_to do |expected|
29
+ match do |actual|
30
+ actual.status == 302 && actual.location == expected
31
+ end
32
+ end
33
+
34
+ def get_sinatra_app(app)
35
+ while app.class != ::Sinatra::Application do
36
+ app = app.instance_variable_get(:@app)
37
+ end
38
+ app
39
+ end
40
+
41
+ def login_user(user=nil)
42
+ user ||= @user
43
+ get_sinatra_app(subject).send(:login_user,user)
44
+ get_sinatra_app(subject).send(:after_login!,user,[user.username,'secret'])
45
+ end
46
+
47
+ def logout_user
48
+ get_sinatra_app(subject).send(:logout)
49
+ end
50
+
51
+ def clear_user_without_logout
52
+ get_sinatra_app(subject).instance_variable_set(:@current_user,nil)
53
+ end
54
+
55
+ def assigns
56
+ ::Sinatra::Application.sorcery_vars
57
+ end
58
+
59
+ class SessionData
60
+ def initialize(cookies)
61
+ @cookies = cookies
62
+ @data = cookies['rack.session']
63
+ if @data
64
+ @data = @data.unpack("m*").first
65
+ @data = Marshal.load(@data)
66
+ else
67
+ @data = {}
68
+ end
69
+ end
70
+
71
+ def [](key)
72
+ @data[key]
73
+ end
74
+
75
+ def []=(key, value)
76
+ @data[key] = value
77
+ session_data = Marshal.dump(@data)
78
+ session_data = [session_data].pack("m*")
79
+ @cookies.merge("rack.session=#{Rack::Utils.escape(session_data)}", URI.parse("//example.org//"))
80
+ raise "session variable not set" unless @cookies['rack.session'] == session_data
81
+ end
82
+ end
83
+
84
+ def session
85
+ SessionData.new(rack_test_session.instance_variable_get(:@rack_mock_session).cookie_jar)
86
+ end
87
+
88
+ def cookies
89
+ rack_test_session.instance_variable_get(:@rack_mock_session).cookie_jar
90
+ end
91
+
92
+ def sorcery_reload!(submodules = [], options = {})
93
+ reload_user_class
94
+
95
+ # return to no-module configuration
96
+ ::Sorcery::Controller::Config.init!
97
+ ::Sorcery::Controller::Config.reset!
98
+
99
+ # clear all filters
100
+ ::Sinatra::Application.instance_variable_set(:@filters,{:before => [],:after => []})
101
+ ::Sinatra::Application.class_eval do
102
+ load File.join(File.dirname(__FILE__),'..','..','..','spec','sinatra','filters.rb')
103
+ end
104
+
105
+ # configure
106
+ ::Sorcery::Controller::Config.submodules = submodules
107
+ ::Sorcery::Controller::Config.user_class = nil
108
+ ::Sinatra::Application.send(:include, Sorcery::Controller::Adapters::Sinatra)
109
+ ::Sinatra::Application.send(:include, Sorcery::Controller)
110
+
111
+ User.activate_sorcery! do |config|
112
+ options.each do |property,value|
113
+ config.send(:"#{property}=", value)
114
+ end
115
+ end
116
+ end
117
+
118
+ def sorcery_controller_property_set(property, value)
119
+ ::Sinatra::Application.activate_sorcery! do |config|
120
+ config.send(:"#{property}=", value)
121
+ end
122
+ end
123
+
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
128
+ end
129
+ end
130
+ end
131
+ end
@@ -1,7 +1,13 @@
1
1
  module Sorcery
2
2
  module TestHelpers
3
- SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS = [:register_last_activity_time_to_db, :deny_banned_user, :validate_session]
4
-
3
+ # a patch to fix a bug in testing that happens when you 'destroy' a session twice.
4
+ # After the first destroy, the session is an ordinary hash, and then when destroy is called again there's an exception.
5
+ class ::Hash
6
+ def destroy
7
+ clear
8
+ end
9
+ end
10
+
5
11
  def create_new_user(attributes_hash = nil)
6
12
  user_attributes_hash = attributes_hash || {:username => 'gizmo', :email => "bla@bla.com", :password => 'secret'}
7
13
  @user = User.new(user_attributes_hash)
@@ -16,62 +22,12 @@ module Sorcery
16
22
  @user
17
23
  end
18
24
 
19
- def login_user(user = nil)
20
- user ||= @user
21
- subject.send(:login_user,user)
22
- subject.send(:after_login!,user,[user.username,'secret'])
23
- end
24
-
25
- def logout_user
26
- subject.send(:logout)
27
- end
28
-
29
- def clear_user_without_logout
30
- subject.instance_variable_set(:@current_user,nil)
31
- end
32
-
33
- def sorcery_reload!(submodules = [], options = {})
34
- reload_user_class
35
-
36
- # return to no-module configuration
37
- ::Sorcery::Controller::Config.init!
38
- ::Sorcery::Controller::Config.reset!
39
-
40
- # remove all plugin before_filters so they won't fail other tests.
41
- # I don't like this way, but I didn't find another.
42
- # hopefully it won't break until Rails 4.
43
- ApplicationController._process_action_callbacks.delete_if {|c| SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) }
44
-
45
- # configure
46
- ::Sorcery::Controller::Config.submodules = submodules
47
- ::Sorcery::Controller::Config.user_class = nil
48
- ActionController::Base.send(:include,::Sorcery::Controller)
49
-
50
- User.activate_sorcery! do |config|
51
- options.each do |property,value|
52
- config.send(:"#{property}=", value)
53
- end
54
- end
55
- end
56
-
57
25
  def sorcery_model_property_set(property, *values)
58
26
  User.class_eval do
59
27
  sorcery_config.send(:"#{property}=", *values)
60
28
  end
61
29
  end
62
-
63
- def sorcery_controller_property_set(property, value)
64
- ApplicationController.activate_sorcery! do |config|
65
- config.send(:"#{property}=", value)
66
- end
67
- end
68
30
 
69
- def sorcery_controller_oauth_property_set(provider, property, value)
70
- ApplicationController.activate_sorcery! do |config|
71
- config.send(provider).send(:"#{property}=", value)
72
- end
73
- end
74
-
75
31
  private
76
32
 
77
33
  # reload user class between specs
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,16 +19,21 @@ 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
+ module Adapters
35
+ autoload :Sinatra, 'sorcery/controller/adapters/sinatra'
36
+ end
32
37
  end
33
38
  module CryptoProviders
34
39
  autoload :AES256, 'sorcery/crypto_providers/aes256'
@@ -39,6 +44,11 @@ module Sorcery
39
44
  autoload :SHA512, 'sorcery/crypto_providers/sha512'
40
45
  end
41
46
  autoload :TestHelpers, 'sorcery/test_helpers'
47
+ module TestHelpers
48
+ autoload :Rails, 'sorcery/test_helpers/rails'
49
+ autoload :Sinatra, 'sorcery/test_helpers/sinatra'
50
+ end
42
51
 
43
52
  require 'sorcery/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
53
+ require 'sorcery/sinatra' if defined?(Sinatra)
44
54
  end