sorcery 0.1.1 → 0.2.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 (75) hide show
  1. data/Gemfile +4 -3
  2. data/Gemfile.lock +16 -13
  3. data/LICENSE.txt +1 -1
  4. data/README.rdoc +77 -63
  5. data/Rakefile +7 -13
  6. data/VERSION +1 -1
  7. data/lib/sorcery/controller/submodules/activity_logging.rb +58 -0
  8. data/lib/sorcery/controller/submodules/brute_force_protection.rb +15 -69
  9. data/lib/sorcery/controller/submodules/http_basic_auth.rb +65 -0
  10. data/lib/sorcery/controller/submodules/oauth/oauth1.rb +25 -0
  11. data/lib/sorcery/controller/submodules/oauth/oauth2.rb +23 -0
  12. data/lib/sorcery/controller/submodules/oauth/providers/facebook.rb +64 -0
  13. data/lib/sorcery/controller/submodules/oauth/providers/twitter.rb +61 -0
  14. data/lib/sorcery/controller/submodules/oauth.rb +95 -0
  15. data/lib/sorcery/controller/submodules/remember_me.rb +14 -5
  16. data/lib/sorcery/controller/submodules/session_timeout.rb +10 -2
  17. data/lib/sorcery/controller.rb +40 -22
  18. data/lib/sorcery/crypto_providers/bcrypt.rb +3 -7
  19. data/lib/sorcery/engine.rb +9 -2
  20. data/lib/sorcery/model/submodules/activity_logging.rb +40 -0
  21. data/lib/sorcery/model/submodules/brute_force_protection.rb +79 -0
  22. data/lib/sorcery/model/submodules/oauth.rb +53 -0
  23. data/lib/sorcery/model/submodules/remember_me.rb +6 -2
  24. data/lib/sorcery/model/submodules/reset_password.rb +96 -0
  25. data/lib/sorcery/model/submodules/user_activation.rb +44 -23
  26. data/lib/sorcery/model/temporary_token.rb +22 -0
  27. data/lib/sorcery/model.rb +13 -6
  28. data/lib/sorcery/test_helpers.rb +84 -0
  29. data/lib/sorcery.rb +17 -1
  30. data/sorcery.gemspec +85 -41
  31. data/spec/Gemfile +3 -2
  32. data/spec/Gemfile.lock +15 -2
  33. data/spec/rails3/app_root/.rspec +1 -0
  34. data/spec/rails3/{Gemfile → app_root/Gemfile} +5 -3
  35. data/spec/rails3/{Gemfile.lock → app_root/Gemfile.lock} +25 -2
  36. data/spec/rails3/app_root/app/controllers/application_controller.rb +48 -2
  37. data/spec/rails3/app_root/app/models/authentication.rb +3 -0
  38. data/spec/rails3/app_root/app/models/user.rb +4 -1
  39. data/spec/rails3/app_root/config/application.rb +1 -3
  40. data/spec/rails3/app_root/config/routes.rb +1 -9
  41. data/spec/rails3/app_root/db/migrate/activation/20101224223622_add_activation_to_users.rb +6 -4
  42. data/spec/rails3/app_root/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +17 -0
  43. data/spec/rails3/app_root/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +11 -0
  44. data/spec/rails3/app_root/db/migrate/core/20101224223620_create_users.rb +4 -4
  45. data/spec/rails3/app_root/db/migrate/oauth/20101224223628_create_authentications.rb +14 -0
  46. data/spec/rails3/app_root/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
  47. data/spec/rails3/app_root/spec/controller_activity_logging_spec.rb +84 -0
  48. data/spec/rails3/app_root/spec/controller_brute_force_protection_spec.rb +65 -0
  49. data/spec/rails3/app_root/spec/controller_http_basic_auth_spec.rb +50 -0
  50. data/spec/rails3/app_root/spec/controller_oauth2_spec.rb +117 -0
  51. data/spec/rails3/app_root/spec/controller_oauth_spec.rb +117 -0
  52. data/spec/rails3/{controller_remember_me_spec.rb → app_root/spec/controller_remember_me_spec.rb} +4 -4
  53. data/spec/rails3/{controller_session_timeout_spec.rb → app_root/spec/controller_session_timeout_spec.rb} +5 -4
  54. data/spec/rails3/{controller_spec.rb → app_root/spec/controller_spec.rb} +23 -16
  55. data/spec/rails3/app_root/spec/spec_helper.orig.rb +27 -0
  56. data/spec/rails3/app_root/spec/spec_helper.rb +61 -0
  57. data/spec/rails3/{user_activation_spec.rb → app_root/spec/user_activation_spec.rb} +62 -22
  58. data/spec/rails3/app_root/spec/user_activity_logging_spec.rb +36 -0
  59. data/spec/rails3/app_root/spec/user_brute_force_protection_spec.rb +76 -0
  60. data/spec/rails3/app_root/spec/user_oauth_spec.rb +39 -0
  61. data/spec/rails3/{user_remember_me_spec.rb → app_root/spec/user_remember_me_spec.rb} +4 -4
  62. data/spec/rails3/app_root/spec/user_reset_password_spec.rb +178 -0
  63. data/spec/rails3/{user_spec.rb → app_root/spec/user_spec.rb} +68 -38
  64. metadata +145 -61
  65. data/features/support/env.rb +0 -13
  66. data/lib/sorcery/model/submodules/password_reset.rb +0 -64
  67. data/spec/rails3/app_root/db/migrate/password_reset/20101224223622_add_password_reset_to_users.rb +0 -9
  68. data/spec/rails3/app_root/test/fixtures/users.yml +0 -9
  69. data/spec/rails3/app_root/test/performance/browsing_test.rb +0 -9
  70. data/spec/rails3/app_root/test/test_helper.rb +0 -13
  71. data/spec/rails3/app_root/test/unit/user_test.rb +0 -8
  72. data/spec/rails3/controller_brute_force_protection_spec.rb +0 -72
  73. data/spec/rails3/spec_helper.rb +0 -115
  74. data/spec/rails3/user_password_reset_spec.rb +0 -76
  75. /data/spec/rails3/{Rakefile → app_root/Rakefile} +0 -0
