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,59 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with Twitter.com.
4
+ #
5
+ # config.twitter.key = <key>
6
+ # config.twitter.secret = <secret>
7
+ # ...
8
+ #
9
+ class Twitter < Base
10
+
11
+ include Protocols::Oauth
12
+
13
+ attr_accessor :state, :user_info_path
14
+
15
+ def initialize
16
+ super
17
+
18
+ @site = 'https://api.twitter.com'
19
+ @user_info_path = '/1.1/account/verify_credentials.json'
20
+ end
21
+
22
+ # Override included get_consumer method to provide authorize_path
23
+ def get_consumer
24
+ ::OAuth::Consumer.new(@key, secret, site: site, authorize_path: '/oauth/authenticate')
25
+ end
26
+
27
+ def get_user_hash(access_token)
28
+ response = access_token.get(user_info_path)
29
+
30
+ {}.tap do |h|
31
+ h[:user_info] = JSON.parse(response.body)
32
+ h[:uid] = h[:user_info]['id'].to_s
33
+ end
34
+ end
35
+
36
+ # calculates and returns the url to which the user should be redirected,
37
+ # to get authenticated at the external provider's site.
38
+ def login_url(params, session)
39
+ req_token = self.get_request_token
40
+ session[:request_token] = req_token.token
41
+ session[:request_token_secret] = req_token.secret
42
+ self.authorize_url({ request_token: req_token.token, request_token_secret: req_token.secret })
43
+ end
44
+
45
+ # tries to login the user from access token
46
+ def process_callback(params, session)
47
+ args = {
48
+ oauth_verifier: params[:oauth_verifier],
49
+ request_token: session[:request_token],
50
+ request_token_secret: session[:request_token_secret]
51
+ }
52
+
53
+ args.merge!({ code: params[:code] }) if params[:code]
54
+ get_access_token(args)
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,63 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with vk.com.
4
+ #
5
+ # config.vk.key = <key>
6
+ # config.vk.secret = <secret>
7
+ # ...
8
+ #
9
+ class Vk < Base
10
+
11
+ include Protocols::Oauth2
12
+
13
+ attr_accessor :auth_path, :token_path, :user_info_url, :scope
14
+
15
+ def initialize
16
+ super
17
+
18
+ @site = 'https://oauth.vk.com/'
19
+ @user_info_url = 'https://api.vk.com/method/getProfiles'
20
+ @auth_path = '/authorize'
21
+ @token_path = '/access_token'
22
+ @scope = 'email'
23
+ end
24
+
25
+ def get_user_hash(access_token)
26
+ user_hash = {}
27
+
28
+ params = {
29
+ access_token: access_token.token,
30
+ uids: access_token.params['user_id'],
31
+ fields: user_info_mapping.values.join(','),
32
+ scope: scope
33
+ }
34
+
35
+ response = access_token.get(user_info_url, params: params)
36
+ if user_hash[:user_info] = JSON.parse(response.body)
37
+ user_hash[:user_info] = user_hash[:user_info]['response'][0]
38
+ user_hash[:user_info]['full_name'] = [user_hash[:user_info]['first_name'], user_hash[:user_info]['last_name']].join(' ')
39
+
40
+ user_hash[:uid] = user_hash[:user_info]['uid']
41
+ user_hash[:user_info]['email'] = access_token.params['email']
42
+ end
43
+ user_hash
44
+ end
45
+
46
+ # calculates and returns the url to which the user should be redirected,
47
+ # to get authenticated at the external provider's site.
48
+ def login_url(params, session)
49
+ self.authorize_url({ authorize_url: auth_path })
50
+ end
51
+
52
+ # tries to login the user from access token
53
+ def process_callback(params, session)
54
+ args = {}.tap do |a|
55
+ a[:code] = params[:code] if params[:code]
56
+ end
57
+
58
+ get_access_token(args, token_url: token_path, token_method: :post)
59
+ end
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,64 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with xing.com.
4
+ #
5
+ # config.xing.key = <key>
6
+ # config.xing.secret = <secret>
7
+ # ...
8
+ #
9
+ class Xing < Base
10
+
11
+ include Protocols::Oauth
12
+
13
+ attr_accessor :access_token_path, :authorize_path, :request_token_path,
14
+ :user_info_path
15
+
16
+
17
+ def initialize
18
+ @configuration = {
19
+ site: 'https://api.xing.com/v1',
20
+ authorize_path: '/authorize',
21
+ request_token_path: '/request_token',
22
+ access_token_path: '/access_token'
23
+ }
24
+ @user_info_path = '/users/me'
25
+ end
26
+
27
+ # Override included get_consumer method to provide authorize_path
28
+ def get_consumer
29
+ ::OAuth::Consumer.new(@key, @secret, @configuration)
30
+ end
31
+
32
+ def get_user_hash(access_token)
33
+ response = access_token.get(user_info_path)
34
+
35
+ {}.tap do |h|
36
+ h[:user_info] = JSON.parse(response.body)['users'].first
37
+ h[:uid] = user_hash[:user_info]['id'].to_s
38
+ end
39
+ end
40
+
41
+ # calculates and returns the url to which the user should be redirected,
42
+ # to get authenticated at the external provider's site.
43
+ def login_url(params, session)
44
+ req_token = get_request_token
45
+ session[:request_token] = req_token.token
46
+ session[:request_token_secret] = req_token.secret
47
+ authorize_url({ request_token: req_token.token, request_token_secret: req_token.secret })
48
+ end
49
+
50
+ # tries to login the user from access token
51
+ def process_callback(params, session)
52
+ args = {
53
+ oauth_verifier: params[:oauth_verifier],
54
+ request_token: session[:request_token],
55
+ request_token_secret: session[:request_token_secret]
56
+ }
57
+
58
+ args.merge!({ code: params[:code] }) if params[:code]
59
+ get_access_token(args)
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,6 @@
1
+ namespace :sorcery do
2
+ desc "Adds sorcery's initializer file"
3
+ task :bootstrap do
4
+ warn "This task is obsolete.\nUse \"rails g sorcery:install\" now.\nSee README for more information."
5
+ end
6
+ end
@@ -0,0 +1,78 @@
1
+ module Sorcery
2
+ module TestHelpers
3
+ # Internal TestHelpers are used to test the gem, internally, and should not be used to test apps *using* sorcery.
4
+ # This file will be included in the spec_helper file.
5
+ module Internal
6
+ def self.included(base)
7
+ # reducing default cost for specs speed
8
+ CryptoProviders::BCrypt.class_eval do
9
+ class << self
10
+ def cost
11
+ 1
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ # a patch to fix a bug in testing that happens when you 'destroy' a session twice.
18
+ # After the first destroy, the session is an ordinary hash, and then when destroy
19
+ # is called again there's an exception.
20
+ class ::Hash
21
+ def destroy
22
+ clear
23
+ end
24
+ end
25
+
26
+ def build_new_user(attributes_hash = nil)
27
+ user_attributes_hash = attributes_hash || {:username => 'gizmo', :email => "bla@bla.com", :password => 'secret'}
28
+ @user = User.new(user_attributes_hash)
29
+ end
30
+
31
+ def create_new_user(attributes_hash = nil)
32
+ @user = build_new_user(attributes_hash)
33
+ @user.sorcery_adapter.save(:raise_on_failure => true)
34
+ @user
35
+ end
36
+
37
+ def create_new_external_user(provider, attributes_hash = nil)
38
+ user_attributes_hash = attributes_hash || {:username => 'gizmo'}
39
+ @user = User.new(user_attributes_hash)
40
+ @user.sorcery_adapter.save(:raise_on_failure => true)
41
+ @user.authentications.create!({:provider => provider, :uid => 123})
42
+ @user
43
+ end
44
+
45
+ def custom_create_new_external_user(provider, authentication_class, attributes_hash = nil)
46
+ authentication_association = authentication_class.name.underscore.pluralize
47
+
48
+ user_attributes_hash = attributes_hash || {:username => 'gizmo'}
49
+ @user = User.new(user_attributes_hash)
50
+ @user.sorcery_adapter.save(:raise_on_failure => true)
51
+ @user.send(authentication_association).create!({:provider => provider, :uid => 123})
52
+ @user
53
+ end
54
+
55
+ def sorcery_model_property_set(property, *values)
56
+ User.class_eval do
57
+ sorcery_config.send(:"#{property}=", *values)
58
+ end
59
+ end
60
+
61
+ def update_model(&block)
62
+ User.class_exec(&block)
63
+ end
64
+
65
+ private
66
+
67
+ # reload user class between specs
68
+ # so it will be possible to test the different submodules in isolation
69
+ def reload_user_class
70
+ Object.send(:remove_const, "User")
71
+ load 'user.rb'
72
+ if User.respond_to?(:reset_column_information)
73
+ User.reset_column_information
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,68 @@
1
+ module Sorcery
2
+ module TestHelpers
3
+ module Internal
4
+ module Rails
5
+ include ::Sorcery::TestHelpers::Rails::Controller
6
+
7
+ SUBMODULES_AUTO_ADDED_CONTROLLER_FILTERS = [
8
+ :register_last_activity_time_to_db,
9
+ :deny_banned_user,
10
+ :validate_session
11
+ ]
12
+
13
+ def sorcery_reload!(submodules = [], options = {})
14
+ reload_user_class
15
+
16
+ # return to no-module configuration
17
+ ::Sorcery::Controller::Config.init!
18
+ ::Sorcery::Controller::Config.reset!
19
+
20
+ # remove all plugin before_filters so they won't fail other tests.
21
+ # I don't like this way, but I didn't find another.
22
+ # hopefully it won't break until Rails 4.
23
+ chain = if Gem::Version.new(::Rails::VERSION::STRING) >= Gem::Version.new("4.1.0")
24
+ SorceryController._process_action_callbacks.send :chain
25
+ else
26
+ SorceryController._process_action_callbacks
27
+ end
28
+
29
+ chain.delete_if {|c| SUBMODULES_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) }
30
+
31
+ # configure
32
+ ::Sorcery::Controller::Config.submodules = submodules
33
+ ::Sorcery::Controller::Config.user_class = nil
34
+ ActionController::Base.send(:include,::Sorcery::Controller)
35
+ ::Sorcery::Controller::Config.user_class = "User"
36
+
37
+ ::Sorcery::Controller::Config.user_config do |user|
38
+ options.each do |property,value|
39
+ user.send(:"#{property}=", value)
40
+ end
41
+ end
42
+ User.authenticates_with_sorcery!
43
+ if defined?(DataMapper) and User.ancestors.include?(DataMapper::Resource)
44
+ DataMapper.auto_migrate!
45
+ User.finalize
46
+ Authentication.finalize
47
+ end
48
+ end
49
+
50
+ def sorcery_controller_property_set(property, value)
51
+ ::Sorcery::Controller::Config.send(:"#{property}=", value)
52
+ end
53
+
54
+ def sorcery_controller_external_property_set(provider, property, value)
55
+ ::Sorcery::Controller::Config.send(provider).send(:"#{property}=", value)
56
+ end
57
+
58
+ # This helper is used to fake multiple users signing in in tests.
59
+ # It does so by clearing @current_user, thus allowing a new user to login,
60
+ # all this without calling the :logout action explicitly.
61
+ # A dirty dirty hack.
62
+ def clear_user_without_logout
63
+ subject.instance_variable_set(:@current_user,nil)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,21 @@
1
+ module Sorcery
2
+ module TestHelpers
3
+ module Rails
4
+ module Controller
5
+ def login_user(user = nil, test_context = {})
6
+ user ||= @user
7
+ @controller.send(:auto_login, user)
8
+ @controller.send(:after_login!, user, [user.send(user.sorcery_config.username_attribute_names.first), 'secret'])
9
+ end
10
+
11
+ def logout_user
12
+ @controller.send(:logout)
13
+ end
14
+
15
+ def logged_in?
16
+ @controller.send(:logged_in?)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ module Sorcery
2
+ module TestHelpers
3
+ module Rails
4
+ module Integration
5
+
6
+ #Accepts arguments for user to login, route to use and HTTP method
7
+ #Defaults - @user, 'sessions_url' and POST
8
+ def login_user(user = nil, route = nil, http_method = :post)
9
+ user ||= @user
10
+ route ||= sessions_url
11
+
12
+ username_attr = user.sorcery_config.username_attribute_names.first
13
+ username = user.send(username_attr)
14
+ page.driver.send(http_method, route, { :"#{username_attr}" => username, :password => 'secret' })
15
+ end
16
+
17
+ #Accepts route and HTTP method arguments
18
+ #Default - 'logout_url' and GET
19
+ def logout_user(route = nil, http_method = :get)
20
+ route ||= logout_url
21
+ page.driver.send(http_method, route)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module Sorcery
2
+ VERSION = "0.8.6"
3
+ end
data/sorcery.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'sorcery/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "cbsorcery"
7
+ s.version = Sorcery::VERSION
8
+ s.authors = ["Noam Ben Ari", "Kir Shatrov", "Grzegorz Witek"]
9
+ s.email = "nbenari@gmail.com"
10
+ s.description = "Provides common authentication needs such as signing in/out, activating by email and resetting password."
11
+ s.summary = "Magical authentication for Rails 3 & 4 applications"
12
+ s.homepage = "http://github.com/NoamB/sorcery"
13
+
14
+ s.files = `git ls-files`.split($/)
15
+ s.require_paths = ["lib"]
16
+
17
+ s.licenses = ["MIT"]
18
+
19
+ s.required_ruby_version = '>= 1.9.3'
20
+
21
+ s.add_dependency "oauth", "~> 0.4", ">= 0.4.4"
22
+ s.add_dependency "oauth2", ">= 0.8.0"
23
+ s.add_dependency "bcrypt", "~> 3.1"
24
+
25
+ s.add_development_dependency "abstract", ">= 1.0.0"
26
+ s.add_development_dependency "json", ">= 1.7.7"
27
+ s.add_development_dependency "yard", "~> 0.6.0"
28
+
29
+ s.add_development_dependency "timecop"
30
+ s.add_development_dependency "simplecov", ">= 0.3.8"
31
+ s.add_development_dependency "rspec", "~> 3.0.0"
32
+ s.add_development_dependency "rspec-rails", "~> 3.0.0"
33
+ end
34
+
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ require 'rails_app/app/mailers/sorcery_mailer'
4
+ require 'shared_examples/user_activation_shared_examples'
5
+
6
+ describe User, "with activation submodule", :active_record => true do
7
+ before(:all) do
8
+ ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation")
9
+ User.reset_column_information
10
+ end
11
+
12
+ after(:all) do
13
+ ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation")
14
+ end
15
+
16
+ it_behaves_like "rails_3_activation_model"
17
+
18
+ end