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.
- data/.document +5 -0
- data/.gitignore +56 -0
- data/.rspec +1 -0
- data/.travis.yml +40 -0
- data/CHANGELOG.md +263 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +20 -0
- data/README.md +360 -0
- data/Rakefile +6 -0
- data/gemfiles/active_record-rails40.gemfile +7 -0
- data/gemfiles/active_record-rails41.gemfile +7 -0
- data/lib/generators/sorcery/USAGE +22 -0
- data/lib/generators/sorcery/helpers.rb +40 -0
- data/lib/generators/sorcery/install_generator.rb +95 -0
- data/lib/generators/sorcery/templates/initializer.rb +451 -0
- data/lib/generators/sorcery/templates/migration/activity_logging.rb +10 -0
- data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +9 -0
- data/lib/generators/sorcery/templates/migration/core.rb +13 -0
- data/lib/generators/sorcery/templates/migration/external.rb +12 -0
- data/lib/generators/sorcery/templates/migration/remember_me.rb +8 -0
- data/lib/generators/sorcery/templates/migration/reset_password.rb +9 -0
- data/lib/generators/sorcery/templates/migration/user_activation.rb +9 -0
- data/lib/sorcery.rb +85 -0
- data/lib/sorcery/adapters/active_record_adapter.rb +120 -0
- data/lib/sorcery/adapters/base_adapter.rb +30 -0
- data/lib/sorcery/controller.rb +157 -0
- data/lib/sorcery/controller/config.rb +65 -0
- data/lib/sorcery/controller/submodules/activity_logging.rb +82 -0
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +38 -0
- data/lib/sorcery/controller/submodules/external.rb +199 -0
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +74 -0
- data/lib/sorcery/controller/submodules/remember_me.rb +81 -0
- data/lib/sorcery/controller/submodules/session_timeout.rb +56 -0
- data/lib/sorcery/crypto_providers/aes256.rb +51 -0
- data/lib/sorcery/crypto_providers/bcrypt.rb +97 -0
- data/lib/sorcery/crypto_providers/common.rb +35 -0
- data/lib/sorcery/crypto_providers/md5.rb +19 -0
- data/lib/sorcery/crypto_providers/sha1.rb +28 -0
- data/lib/sorcery/crypto_providers/sha256.rb +36 -0
- data/lib/sorcery/crypto_providers/sha512.rb +36 -0
- data/lib/sorcery/engine.rb +21 -0
- data/lib/sorcery/model.rb +183 -0
- data/lib/sorcery/model/config.rb +96 -0
- data/lib/sorcery/model/submodules/activity_logging.rb +70 -0
- data/lib/sorcery/model/submodules/brute_force_protection.rb +125 -0
- data/lib/sorcery/model/submodules/external.rb +100 -0
- data/lib/sorcery/model/submodules/remember_me.rb +62 -0
- data/lib/sorcery/model/submodules/reset_password.rb +131 -0
- data/lib/sorcery/model/submodules/user_activation.rb +149 -0
- data/lib/sorcery/model/temporary_token.rb +30 -0
- data/lib/sorcery/protocols/certs/ca-bundle.crt +5182 -0
- data/lib/sorcery/protocols/oauth.rb +42 -0
- data/lib/sorcery/protocols/oauth2.rb +47 -0
- data/lib/sorcery/providers/base.rb +27 -0
- data/lib/sorcery/providers/facebook.rb +63 -0
- data/lib/sorcery/providers/github.rb +51 -0
- data/lib/sorcery/providers/google.rb +51 -0
- data/lib/sorcery/providers/jira.rb +77 -0
- data/lib/sorcery/providers/linkedin.rb +66 -0
- data/lib/sorcery/providers/liveid.rb +53 -0
- data/lib/sorcery/providers/twitter.rb +59 -0
- data/lib/sorcery/providers/vk.rb +63 -0
- data/lib/sorcery/providers/xing.rb +64 -0
- data/lib/sorcery/railties/tasks.rake +6 -0
- data/lib/sorcery/test_helpers/internal.rb +78 -0
- data/lib/sorcery/test_helpers/internal/rails.rb +68 -0
- data/lib/sorcery/test_helpers/rails/controller.rb +21 -0
- data/lib/sorcery/test_helpers/rails/integration.rb +26 -0
- data/lib/sorcery/version.rb +3 -0
- data/sorcery.gemspec +34 -0
- data/spec/active_record/user_activation_spec.rb +18 -0
- data/spec/active_record/user_activity_logging_spec.rb +17 -0
- data/spec/active_record/user_brute_force_protection_spec.rb +16 -0
- data/spec/active_record/user_oauth_spec.rb +16 -0
- data/spec/active_record/user_remember_me_spec.rb +16 -0
- data/spec/active_record/user_reset_password_spec.rb +16 -0
- data/spec/active_record/user_spec.rb +37 -0
- data/spec/controllers/controller_activity_logging_spec.rb +124 -0
- data/spec/controllers/controller_brute_force_protection_spec.rb +43 -0
- data/spec/controllers/controller_http_basic_auth_spec.rb +68 -0
- data/spec/controllers/controller_oauth2_spec.rb +407 -0
- data/spec/controllers/controller_oauth_spec.rb +240 -0
- data/spec/controllers/controller_remember_me_spec.rb +117 -0
- data/spec/controllers/controller_session_timeout_spec.rb +80 -0
- data/spec/controllers/controller_spec.rb +215 -0
- data/spec/orm/active_record.rb +21 -0
- data/spec/rails_app/app/active_record/authentication.rb +3 -0
- data/spec/rails_app/app/active_record/user.rb +5 -0
- data/spec/rails_app/app/active_record/user_provider.rb +3 -0
- data/spec/rails_app/app/controllers/sorcery_controller.rb +265 -0
- data/spec/rails_app/app/helpers/application_helper.rb +2 -0
- data/spec/rails_app/app/mailers/sorcery_mailer.rb +32 -0
- data/spec/rails_app/app/views/application/index.html.erb +17 -0
- data/spec/rails_app/app/views/layouts/application.html.erb +14 -0
- data/spec/rails_app/app/views/sorcery_mailer/activation_email.html.erb +17 -0
- data/spec/rails_app/app/views/sorcery_mailer/activation_email.text.erb +9 -0
- data/spec/rails_app/app/views/sorcery_mailer/activation_needed_email.html.erb +17 -0
- data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
- data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
- data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
- data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
- data/spec/rails_app/app/views/sorcery_mailer/send_unlock_token_email.text.erb +1 -0
- data/spec/rails_app/config.ru +4 -0
- data/spec/rails_app/config/application.rb +56 -0
- data/spec/rails_app/config/boot.rb +4 -0
- data/spec/rails_app/config/database.yml +22 -0
- data/spec/rails_app/config/environment.rb +5 -0
- data/spec/rails_app/config/environments/test.rb +37 -0
- data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails_app/config/initializers/inflections.rb +10 -0
- data/spec/rails_app/config/initializers/mime_types.rb +5 -0
- data/spec/rails_app/config/initializers/secret_token.rb +7 -0
- data/spec/rails_app/config/initializers/session_store.rb +12 -0
- data/spec/rails_app/config/locales/en.yml +5 -0
- data/spec/rails_app/config/routes.rb +48 -0
- data/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +17 -0
- data/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +19 -0
- data/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +13 -0
- data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +16 -0
- data/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +22 -0
- data/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
- data/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
- data/spec/rails_app/db/schema.rb +23 -0
- data/spec/rails_app/db/seeds.rb +7 -0
- data/spec/shared_examples/user_activation_shared_examples.rb +242 -0
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +97 -0
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +156 -0
- data/spec/shared_examples/user_oauth_shared_examples.rb +36 -0
- data/spec/shared_examples/user_remember_me_shared_examples.rb +57 -0
- data/spec/shared_examples/user_reset_password_shared_examples.rb +263 -0
- data/spec/shared_examples/user_shared_examples.rb +467 -0
- data/spec/sorcery_crypto_providers_spec.rb +198 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +41 -0
- metadata +350 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
class SorceryActivityLogging < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
add_column :<%= model_class_name.tableize %>, :last_login_at, :datetime, :default => nil
|
|
4
|
+
add_column :<%= model_class_name.tableize %>, :last_logout_at, :datetime, :default => nil
|
|
5
|
+
add_column :<%= model_class_name.tableize %>, :last_activity_at, :datetime, :default => nil
|
|
6
|
+
add_column :<%= model_class_name.tableize %>, :last_login_from_ip_address, :string, :default => nil
|
|
7
|
+
|
|
8
|
+
add_index :<%= model_class_name.tableize %>, [:last_logout_at, :last_activity_at]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
class SorceryBruteForceProtection < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
add_column :<%= model_class_name.tableize %>, :failed_logins_count, :integer, :default => 0
|
|
4
|
+
add_column :<%= model_class_name.tableize %>, :lock_expires_at, :datetime, :default => nil
|
|
5
|
+
add_column :<%= model_class_name.tableize %>, :unlock_token, :string, :default => nil
|
|
6
|
+
|
|
7
|
+
add_index :<%= model_class_name.tableize %>, :unlock_token
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class SorceryCore < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
create_table :<%= model_class_name.tableize %> do |t|
|
|
4
|
+
t.string :email, :null => false
|
|
5
|
+
t.string :crypted_password, :null => false
|
|
6
|
+
t.string :salt, :null => false
|
|
7
|
+
|
|
8
|
+
t.timestamps
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
add_index :<%= model_class_name.tableize %>, :email, unique: true
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class SorceryExternal < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
create_table :authentications do |t|
|
|
4
|
+
t.integer :<%= model_class_name.tableize.singularize %>_id, :null => false
|
|
5
|
+
t.string :provider, :uid, :null => false
|
|
6
|
+
|
|
7
|
+
t.timestamps
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
add_index :<%= model_class_name.tableize %>, [:provider, :uid]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
class SorceryRememberMe < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
add_column :<%= model_class_name.tableize %>, :remember_me_token, :string, :default => nil
|
|
4
|
+
add_column :<%= model_class_name.tableize %>, :remember_me_token_expires_at, :datetime, :default => nil
|
|
5
|
+
|
|
6
|
+
add_index :<%= model_class_name.tableize %>, :remember_me_token
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
class SorceryResetPassword < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
add_column :<%= model_class_name.tableize %>, :reset_password_token, :string, :default => nil
|
|
4
|
+
add_column :<%= model_class_name.tableize %>, :reset_password_token_expires_at, :datetime, :default => nil
|
|
5
|
+
add_column :<%= model_class_name.tableize %>, :reset_password_email_sent_at, :datetime, :default => nil
|
|
6
|
+
|
|
7
|
+
add_index :<%= model_class_name.tableize %>, :reset_password_token
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
class SorceryUserActivation < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
add_column :<%= model_class_name.tableize %>, :activation_state, :string, :default => nil
|
|
4
|
+
add_column :<%= model_class_name.tableize %>, :activation_token, :string, :default => nil
|
|
5
|
+
add_column :<%= model_class_name.tableize %>, :activation_token_expires_at, :datetime, :default => nil
|
|
6
|
+
|
|
7
|
+
add_index :<%= model_class_name.tableize %>, :activation_token
|
|
8
|
+
end
|
|
9
|
+
end
|
data/lib/sorcery.rb
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require 'sorcery/version'
|
|
2
|
+
|
|
3
|
+
module Sorcery
|
|
4
|
+
|
|
5
|
+
require 'sorcery/model'
|
|
6
|
+
|
|
7
|
+
module Adapters
|
|
8
|
+
require 'sorcery/adapters/base_adapter'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module Model
|
|
12
|
+
require 'sorcery/model/temporary_token'
|
|
13
|
+
require 'sorcery/model/config'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
module Submodules
|
|
17
|
+
require 'sorcery/model/submodules/user_activation'
|
|
18
|
+
require 'sorcery/model/submodules/reset_password'
|
|
19
|
+
require 'sorcery/model/submodules/remember_me'
|
|
20
|
+
require 'sorcery/model/submodules/activity_logging'
|
|
21
|
+
require 'sorcery/model/submodules/brute_force_protection'
|
|
22
|
+
require 'sorcery/model/submodules/external'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
require 'sorcery/controller'
|
|
27
|
+
|
|
28
|
+
module Controller
|
|
29
|
+
autoload :Config, 'sorcery/controller/config'
|
|
30
|
+
module Submodules
|
|
31
|
+
require 'sorcery/controller/submodules/remember_me'
|
|
32
|
+
require 'sorcery/controller/submodules/session_timeout'
|
|
33
|
+
require 'sorcery/controller/submodules/brute_force_protection'
|
|
34
|
+
require 'sorcery/controller/submodules/http_basic_auth'
|
|
35
|
+
require 'sorcery/controller/submodules/activity_logging'
|
|
36
|
+
require 'sorcery/controller/submodules/external'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
module Protocols
|
|
41
|
+
require 'sorcery/protocols/oauth'
|
|
42
|
+
require 'sorcery/protocols/oauth2'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
module CryptoProviders
|
|
46
|
+
require 'sorcery/crypto_providers/common'
|
|
47
|
+
require 'sorcery/crypto_providers/aes256'
|
|
48
|
+
require 'sorcery/crypto_providers/bcrypt'
|
|
49
|
+
require 'sorcery/crypto_providers/md5'
|
|
50
|
+
require 'sorcery/crypto_providers/sha1'
|
|
51
|
+
require 'sorcery/crypto_providers/sha256'
|
|
52
|
+
require 'sorcery/crypto_providers/sha512'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
module TestHelpers
|
|
56
|
+
require 'sorcery/test_helpers/internal'
|
|
57
|
+
|
|
58
|
+
module Rails
|
|
59
|
+
require 'sorcery/test_helpers/rails/controller'
|
|
60
|
+
require 'sorcery/test_helpers/rails/integration'
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
module Internal
|
|
64
|
+
require 'sorcery/test_helpers/internal/rails'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
require 'sorcery/adapters/base_adapter'
|
|
70
|
+
|
|
71
|
+
if defined?(ActiveRecord)
|
|
72
|
+
require 'sorcery/adapters/active_record_adapter'
|
|
73
|
+
ActiveRecord::Base.extend Sorcery::Model
|
|
74
|
+
|
|
75
|
+
ActiveRecord::Base.send :define_method, :sorcery_adapter do
|
|
76
|
+
@sorcery_adapter ||= Sorcery::Adapters::ActiveRecordAdapter.new(self)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
ActiveRecord::Base.send :define_singleton_method, :sorcery_adapter do
|
|
80
|
+
Sorcery::Adapters::ActiveRecordAdapter.from(self)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
require 'sorcery/engine' if defined?(Rails)
|
|
85
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
module Sorcery
|
|
2
|
+
module Adapters
|
|
3
|
+
class ActiveRecordAdapter < BaseAdapter
|
|
4
|
+
def update_attributes(attrs)
|
|
5
|
+
attrs.each do |name, value|
|
|
6
|
+
@model.send(:"#{name}=", value)
|
|
7
|
+
end
|
|
8
|
+
primary_key = @model.class.primary_key
|
|
9
|
+
@model.class.where(:"#{primary_key}" => @model.send(:"#{primary_key}")).update_all(attrs)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def save(options = {})
|
|
13
|
+
mthd = options.delete(:raise_on_failure) ? :save! : :save
|
|
14
|
+
@model.send(mthd, options)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def increment(field)
|
|
18
|
+
@model.increment!(field)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def find_authentication_by_oauth_credentials(relation_name, provider, uid)
|
|
22
|
+
@user_config ||= ::Sorcery::Controller::Config.user_class.to_s.constantize.sorcery_config
|
|
23
|
+
conditions = {
|
|
24
|
+
@user_config.provider_uid_attribute_name => uid,
|
|
25
|
+
@user_config.provider_attribute_name => provider
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@model.public_send(relation_name).where(conditions).first
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class << self
|
|
32
|
+
def define_field(name, type, options={})
|
|
33
|
+
# AR fields are defined through migrations, only validator here
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def define_callback(time, event, method_name, options={})
|
|
37
|
+
@klass.send "#{time}_#{event}", method_name, options.slice(:if)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def find_by_oauth_credentials(provider, uid)
|
|
41
|
+
@user_config ||= ::Sorcery::Controller::Config.user_class.to_s.constantize.sorcery_config
|
|
42
|
+
conditions = {
|
|
43
|
+
@user_config.provider_uid_attribute_name => uid,
|
|
44
|
+
@user_config.provider_attribute_name => provider
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@klass.where(conditions).first
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def find_by_remember_me_token(token)
|
|
51
|
+
@klass.where(@klass.sorcery_config.remember_me_token_attribute_name => token).first
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def find_by_credentials(credentials)
|
|
55
|
+
relation = nil
|
|
56
|
+
|
|
57
|
+
@klass.sorcery_config.username_attribute_names.each do |attribute|
|
|
58
|
+
if @klass.sorcery_config.downcase_username_before_authenticating
|
|
59
|
+
condition = @klass.arel_table[attribute].lower.eq(@klass.arel_table.lower(credentials[0]))
|
|
60
|
+
else
|
|
61
|
+
condition = @klass.arel_table[attribute].eq(credentials[0])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
if relation.nil?
|
|
65
|
+
relation = condition
|
|
66
|
+
else
|
|
67
|
+
relation = relation.or(condition)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
@klass.where(relation).first
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def find_by_token(token_attr_name, token)
|
|
75
|
+
condition = @klass.arel_table[token_attr_name].eq(token)
|
|
76
|
+
|
|
77
|
+
@klass.where(condition).first
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def find_by_activation_token(token)
|
|
81
|
+
@klass.where(@klass.sorcery_config.activation_token_attribute_name => token).first
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def find_by_id(id)
|
|
85
|
+
@klass.find_by_id(id)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def find_by_username(username)
|
|
89
|
+
@klass.sorcery_config.username_attribute_names.each do |attribute|
|
|
90
|
+
if @klass.sorcery_config.downcase_username_before_authenticating
|
|
91
|
+
username = username.downcase
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
result = @klass.where(attribute => username).first
|
|
95
|
+
return result if result
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def find_by_email(email)
|
|
100
|
+
@klass.where(@klass.sorcery_config.email_attribute_name => email).first
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def get_current_users
|
|
104
|
+
config = @klass.sorcery_config
|
|
105
|
+
|
|
106
|
+
@klass
|
|
107
|
+
.where("#{config.last_activity_at_attribute_name} IS NOT NULL") \
|
|
108
|
+
.where("#{config.last_logout_at_attribute_name} IS NULL OR #{config.last_activity_at_attribute_name} > #{config.last_logout_at_attribute_name}") \
|
|
109
|
+
.where("#{config.last_activity_at_attribute_name} > ? ", config.activity_timeout.seconds.ago.utc.to_s(:db))
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def transaction(&blk)
|
|
113
|
+
@klass.tap(&blk)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Sorcery
|
|
2
|
+
module Adapters
|
|
3
|
+
class BaseAdapter
|
|
4
|
+
def initialize(model)
|
|
5
|
+
@model = model
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def self.from(klass)
|
|
9
|
+
@klass = klass
|
|
10
|
+
self
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.delete_all
|
|
14
|
+
@klass.delete_all
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.find(id)
|
|
18
|
+
find_by_id(id)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def increment(field)
|
|
22
|
+
@model.increment(field)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def update_attribute(name, value)
|
|
26
|
+
update_attributes(name => value)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
module Sorcery
|
|
2
|
+
module Controller
|
|
3
|
+
def self.included(klass)
|
|
4
|
+
klass.class_eval do
|
|
5
|
+
include InstanceMethods
|
|
6
|
+
Config.submodules.each do |mod|
|
|
7
|
+
begin
|
|
8
|
+
include Submodules.const_get(mod.to_s.split('_').map { |p| p.capitalize }.join)
|
|
9
|
+
rescue NameError
|
|
10
|
+
# don't stop on a missing submodule.
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
Config.update!
|
|
15
|
+
Config.configure!
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
module InstanceMethods
|
|
19
|
+
# To be used as before_filter.
|
|
20
|
+
# Will trigger auto-login attempts via the call to logged_in?
|
|
21
|
+
# If all attempts to auto-login fail, the failure callback will be called.
|
|
22
|
+
def require_login
|
|
23
|
+
if !logged_in?
|
|
24
|
+
session[:return_to_url] = request.url if Config.save_return_to_url && request.get?
|
|
25
|
+
self.send(Config.not_authenticated_action)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Takes credentials and returns a user on successful authentication.
|
|
30
|
+
# Runs hooks after login or failed login.
|
|
31
|
+
def login(*credentials)
|
|
32
|
+
@current_user = nil
|
|
33
|
+
user = user_class.authenticate(*credentials)
|
|
34
|
+
if user
|
|
35
|
+
old_session = session.dup.to_hash
|
|
36
|
+
reset_sorcery_session
|
|
37
|
+
old_session.each_pair do |k,v|
|
|
38
|
+
session[k.to_sym] = v
|
|
39
|
+
end
|
|
40
|
+
form_authenticity_token
|
|
41
|
+
|
|
42
|
+
auto_login(user)
|
|
43
|
+
after_login!(user, credentials)
|
|
44
|
+
current_user
|
|
45
|
+
else
|
|
46
|
+
after_failed_login!(credentials)
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# put this into the catch block to rescue undefined method `destroy_session'
|
|
52
|
+
# hotfix for https://github.com/NoamB/sorcery/issues/464
|
|
53
|
+
# can be removed when Rails 4.1 is out
|
|
54
|
+
def reset_sorcery_session
|
|
55
|
+
reset_session # protect from session fixation attacks
|
|
56
|
+
rescue NoMethodError
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Resets the session and runs hooks before and after.
|
|
60
|
+
def logout
|
|
61
|
+
if logged_in?
|
|
62
|
+
@current_user = current_user if @current_user.nil?
|
|
63
|
+
before_logout!(@current_user)
|
|
64
|
+
reset_sorcery_session
|
|
65
|
+
after_logout!
|
|
66
|
+
@current_user = nil
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def logged_in?
|
|
71
|
+
!!current_user
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# attempts to auto-login from the sources defined (session, basic_auth, cookie, etc.)
|
|
75
|
+
# returns the logged in user if found, nil if not
|
|
76
|
+
def current_user
|
|
77
|
+
unless defined?(@current_user)
|
|
78
|
+
@current_user = login_from_session || login_from_other_sources || nil
|
|
79
|
+
end
|
|
80
|
+
@current_user
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def current_user=(user)
|
|
84
|
+
@current_user = user
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# used when a user tries to access a page while logged out, is asked to login,
|
|
88
|
+
# and we want to return him back to the page he originally wanted.
|
|
89
|
+
def redirect_back_or_to(url, flash_hash = {})
|
|
90
|
+
redirect_to(session[:return_to_url] || url, :flash => flash_hash)
|
|
91
|
+
session[:return_to_url] = nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# The default action for denying non-authenticated users.
|
|
95
|
+
# You can override this method in your controllers,
|
|
96
|
+
# or provide a different method in the configuration.
|
|
97
|
+
def not_authenticated
|
|
98
|
+
redirect_to root_path
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# login a user instance
|
|
102
|
+
#
|
|
103
|
+
# @param [<User-Model>] user the user instance.
|
|
104
|
+
# @return - do not depend on the return value.
|
|
105
|
+
def auto_login(user, should_remember = false)
|
|
106
|
+
session[:user_id] = user.id.to_s
|
|
107
|
+
@current_user = user
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Overwrite Rails' handle unverified request
|
|
111
|
+
def handle_unverified_request
|
|
112
|
+
cookies[:remember_me_token] = nil
|
|
113
|
+
@current_user = nil
|
|
114
|
+
super # call the default behaviour which resets the session
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
protected
|
|
118
|
+
|
|
119
|
+
# Tries all available sources (methods) until one doesn't return false.
|
|
120
|
+
def login_from_other_sources
|
|
121
|
+
result = nil
|
|
122
|
+
Config.login_sources.find do |source|
|
|
123
|
+
result = send(source)
|
|
124
|
+
end
|
|
125
|
+
result || false
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def login_from_session
|
|
129
|
+
@current_user = if session[:user_id]
|
|
130
|
+
user_class.sorcery_adapter.find_by_id(session[:user_id])
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def after_login!(user, credentials = [])
|
|
135
|
+
Config.after_login.each {|c| self.send(c, user, credentials)}
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def after_failed_login!(credentials)
|
|
139
|
+
Config.after_failed_login.each {|c| self.send(c, credentials)}
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def before_logout!(user)
|
|
143
|
+
Config.before_logout.each {|c| self.send(c, user)}
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def after_logout!
|
|
147
|
+
Config.after_logout.each {|c| self.send(c)}
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def user_class
|
|
151
|
+
@user_class ||= Config.user_class.to_s.constantize
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
end
|
|
157
|
+
end
|