@@ -1,64 +0,0 @@
1
- module Sorcery
2
- module Model
3
- module Submodules
4
- # This submodule adds the ability to reset password via email confirmation.
5
- module PasswordReset
6
- def self.included(base)
7
- base.sorcery_config.class_eval do
8
- attr_accessor :reset_password_code_attribute_name, # reset password code attribute name.
9
- :sorcery_mailer, # mailer class. Needed.
10
- :reset_password_email_method_name # reset password email method on your mailer class.
11
-
12
- end
13
-
14
- base.sorcery_config.instance_eval do
15
- @defaults.merge!(:@reset_password_code_attribute_name => :reset_password_code,
16
- :@sorcery_mailer => nil,
17
- :@reset_password_email_method_name => :reset_password_email)
18
-
19
- reset!
20
- end
21
-
22
- base.class_eval do
23
- clear_reset_password_code_proc = Proc.new do |record|
24
- record.valid? && record.send(sorcery_config.password_attribute_name)
25
- end
26
-
27
- before_save :clear_reset_password_code, :if =>clear_reset_password_code_proc
28
- end
29
-
30
- base.sorcery_config.after_config << :validate_mailer_defined
31
-
32
- base.extend(ClassMethods)
33
- base.send(:include, InstanceMethods)
34
- end
35
-
36
- module ClassMethods
37
- def validate_mailer_defined
38
- msg = "To use password_reset submodule, you must define a mailer (config.sorcery_mailer = YourMailerClass)."
39
- raise ArgumentError, msg if @sorcery_config.sorcery_mailer == nil
40
- end
41
- end
42
-
43
- module InstanceMethods
44
- def reset_password!
45
- config = sorcery_config
46
- self.send(:"#{config.reset_password_code_attribute_name}=", generate_random_code)
47
- self.class.transaction do
48
- self.save!(:validate => false)
49
- generic_send_email(:reset_password_email_method_name)
50
- end
51
- end
52
-
53
- protected
54
-
55
- def clear_reset_password_code
56
- config = sorcery_config
57
- self.send(:"#{config.reset_password_code_attribute_name}=", nil)
58
- end
59
- end
60
-
61
- end
62
- end
63
- end
64
- end
@@ -1,9 +0,0 @@
1
- class AddPasswordResetToUsers < ActiveRecord::Migration
2
- def self.up
3
- add_column :users, :reset_password_code, :string, :default => nil
4
- end
5
-
6
- def self.down
7
- remove_column :users, :reset_password_code
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
-
3
- one:
4
- email: MyString
5
- crypted_password: MyString
6
-
7
- two:
8
- email: MyString
9
- crypted_password: MyString
@@ -1,9 +0,0 @@
1
- require 'test_helper'
2
- require 'rails/performance_test_help'
3
-
4
- # Profiling results for each test method are written to tmp/performance.
5
- class BrowsingTest < ActionDispatch::PerformanceTest
6
- def test_homepage
7
- get '/'
8
- end
9
- end
@@ -1,13 +0,0 @@
1
- ENV["RAILS_ENV"] = "test"
2
- require File.expand_path('../../config/environment', __FILE__)
3
- require 'rails/test_help'
4
-
5
- class ActiveSupport::TestCase
6
- # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
7
- #
8
- # Note: You'll currently still have to declare fixtures explicitly in integration tests
9
- # -- they do not yet inherit this setting
10
- fixtures :all
11
-
12
- # Add more helper methods to be used by all tests here...
13
- end
@@ -1,8 +0,0 @@
1
- require 'test_helper'
2
-
3
- class UserTest < ActiveSupport::TestCase
4
- # Replace this with your real tests.
5
- test "the truth" do
6
- assert true
7
- end
8
- end
@@ -1,72 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe ApplicationController do
4
-
5
- # ----------------- SESSION TIMEOUT -----------------------
6
- describe ApplicationController, "with brute force protection features" do
7
- before(:all) do
8
- plugin_model_configure([:brute_force_protection])
9
- create_new_user
10
- end
11
-
12
- after(:each) do
13
- Sorcery::Controller::Config.reset!
14
- plugin_set_controller_config_property(:user_class, User)
15
- end
16
-
17
- it "should have configuration for 'login_retries_amount_allowed' per session" do
18
- plugin_set_controller_config_property(:login_retries_amount_allowed, 32)
19
- Sorcery::Controller::Config.login_retries_amount_allowed.should equal(32)
20
- end
21
-
22
- it "should have configuration for 'login_retries_counter_reset_time'" do
23
- plugin_set_controller_config_property(:login_retries_time_period, 32)
24
- Sorcery::Controller::Config.login_retries_time_period.should equal(32)
25
- end
26
-
27
- it "should count login retries per session" do
28
- 3.times {get :test_login, :username => 'gizmo', :password => 'blabla'}
29
- session[:failed_logins].should == 3
30
- end
31
-
32
- it "should reset the counter if enough time has passed" do
33
- plugin_set_controller_config_property(:login_retries_amount_allowed, 5)
34
- plugin_set_controller_config_property(:login_retries_time_period, 0.2)
35
- get :test_login, :username => 'gizmo', :password => 'blabla'
36
- sleep 0.4
37
- get :test_login, :username => 'gizmo', :password => 'blabla'
38
- session[:failed_logins].should == 1
39
- end
40
-
41
- it "should ban session when number of retries reached within an amount of time" do
42
- plugin_set_controller_config_property(:login_retries_amount_allowed, 1)
43
- plugin_set_controller_config_property(:login_retries_time_period, 50)
44
- get :test_login, :username => 'gizmo', :password => 'blabla'
45
- get :test_login, :username => 'gizmo', :password => 'blabla'
46
- session[:banned].should == true
47
- end
48
-
49
- it "should clear ban after ban time limit passes" do
50
- plugin_set_controller_config_property(:login_retries_amount_allowed, 1)
51
- plugin_set_controller_config_property(:login_retries_time_period, 50)
52
- plugin_set_controller_config_property(:login_ban_time_period, 0.2)
53
- get :test_login, :username => 'gizmo', :password => 'blabla'
54
- get :test_login, :username => 'gizmo', :password => 'blabla'
55
- session[:banned].should == true
56
- sleep 0.3
57
- get :test_login, :username => 'gizmo', :password => 'blabla'
58
- session[:banned].should == nil
59
- end
60
-
61
- it "banned session calls the configured banned action" do
62
- plugin_set_controller_config_property(:login_retries_amount_allowed, 1)
63
- plugin_set_controller_config_property(:login_retries_time_period, 50)
64
- plugin_set_controller_config_property(:login_ban_time_period, 50)
65
- get :test_login, :username => 'gizmo', :password => 'blabla'
66
- get :test_login, :username => 'gizmo', :password => 'blabla'
67
- get :test_login, :username => 'gizmo', :password => 'blabla'
68
- session[:banned].should == true
69
- response.body.should == " "
70
- end
71
- end
72
- end
@@ -1,115 +0,0 @@
1
- $: << File.join(File.dirname(__FILE__), '..', '..', 'lib' )
2
-
3
- require 'simplecov'
4
- SimpleCov.root File.join(File.dirname(__FILE__), "app_root" )
5
- SimpleCov.start do
6
- add_filter "/config/"
7
-
8
- add_group 'Controllers', 'app/controllers'
9
- add_group 'Models', 'app/models'
10
- add_group 'Helpers', 'app/helpers'
11
- add_group 'Libraries', 'lib'
12
- add_group 'Plugins', 'vendor/plugins'
13
- add_group 'Migrations', 'db/migrate'
14
- end
15
-
16
- # Set the default environment to sqlite3's in_memory database
17
- ENV['RAILS_ENV'] ||= 'in_memory'
18
- ENV['RAILS_ROOT'] = 'app_root'
19
-
20
- # Load the Rails environment and testing framework
21
- require "#{File.dirname(__FILE__)}/app_root/config/environment"
22
- #require "#{File.dirname(__FILE__)}/../../init" # for plugins
23
- require 'rspec/rails'
24
- #require 'sorcery'
25
-
26
- # Undo changes to RAILS_ENV
27
- silence_warnings {RAILS_ENV = ENV['RAILS_ENV']}
28
-
29
- RSpec.configure do |config|
30
- config.use_transactional_fixtures = true
31
- config.use_instantiated_fixtures = false
32
- config.include RSpec::Rails::ControllerExampleGroup, :example_group => { :file_path => /controller(.)*_spec.rb$/ }#:file_path => /\bspec[\\\/]controllers[\\\/]/ }
33
-
34
- config.before(:suite) do
35
- ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/core")
36
- end
37
-
38
- config.after(:suite) do
39
- ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/core")
40
- end
41
- end
42
-
43
- #----------------------------------------------------------------
44
- #require File.join(File.dirname(__FILE__), 'app_root','app','models','user')
45
-
46
- class TestUser < ActiveRecord::Base
47
- activate_sorcery!
48
- end
49
-
50
- class TestMailer < ActionMailer::Base
51
-
52
- end
53
-
54
- module Sorcery
55
- module Model
56
- module Submodules
57
- module TestSubmodule
58
- def my_instance_method
59
- end
60
- end
61
- end
62
- end
63
- end
64
-
65
- def create_new_user
66
- user_attributes_hash = {:username => 'gizmo', :email => "bla@bla.com", :password => 'secret'}
67
- @user = User.new(user_attributes_hash)
68
- @user.save!
69
- end
70
-
71
- def login_user
72
- subject.send(:login_user,@user)
73
- subject.send(:after_login!,@user,['gizmo','secret'])
74
- end
75
-
76
- # TODO: rename to sorcery_reload!(subs = [], model_opts = {}, controller_opts = {})
77
- def plugin_model_configure(submodules = [], options = {})
78
- reload_user_class
79
-
80
- # return to no-module configuration
81
- ::Sorcery::Controller::Config.init!
82
- ::Sorcery::Controller::Config.reset!
83
-
84
- # configure
85
- ::Sorcery::Controller::Config.submodules = submodules
86
- ::Sorcery::Controller::Config.user_class = nil # the next line will reset it to User
87
- ApplicationController.send(:include,::Sorcery::Controller)
88
-
89
- User.activate_sorcery! do |config|
90
- options.each do |property,value|
91
- config.send(:"#{property}=", value)
92
- end
93
- end
94
- end
95
-
96
- # TODO: rename to sorcery_model_property_set(prop, val)
97
- def plugin_set_model_config_property(property, *values)
98
- User.class_eval do
99
- sorcery_config.send(:"#{property}=", *values)
100
- end
101
- end
102
-
103
- # TODO: rename to sorcery_controller_property_set(prop, val)
104
- def plugin_set_controller_config_property(property, value)
105
- ApplicationController.activate_sorcery! do |config|
106
- config.send(:"#{property}=", value)
107
- end
108
- end
109
-
110
- private
111
-
112
- def reload_user_class
113
- Object.send(:remove_const,:User)
114
- load 'user.rb'
115
- end
@@ -1,76 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe "User with password_reset submodule" do
4
- before(:all) do
5
- ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/password_reset")
6
- end
7
-
8
- after(:all) do
9
- ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/password_reset")
10
- end
11
-
12
- # ----------------- PLUGIN CONFIGURATION -----------------------
13
- describe User, "loaded plugin configuration" do
14
-
15
- before(:all) do
16
- plugin_model_configure([:password_reset], :sorcery_mailer => ::SorceryMailer)
17
- end
18
-
19
- after(:each) do
20
- User.sorcery_config.reset!
21
- end
22
-
23
- it "should respond to 'reset_password!'" do
24
- create_new_user
25
- @user.should respond_to(:reset_password!)
26
- end
27
- end
28
-
29
- # ----------------- PLUGIN ACTIVATED -----------------------
30
- describe User, "when activated with sorcery" do
31
-
32
- before(:all) do
33
- plugin_model_configure([:password_reset], :sorcery_mailer => ::SorceryMailer)
34
- end
35
-
36
- before(:each) do
37
- User.delete_all
38
- end
39
-
40
- it "'reset_password!' should generate a reset_password_code" do
41
- create_new_user
42
- @user.reset_password_code.should be_nil
43
- @user.reset_password!
44
- @user.reset_password_code.should_not be_nil
45
- end
46
-
47
- it "the reset_password_code should be random" do
48
- create_new_user
49
- @user.reset_password!
50
- old_password_code = @user.reset_password_code
51
- @user.reset_password!
52
- @user.reset_password_code.should_not == old_password_code
53
- end
54
-
55
- it "should send an email on reset" do
56
- create_new_user
57
- old_size = ActionMailer::Base.deliveries.size
58
- @user.reset_password!
59
- ActionMailer::Base.deliveries.size.should == old_size + 1
60
- end
61
-
62
- it "when a new password is set, should delete reset_password_code" do
63
- create_new_user
64
- @user.reset_password!
65
- @user.reset_password_code.should_not be_nil
66
- @user.password = "blabulsdf"
67
- @user.save!
68
- @user.reset_password_code.should be_nil
69
- end
70
-
71
- it "if mailer is nil on activation, throw exception!" do
72
- expect{plugin_model_configure([:password_reset])}.to raise_error(ArgumentError)
73
- end
74
- end
75
-
76
- end
File without changes