cbsorcery 0.8.6

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 (135) hide show
  1. data/.document +5 -0
  2. data/.gitignore +56 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +40 -0
  5. data/CHANGELOG.md +263 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.md +360 -0
  9. data/Rakefile +6 -0
  10. data/gemfiles/active_record-rails40.gemfile +7 -0
  11. data/gemfiles/active_record-rails41.gemfile +7 -0
  12. data/lib/generators/sorcery/USAGE +22 -0
  13. data/lib/generators/sorcery/helpers.rb +40 -0
  14. data/lib/generators/sorcery/install_generator.rb +95 -0
  15. data/lib/generators/sorcery/templates/initializer.rb +451 -0
  16. data/lib/generators/sorcery/templates/migration/activity_logging.rb +10 -0
  17. data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +9 -0
  18. data/lib/generators/sorcery/templates/migration/core.rb +13 -0
  19. data/lib/generators/sorcery/templates/migration/external.rb +12 -0
  20. data/lib/generators/sorcery/templates/migration/remember_me.rb +8 -0
  21. data/lib/generators/sorcery/templates/migration/reset_password.rb +9 -0
  22. data/lib/generators/sorcery/templates/migration/user_activation.rb +9 -0
  23. data/lib/sorcery.rb +85 -0
  24. data/lib/sorcery/adapters/active_record_adapter.rb +120 -0
  25. data/lib/sorcery/adapters/base_adapter.rb +30 -0
  26. data/lib/sorcery/controller.rb +157 -0
  27. data/lib/sorcery/controller/config.rb +65 -0
  28. data/lib/sorcery/controller/submodules/activity_logging.rb +82 -0
  29. data/lib/sorcery/controller/submodules/brute_force_protection.rb +38 -0
  30. data/lib/sorcery/controller/submodules/external.rb +199 -0
  31. data/lib/sorcery/controller/submodules/http_basic_auth.rb +74 -0
  32. data/lib/sorcery/controller/submodules/remember_me.rb +81 -0
  33. data/lib/sorcery/controller/submodules/session_timeout.rb +56 -0
  34. data/lib/sorcery/crypto_providers/aes256.rb +51 -0
  35. data/lib/sorcery/crypto_providers/bcrypt.rb +97 -0
  36. data/lib/sorcery/crypto_providers/common.rb +35 -0
  37. data/lib/sorcery/crypto_providers/md5.rb +19 -0
  38. data/lib/sorcery/crypto_providers/sha1.rb +28 -0
  39. data/lib/sorcery/crypto_providers/sha256.rb +36 -0
  40. data/lib/sorcery/crypto_providers/sha512.rb +36 -0
  41. data/lib/sorcery/engine.rb +21 -0
  42. data/lib/sorcery/model.rb +183 -0
  43. data/lib/sorcery/model/config.rb +96 -0
  44. data/lib/sorcery/model/submodules/activity_logging.rb +70 -0
  45. data/lib/sorcery/model/submodules/brute_force_protection.rb +125 -0
  46. data/lib/sorcery/model/submodules/external.rb +100 -0
  47. data/lib/sorcery/model/submodules/remember_me.rb +62 -0
  48. data/lib/sorcery/model/submodules/reset_password.rb +131 -0
  49. data/lib/sorcery/model/submodules/user_activation.rb +149 -0
  50. data/lib/sorcery/model/temporary_token.rb +30 -0
  51. data/lib/sorcery/protocols/certs/ca-bundle.crt +5182 -0
  52. data/lib/sorcery/protocols/oauth.rb +42 -0
  53. data/lib/sorcery/protocols/oauth2.rb +47 -0
  54. data/lib/sorcery/providers/base.rb +27 -0
  55. data/lib/sorcery/providers/facebook.rb +63 -0
  56. data/lib/sorcery/providers/github.rb +51 -0
  57. data/lib/sorcery/providers/google.rb +51 -0
  58. data/lib/sorcery/providers/jira.rb +77 -0
  59. data/lib/sorcery/providers/linkedin.rb +66 -0
  60. data/lib/sorcery/providers/liveid.rb +53 -0
  61. data/lib/sorcery/providers/twitter.rb +59 -0
  62. data/lib/sorcery/providers/vk.rb +63 -0
  63. data/lib/sorcery/providers/xing.rb +64 -0
  64. data/lib/sorcery/railties/tasks.rake +6 -0
  65. data/lib/sorcery/test_helpers/internal.rb +78 -0
  66. data/lib/sorcery/test_helpers/internal/rails.rb +68 -0
  67. data/lib/sorcery/test_helpers/rails/controller.rb +21 -0
  68. data/lib/sorcery/test_helpers/rails/integration.rb +26 -0
  69. data/lib/sorcery/version.rb +3 -0
  70. data/sorcery.gemspec +34 -0
  71. data/spec/active_record/user_activation_spec.rb +18 -0
  72. data/spec/active_record/user_activity_logging_spec.rb +17 -0
  73. data/spec/active_record/user_brute_force_protection_spec.rb +16 -0
  74. data/spec/active_record/user_oauth_spec.rb +16 -0
  75. data/spec/active_record/user_remember_me_spec.rb +16 -0
  76. data/spec/active_record/user_reset_password_spec.rb +16 -0
  77. data/spec/active_record/user_spec.rb +37 -0
  78. data/spec/controllers/controller_activity_logging_spec.rb +124 -0
  79. data/spec/controllers/controller_brute_force_protection_spec.rb +43 -0
  80. data/spec/controllers/controller_http_basic_auth_spec.rb +68 -0
  81. data/spec/controllers/controller_oauth2_spec.rb +407 -0
  82. data/spec/controllers/controller_oauth_spec.rb +240 -0
  83. data/spec/controllers/controller_remember_me_spec.rb +117 -0
  84. data/spec/controllers/controller_session_timeout_spec.rb +80 -0
  85. data/spec/controllers/controller_spec.rb +215 -0
  86. data/spec/orm/active_record.rb +21 -0
  87. data/spec/rails_app/app/active_record/authentication.rb +3 -0
  88. data/spec/rails_app/app/active_record/user.rb +5 -0
  89. data/spec/rails_app/app/active_record/user_provider.rb +3 -0
  90. data/spec/rails_app/app/controllers/sorcery_controller.rb +265 -0
  91. data/spec/rails_app/app/helpers/application_helper.rb +2 -0
  92. data/spec/rails_app/app/mailers/sorcery_mailer.rb +32 -0
  93. data/spec/rails_app/app/views/application/index.html.erb +17 -0
  94. data/spec/rails_app/app/views/layouts/application.html.erb +14 -0
  95. data/spec/rails_app/app/views/sorcery_mailer/activation_email.html.erb +17 -0
  96. data/spec/rails_app/app/views/sorcery_mailer/activation_email.text.erb +9 -0
  97. data/spec/rails_app/app/views/sorcery_mailer/activation_needed_email.html.erb +17 -0
  98. data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
  99. data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
  100. data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
  101. data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
  102. data/spec/rails_app/app/views/sorcery_mailer/send_unlock_token_email.text.erb +1 -0
  103. data/spec/rails_app/config.ru +4 -0
  104. data/spec/rails_app/config/application.rb +56 -0
  105. data/spec/rails_app/config/boot.rb +4 -0
  106. data/spec/rails_app/config/database.yml +22 -0
  107. data/spec/rails_app/config/environment.rb +5 -0
  108. data/spec/rails_app/config/environments/test.rb +37 -0
  109. data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  110. data/spec/rails_app/config/initializers/inflections.rb +10 -0
  111. data/spec/rails_app/config/initializers/mime_types.rb +5 -0
  112. data/spec/rails_app/config/initializers/secret_token.rb +7 -0
  113. data/spec/rails_app/config/initializers/session_store.rb +12 -0
  114. data/spec/rails_app/config/locales/en.yml +5 -0
  115. data/spec/rails_app/config/routes.rb +48 -0
  116. data/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +17 -0
  117. data/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +19 -0
  118. data/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +13 -0
  119. data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +16 -0
  120. data/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +22 -0
  121. data/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
  122. data/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
  123. data/spec/rails_app/db/schema.rb +23 -0
  124. data/spec/rails_app/db/seeds.rb +7 -0
  125. data/spec/shared_examples/user_activation_shared_examples.rb +242 -0
  126. data/spec/shared_examples/user_activity_logging_shared_examples.rb +97 -0
  127. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +156 -0
  128. data/spec/shared_examples/user_oauth_shared_examples.rb +36 -0
  129. data/spec/shared_examples/user_remember_me_shared_examples.rb +57 -0
  130. data/spec/shared_examples/user_reset_password_shared_examples.rb +263 -0
  131. data/spec/shared_examples/user_shared_examples.rb +467 -0
  132. data/spec/sorcery_crypto_providers_spec.rb +198 -0
  133. data/spec/spec.opts +2 -0
  134. data/spec/spec_helper.rb +41 -0
  135. metadata +350 -0
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
5
+ </head>
6
+ <body>
7
+ <h1>Hello, <%= @user.username %></h1>
8
+ <p>
9
+ You have requested to reset your password.
10
+ </p>
11
+ <p>
12
+ To choose a new password, just follow this link: <%= @url %>.
13
+ </p>
14
+ <p>Have a great day!</p>
15
+ </body>
16
+ </html>
@@ -0,0 +1,8 @@
1
+ Hello, <%= @user.username %>
2
+ ===============================================
3
+
4
+ You have requested to reset your password.
5
+
6
+ To choose a new password, just follow this link: <%= @url %>.
7
+
8
+ Have a great day!
@@ -0,0 +1 @@
1
+ Please visit <%= @url %> for unlock your account.
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run RailsApp::Application
@@ -0,0 +1,56 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require "action_controller/railtie"
4
+ require "action_mailer/railtie"
5
+ require "rails/test_unit/railtie"
6
+
7
+ Bundler.require :default, SORCERY_ORM
8
+
9
+ begin
10
+ require "#{SORCERY_ORM}/railtie"
11
+ rescue LoadError
12
+ end
13
+
14
+ require "sorcery"
15
+
16
+ module AppRoot
17
+ class Application < Rails::Application
18
+ config.autoload_paths.reject!{ |p| p =~ /\/app\/(\w+)$/ && !%w(controllers helpers mailers views).include?($1) }
19
+ config.autoload_paths += [ "#{config.root}/app/#{SORCERY_ORM}" ]
20
+
21
+ # Settings in config/environments/* take precedence over those specified here.
22
+ # Application configuration should go into files in config/initializers
23
+ # -- all .rb files in that directory are automatically loaded.
24
+
25
+ # Custom directories with classes and modules you want to be autoloadable.
26
+ # config.autoload_paths += %W(#{config.root}/extras)
27
+
28
+ # Only load the plugins named here, in the order given (default is alphabetical).
29
+ # :all can be used as a placeholder for all plugins not explicitly named.
30
+ # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
31
+
32
+ # Activate observers that should always be running.
33
+ # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
34
+
35
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
36
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
37
+ # config.time_zone = 'Central Time (US & Canada)'
38
+
39
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
40
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
41
+ # config.i18n.default_locale = :de
42
+
43
+ # JavaScript files you want as :defaults (application.js is always included).
44
+ # config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
45
+
46
+ # Configure the default encoding used in templates for Ruby 1.9.
47
+ config.encoding = "utf-8"
48
+
49
+ # Configure sensitive parameters which will be filtered from the log file.
50
+ config.filter_parameters += [:password]
51
+
52
+ config.action_mailer.delivery_method = :test
53
+
54
+ config.active_support.deprecation = :stderr
55
+ end
56
+ end
@@ -0,0 +1,4 @@
1
+ # Set up gems listed in the Gemfile.
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
@@ -0,0 +1,22 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3-ruby (not necessary on OS X Leopard)
3
+ development:
4
+ adapter: sqlite3
5
+ database: db/development.sqlite3
6
+ pool: 5
7
+ timeout: 5000
8
+
9
+ # Warning: The database defined as "test" will be erased and
10
+ # re-generated from your development database when you run "rake".
11
+ # Do not set this db to the same as development or production.
12
+ test:
13
+ adapter: sqlite3
14
+ database: db/test.sqlite3
15
+ pool: 5
16
+ timeout: 5000
17
+ # adapter: sqlite3
18
+ # database: ":memory:"
19
+
20
+ production:
21
+ adapter: sqlite3
22
+ database: ":memory:"
@@ -0,0 +1,5 @@
1
+ # Load the rails application
2
+ require File.expand_path('../application', __FILE__)
3
+
4
+ # Initialize the rails application
5
+ AppRoot::Application.initialize!
@@ -0,0 +1,37 @@
1
+ AppRoot::Application.configure do
2
+ # Settings specified here will take precedence over those in config/application.rb
3
+
4
+ # The test environment is used exclusively to run your application's
5
+ # test suite. You never need to work with it otherwise. Remember that
6
+ # your test database is "scratch space" for the test suite and is wiped
7
+ # and recreated between test runs. Don't rely on the data there!
8
+ config.cache_classes = true
9
+
10
+ # Log error messages when you accidentally call methods on nil.
11
+ config.whiny_nils = true
12
+
13
+ # Show full error reports and disable caching
14
+ config.consider_all_requests_local = true
15
+ config.action_controller.perform_caching = false
16
+
17
+ # Raise exceptions instead of rendering exception templates
18
+ config.action_dispatch.show_exceptions = false
19
+
20
+ # Disable request forgery protection in test environment
21
+ config.action_controller.allow_forgery_protection = false
22
+
23
+ # Tell Action Mailer not to deliver emails to the real world.
24
+ # The :test delivery method accumulates sent emails in the
25
+ # ActionMailer::Base.deliveries array.
26
+ config.action_mailer.delivery_method = :test
27
+
28
+ # Use SQL instead of Active Record's schema dumper when creating the test database.
29
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
30
+ # like if you have constraints or database-specific column types
31
+ # config.active_record.schema_format = :sql
32
+
33
+ # Print deprecation notices to the stderr
34
+ config.active_support.deprecation = :stderr
35
+
36
+ config.eager_load = false
37
+ end
@@ -0,0 +1,7 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4
+ # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5
+
6
+ # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7
+ # Rails.backtrace_cleaner.remove_silencers!
@@ -0,0 +1,10 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new inflection rules using the following format
4
+ # (all these examples are active by default):
5
+ # ActiveSupport::Inflector.inflections do |inflect|
6
+ # inflect.plural /^(ox)$/i, '\1en'
7
+ # inflect.singular /^(ox)en/i, '\1'
8
+ # inflect.irregular 'person', 'people'
9
+ # inflect.uncountable %w( fish sheep )
10
+ # end
@@ -0,0 +1,5 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new mime types for use in respond_to blocks:
4
+ # Mime::Type.register "text/richtext", :rtf
5
+ # Mime::Type.register_alias "text/html", :iphone
@@ -0,0 +1,7 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Your secret key for verifying the integrity of signed cookies.
4
+ # If you change this key, all old signed cookies will become invalid!
5
+ # Make sure the secret is at least 30 characters and all random,
6
+ # no regular words or you'll be exposed to dictionary attacks.
7
+ AppRoot::Application.config.secret_token = 'a9789f869a0d0ac2f2b683d6e9410c530696b178bca28a7971f4a652b14ff2da89f2cf4dcbf0355f6bc41f81731aa8e46085674d1acc1980436f61cdba76ff5d'
@@ -0,0 +1,12 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ AppRoot::Application.config.session_store :cookie_store, :key => '_app_root_session'
4
+
5
+ # Use the database for sessions instead of the cookie-based default,
6
+ # which shouldn't be used to store highly confidential information
7
+ # (create the session table with "rails generate session_migration")
8
+ # AppRoot::Application.config.session_store :active_record_store
9
+
10
+ if AppRoot::Application.config.respond_to?(:secret_key_base=)
11
+ AppRoot::Application.config.secret_key_base = "foobar"
12
+ end
@@ -0,0 +1,5 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ hello: "Hello world"
@@ -0,0 +1,48 @@
1
+ AppRoot::Application.routes.draw do
2
+ root :to => "application#index"
3
+
4
+ controller :sorcery do
5
+ get :test_login
6
+ get :test_logout
7
+ get :some_action
8
+ post :test_return_to
9
+ get :test_auto_login
10
+ post :test_login_with_remember_in_login
11
+ get :test_login_from_cookie
12
+ get :test_login_from
13
+ get :test_logout_with_remember
14
+ get :test_should_be_logged_in
15
+ get :test_create_from_provider
16
+ get :test_add_second_provider
17
+ get :test_return_to_with_external
18
+ get :test_login_from
19
+ get :test_login_from_twitter
20
+ get :test_login_from_facebook
21
+ get :test_login_from_github
22
+ get :test_login_from_google
23
+ get :test_login_from_liveid
24
+ get :test_login_from_vk
25
+ get :test_login_from_jira
26
+ get :login_at_test
27
+ get :login_at_test_twitter
28
+ get :login_at_test_facebook
29
+ get :login_at_test_github
30
+ get :login_at_test_google
31
+ get :login_at_test_liveid
32
+ get :login_at_test_vk
33
+ get :login_at_test_jira
34
+ get :test_return_to_with_external
35
+ get :test_return_to_with_external_twitter
36
+ get :test_return_to_with_external_facebook
37
+ get :test_return_to_with_external_github
38
+ get :test_return_to_with_external_google
39
+ get :test_return_to_with_external_liveid
40
+ get :test_return_to_with_external_vk
41
+ get :test_return_to_with_external_jira
42
+ get :test_http_basic_auth
43
+ get :some_action_making_a_non_persisted_change_to_the_user
44
+ post :test_login_with_remember
45
+ get :test_create_from_provider_with_block
46
+ get :login_at_test_with_state
47
+ end
48
+ end
@@ -0,0 +1,17 @@
1
+ class AddActivationToUsers < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :users, :activation_state, :string, :default => nil
4
+ add_column :users, :activation_token, :string, :default => nil
5
+ add_column :users, :activation_token_expires_at, :datetime, :default => nil
6
+
7
+ add_index :users, :activation_token
8
+ end
9
+
10
+ def self.down
11
+ remove_index :users, :activation_token
12
+
13
+ remove_column :users, :activation_token_expires_at
14
+ remove_column :users, :activation_token
15
+ remove_column :users, :activation_state
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ class AddActivityLoggingToUsers < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :users, :last_login_at, :datetime, :default => nil
4
+ add_column :users, :last_logout_at, :datetime, :default => nil
5
+ add_column :users, :last_activity_at, :datetime, :default => nil
6
+ add_column :users, :last_login_from_ip_address, :string, :default => nil
7
+
8
+ add_index :users, [:last_logout_at, :last_activity_at]
9
+ end
10
+
11
+ def self.down
12
+ remove_index :users, [:last_logout_at, :last_activity_at]
13
+
14
+ remove_column :users, :last_activity_at
15
+ remove_column :users, :last_logout_at
16
+ remove_column :users, :last_login_at
17
+ remove_column :users, :last_login_from_ip_address
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ class AddBruteForceProtectionToUsers < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :users, :failed_logins_count, :integer, :default => 0
4
+ add_column :users, :lock_expires_at, :datetime, :default => nil
5
+ add_column :users, :unlock_token, :string, :default => nil
6
+ end
7
+
8
+ def self.down
9
+ remove_column :users, :unlock_token
10
+ remove_column :users, :lock_expires_at
11
+ remove_column :users, :failed_logins_count
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.string :username, :null => false
5
+ t.string :email, :default => nil
6
+ t.string :crypted_password, :default => nil
7
+ t.string :salt, :default => nil
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :users
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ class CreateAuthenticationsAndUserProviders < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :authentications do |t|
4
+ t.integer :user_id, null: false
5
+ t.string :provider, :uid, null: false
6
+
7
+ t.timestamps
8
+ end
9
+
10
+ create_table :user_providers do |t|
11
+ t.integer :user_id, null: false
12
+ t.string :provider, :uid, null: false
13
+
14
+ t.timestamps
15
+ end
16
+ end
17
+
18
+ def self.down
19
+ drop_table :authentications
20
+ drop_table :user_providers
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ class AddRememberMeTokenToUsers < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :users, :remember_me_token, :string, :default => nil
4
+ add_column :users, :remember_me_token_expires_at, :datetime, :default => nil
5
+
6
+ add_index :users, :remember_me_token
7
+ end
8
+
9
+ def self.down
10
+ remove_index :users, :remember_me_token
11
+
12
+ remove_column :users, :remember_me_token_expires_at
13
+ remove_column :users, :remember_me_token
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ class AddResetPasswordToUsers < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :users, :reset_password_token, :string, :default => nil
4
+ add_column :users, :reset_password_token_expires_at, :datetime, :default => nil
5
+ add_column :users, :reset_password_email_sent_at, :datetime, :default => nil
6
+ end
7
+
8
+ def self.down
9
+ remove_column :users, :reset_password_email_sent_at
10
+ remove_column :users, :reset_password_token_expires_at
11
+ remove_column :users, :reset_password_token
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ # This file is auto-generated from the current state of the database. Instead
2
+ # of editing this file, please use the migrations feature of Active Record to
3
+ # incrementally modify your database, and then regenerate this schema definition.
4
+ #
5
+ # Note that this schema.rb definition is the authoritative source for your
6
+ # database schema. If you need to create the application database on another
7
+ # system, you should be using db:schema:load, not running all the migrations
8
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
10
+ #
11
+ # It's strongly recommended to check this file into your version control system.
12
+
13
+ ActiveRecord::Schema.define(:version => 20101224223620) do
14
+
15
+ create_table "users", :force => true do |t|
16
+ t.string "username"
17
+ t.string "email"
18
+ t.string "crypted_password"
19
+ t.datetime "created_at"
20
+ t.datetime "updated_at"
21
+ end
22
+
23
+ end
@@ -0,0 +1,7 @@
1
+ # This file should contain all the record creation needed to seed the database with its default values.
2
+ # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
3
+ #
4
+ # Examples:
5
+ #
6
+ # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
7
+ # Mayor.create(:name => 'Daley', :city => cities.first)
@@ -0,0 +1,242 @@
1
+ shared_examples_for "rails_3_activation_model" do
2
+ let(:user) { create_new_user }
3
+ let(:new_user) { build_new_user }
4
+
5
+ context "loaded plugin configuration" do
6
+ before(:all) do
7
+ sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
8
+ end
9
+
10
+ after(:each) do
11
+ User.sorcery_config.reset!
12
+ sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
13
+ end
14
+
15
+ it "enables configuration option 'activation_state_attribute_name'" do
16
+ sorcery_model_property_set(:activation_state_attribute_name, :status)
17
+
18
+ expect(User.sorcery_config.activation_state_attribute_name).to eq :status
19
+ end
20
+
21
+ it "enables configuration option 'activation_token_attribute_name'" do
22
+ sorcery_model_property_set(:activation_token_attribute_name, :code)
23
+
24
+ expect(User.sorcery_config.activation_token_attribute_name).to eql :code
25
+ end
26
+
27
+ it "enables configuration option 'user_activation_mailer'" do
28
+ sorcery_model_property_set(:user_activation_mailer, TestMailer)
29
+
30
+ expect(User.sorcery_config.user_activation_mailer).to equal(TestMailer)
31
+ end
32
+
33
+ it "enables configuration option 'activation_needed_email_method_name'" do
34
+ sorcery_model_property_set(:activation_needed_email_method_name, :my_activation_email)
35
+
36
+ expect(User.sorcery_config.activation_needed_email_method_name).to eq :my_activation_email
37
+ end
38
+
39
+ it "enables configuration option 'activation_success_email_method_name'" do
40
+ sorcery_model_property_set(:activation_success_email_method_name, :my_activation_email)
41
+
42
+ expect(User.sorcery_config.activation_success_email_method_name).to eq :my_activation_email
43
+ end
44
+
45
+ it "enables configuration option 'activation_mailer_disabled'" do
46
+ sorcery_model_property_set(:activation_mailer_disabled, :my_activation_mailer_disabled)
47
+
48
+ expect(User.sorcery_config.activation_mailer_disabled).to eq :my_activation_mailer_disabled
49
+ end
50
+
51
+ it "if mailer is nil and mailer is enabled, throw exception!" do
52
+ expect{sorcery_reload!([:user_activation], :activation_mailer_disabled => false)}.to raise_error(ArgumentError)
53
+ end
54
+
55
+ it "if mailer is disabled and mailer is nil, do NOT throw exception" do
56
+ expect{sorcery_reload!([:user_activation], :activation_mailer_disabled => true)}.to_not raise_error
57
+ end
58
+ end
59
+
60
+
61
+ context "activation process" do
62
+ before(:all) do
63
+ sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
64
+ end
65
+
66
+ it "initializes user state to 'pending'" do
67
+ expect(user.activation_state).to eq "pending"
68
+ end
69
+
70
+ specify { expect(user).to respond_to :activate! }
71
+
72
+ it "clears activation code and change state to 'active' on activation" do
73
+ activation_token = user.activation_token
74
+ user.activate!
75
+ user2 = User.sorcery_adapter.find(user.id) # go to db to make sure it was saved and not just in memory
76
+
77
+ expect(user2.activation_token).to be_nil
78
+ expect(user2.activation_state).to eq "active"
79
+ expect(User.sorcery_adapter.find_by_activation_token activation_token).to be_nil
80
+ end
81
+
82
+
83
+ context "mailer is enabled" do
84
+ it "sends the user an activation email" do
85
+ old_size = ActionMailer::Base.deliveries.size
86
+ create_new_user
87
+
88
+ expect(ActionMailer::Base.deliveries.size).to eq old_size + 1
89
+ end
90
+
91
+ it "calls send_activation_needed_email! method of user" do
92
+ expect(new_user).to receive(:send_activation_needed_email!).once
93
+
94
+ new_user.sorcery_adapter.save(:raise_on_failure => true)
95
+ end
96
+
97
+ it "subsequent saves do not send activation email" do
98
+ user
99
+ old_size = ActionMailer::Base.deliveries.size
100
+ user.email = "Shauli"
101
+ user.sorcery_adapter.save(:raise_on_failure => true)
102
+
103
+ expect(ActionMailer::Base.deliveries.size).to eq old_size
104
+ end
105
+
106
+ it "sends the user an activation success email on successful activation" do
107
+ user
108
+ old_size = ActionMailer::Base.deliveries.size
109
+ user.activate!
110
+
111
+ expect(ActionMailer::Base.deliveries.size).to eq old_size + 1
112
+ end
113
+
114
+ it "calls send_activation_success_email! method of user on activation" do
115
+ expect(user).to receive(:send_activation_success_email!).once
116
+
117
+ user.activate!
118
+ end
119
+
120
+ it "subsequent saves do not send activation success email" do
121
+ user.activate!
122
+ old_size = ActionMailer::Base.deliveries.size
123
+ user.email = "Shauli"
124
+ user.sorcery_adapter.save(:raise_on_failure => true)
125
+
126
+ expect(ActionMailer::Base.deliveries.size).to eq old_size
127
+ end
128
+
129
+ it "activation needed email is optional" do
130
+ sorcery_model_property_set(:activation_needed_email_method_name, nil)
131
+ old_size = ActionMailer::Base.deliveries.size
132
+
133
+ expect(ActionMailer::Base.deliveries.size).to eq old_size
134
+ end
135
+
136
+ it "activation success email is optional" do
137
+ sorcery_model_property_set(:activation_success_email_method_name, nil)
138
+ old_size = ActionMailer::Base.deliveries.size
139
+ user.activate!
140
+
141
+ expect(ActionMailer::Base.deliveries.size).to eq old_size
142
+ end
143
+ end
144
+
145
+ context "mailer has been disabled" do
146
+ before(:each) do
147
+ sorcery_reload!([:user_activation], :activation_mailer_disabled => true, :user_activation_mailer => ::SorceryMailer)
148
+ end
149
+
150
+ it "does not send the user an activation email" do
151
+ old_size = ActionMailer::Base.deliveries.size
152
+
153
+ expect(ActionMailer::Base.deliveries.size).to eq old_size
154
+ end
155
+
156
+ it "does not call send_activation_needed_email! method of user" do
157
+ user = build_new_user
158
+
159
+ expect(user).to receive(:send_activation_needed_email!).never
160
+
161
+ user.sorcery_adapter.save(:raise_on_failure => true)
162
+ end
163
+
164
+ it "does not send the user an activation success email on successful activation" do
165
+ old_size = ActionMailer::Base.deliveries.size
166
+ user.activate!
167
+
168
+ expect(ActionMailer::Base.deliveries.size).to eq old_size
169
+ end
170
+
171
+ it "calls send_activation_success_email! method of user on activation" do
172
+ expect(user).to receive(:send_activation_success_email!).never
173
+
174
+ user.activate!
175
+ end
176
+ end
177
+ end
178
+
179
+ describe "prevent non-active login feature" do
180
+ before(:all) do
181
+ sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
182
+ end
183
+
184
+ before(:each) do
185
+ User.sorcery_adapter.delete_all
186
+ end
187
+
188
+ it "does not allow a non-active user to authenticate" do
189
+ expect(User.authenticate user.email, 'secret').to be_falsy
190
+ end
191
+
192
+ it "allows a non-active user to authenticate if configured so" do
193
+ sorcery_model_property_set(:prevent_non_active_users_to_login, false)
194
+
195
+ expect(User.authenticate user.email, 'secret').to be_truthy
196
+ end
197
+ end
198
+
199
+ describe "load_from_activation_token" do
200
+ before(:all) do
201
+ sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
202
+ end
203
+
204
+ after(:each) do
205
+ Timecop.return
206
+ end
207
+
208
+ it "load_from_activation_token returns user when token is found" do
209
+ expect(User.load_from_activation_token user.activation_token).to eq user
210
+ end
211
+
212
+ it "load_from_activation_token does NOT return user when token is NOT found" do
213
+ expect(User.load_from_activation_token "a").to be_nil
214
+ end
215
+
216
+ it "load_from_activation_token returas user when token is found and not expired" do
217
+ sorcery_model_property_set(:activation_token_expiration_period, 500)
218
+
219
+ expect(User.load_from_activation_token user.activation_token).to eq user
220
+ end
221
+
222
+ it "load_from_activation_token does NOT return user when token is found and expired" do
223
+ sorcery_model_property_set(:activation_token_expiration_period, 0.1)
224
+ user
225
+
226
+ Timecop.travel(Time.now.in_time_zone+0.5)
227
+
228
+ expect(User.load_from_activation_token user.activation_token).to be_nil
229
+ end
230
+
231
+ it "load_from_activation_token returns nil if token is blank" do
232
+ expect(User.load_from_activation_token nil).to be_nil
233
+ expect(User.load_from_activation_token "").to be_nil
234
+ end
235
+
236
+ it "load_from_activation_token is always valid if expiration period is nil" do
237
+ sorcery_model_property_set(:activation_token_expiration_period, nil)
238
+
239
+ expect(User.load_from_activation_token user.activation_token).to eq user
240
+ end
241
+ end
242
+ end