cbsorcery 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
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