devise_invalidatable 0.0.1
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.
- checksums.yaml +7 -0
- data/lib/devise_invalidatable.rb +16 -0
- data/lib/devise_invalidatable/hooks/invalidatable.rb +25 -0
- data/lib/devise_invalidatable/model.rb +37 -0
- data/lib/devise_invalidatable/version.rb +3 -0
- data/lib/generators/devise_invalidatable/devise_invalidatable_generator.rb +36 -0
- data/lib/generators/devise_invalidatable/templates/migration.rb +18 -0
- metadata +77 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f92232200260dbb1d0e4052ad0e17a6d7e6fdc6c
|
4
|
+
data.tar.gz: 925c9619e77588dddb81a9e94dfd5834c0c5277a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0ce8619f19ff1f1a5e5c9988273f318b4902920f7f473e09feb9b20bbc1187c38ed57bdfe9ca74a0b2181a74d2b6db95602a1a5c2aa5654515d6e9fcd98d9ea3
|
7
|
+
data.tar.gz: c336ff382bc2a9cf22e2d71c43476967f3f778d365453757d78044c4b4ccd6dccf65c5cbe3be1675ed00a1b000c58a405ce151d68207b625ec4bce2af9ee6e3a
|
@@ -0,0 +1,16 @@
|
|
1
|
+
unless defined?(Devise)
|
2
|
+
require 'devise'
|
3
|
+
end
|
4
|
+
require 'devise_invalidatable'
|
5
|
+
|
6
|
+
Devise.add_module(:invalidatable,
|
7
|
+
model: 'devise_invalidatable/model')
|
8
|
+
|
9
|
+
module DeviseInvalidatable
|
10
|
+
end
|
11
|
+
|
12
|
+
class UserSession < ActiveRecord::Base
|
13
|
+
def self.deactivate(session_id)
|
14
|
+
where(session_id: session_id).delete_all
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# After authenticating, we’re removing any session activation that may already
|
2
|
+
# exist, and creating a new session# activation. We generate our own random id
|
3
|
+
# (in User#activate_session) and store it in the auth_id key. There is already
|
4
|
+
# a session_id key, but the session gets renewed (and the session id changes)
|
5
|
+
# after authentication in order to avoid session fixation attacks. So it’s
|
6
|
+
# easier to just use our own id.
|
7
|
+
Warden::Manager.after_set_user except: :fetch do |user, warden, _|
|
8
|
+
UserSession.deactivate(warden.raw_session['auth_id'])
|
9
|
+
warden.raw_session['auth_id'] = user.activate_session
|
10
|
+
end
|
11
|
+
|
12
|
+
# After fetching a user from the session, we check that the session is marked
|
13
|
+
# as active for that user. If it’s not we log the user out.
|
14
|
+
Warden::Manager.after_fetch do |user, warden, _|
|
15
|
+
unless user.session_active?(warden.raw_session['auth_id'])
|
16
|
+
warden.logout
|
17
|
+
throw :warden, message: :unauthenticated
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# When logging out, we deactivate the current session. This ensures that the
|
22
|
+
# session cookie can’t be reused afterwards.
|
23
|
+
Warden::Manager.before_logout do |_, warden, _|
|
24
|
+
UserSession.deactivate(warden.raw_session['auth_id'])
|
25
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'devise_invalidatable/hooks/invalidatable'
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
module Models
|
5
|
+
module Invalidatable
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
has_many :user_sessions,
|
10
|
+
class_name: 'UserSession',
|
11
|
+
foreign_key: :user_id,
|
12
|
+
dependent: :destroy
|
13
|
+
end
|
14
|
+
|
15
|
+
def activate_session
|
16
|
+
new_session = user_sessions.new
|
17
|
+
new_session.session_id = SecureRandom.hex(127)
|
18
|
+
new_session.save
|
19
|
+
purge_old_sessions
|
20
|
+
new_session.session_id
|
21
|
+
end
|
22
|
+
|
23
|
+
def exclusive_session(session_id)
|
24
|
+
user_sessions.where('session_id != ?', session_id).delete_all
|
25
|
+
end
|
26
|
+
|
27
|
+
def session_active?(session_id)
|
28
|
+
user_sessions.where(session_id: session_id).exists?
|
29
|
+
end
|
30
|
+
|
31
|
+
def purge_old_sessions
|
32
|
+
user_sessions.order('created_at desc').offset(10).destroy_all
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
class DeviseInvalidatableGenerator < Rails::Generators::NamedBase
|
4
|
+
include Rails::Generators::Migration
|
5
|
+
|
6
|
+
desc 'Creates a migration to add the required attributes to NAME, and adds' \
|
7
|
+
'the necessary Devise directives to the model'
|
8
|
+
|
9
|
+
def self.source_root
|
10
|
+
@_devise_source_root ||= File.expand_path('../templates', __FILE__)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.next_migration_number(dirname)
|
14
|
+
if ActiveRecord::Base.timestamped_migrations
|
15
|
+
Time.now.utc.strftime('%Y%m%d%H%M%S')
|
16
|
+
else
|
17
|
+
'%.3d' % (current_migration_number(dirname) + 1)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_migration_file
|
22
|
+
migration_template 'migration.rb', 'db/migrate/devise_create_user_sessions.rb'
|
23
|
+
end
|
24
|
+
|
25
|
+
def inject_devise_directives_into_model
|
26
|
+
model_path = File.join('app', 'models', "#{file_path}.rb")
|
27
|
+
class_path = namespaced? ? class_name.to_s.split('::') : [class_name]
|
28
|
+
indent_depth = class_path.size
|
29
|
+
|
30
|
+
content = ['devise :invalidatable']
|
31
|
+
content = content.map { |line| ' ' * indent_depth + line }.join("\n") << "\n"
|
32
|
+
|
33
|
+
inject_into_class(model_path, class_path.last, content)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class DeviseCreateUserSessions < ActiveRecord::Migration
|
2
|
+
@@table_name = :user_sessions
|
3
|
+
@@column_name = :user_id
|
4
|
+
|
5
|
+
def up
|
6
|
+
create_table @@table_name do |t|
|
7
|
+
t.integer @@column_name
|
8
|
+
t.string :session_id
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
add_index(@@table_name, @@column_name)
|
12
|
+
add_index(@@table_name, :session_id, unique: true)
|
13
|
+
end
|
14
|
+
|
15
|
+
def down
|
16
|
+
drop_table(@@table_name)
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: devise_invalidatable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Adkins
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: devise
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Adds the ability to invalidate a session with Devise
|
42
|
+
email: mdadki@gmail.com
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- lib/devise_invalidatable.rb
|
48
|
+
- lib/devise_invalidatable/hooks/invalidatable.rb
|
49
|
+
- lib/devise_invalidatable/model.rb
|
50
|
+
- lib/devise_invalidatable/version.rb
|
51
|
+
- lib/generators/devise_invalidatable/devise_invalidatable_generator.rb
|
52
|
+
- lib/generators/devise_invalidatable/templates/migration.rb
|
53
|
+
homepage: https://github.com/madkins/devise_invalidatable
|
54
|
+
licenses:
|
55
|
+
- MIT
|
56
|
+
metadata: {}
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 2.2.2
|
74
|
+
signing_key:
|
75
|
+
specification_version: 4
|
76
|
+
summary: Adds the ability to invalidate a session with Devise
|
77
|
+
test_files: []
|