authie 1.0.0
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/db/migrate/20141012174250_create_authie_sessions.rb +17 -0
- data/lib/authie.rb +4 -0
- data/lib/authie/config.rb +24 -0
- data/lib/authie/controller_extension.rb +48 -0
- data/lib/authie/engine.rb +21 -0
- data/lib/authie/error.rb +4 -0
- data/lib/authie/session.rb +153 -0
- data/lib/authie/version.rb +3 -0
- metadata +53 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5fae3a28b39351d3fd2d65cceb2fb3c27ae48fc8
|
4
|
+
data.tar.gz: f495eea593432bacdfb352cf81e22c06a4d51e43
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b4ea09a545f6e32133e3c07fc79a8b2f925dd3ca796146fc1beff04e4863fd7acaa0cdc725a035087f2d6d0616ea18a29afaedaf937846bd7a1b5ff49b9431d7
|
7
|
+
data.tar.gz: 556e8ae46773fefcd25b11e9e3d0f30c8cd7b71dcc54986f28255ce57f7867e9d984d1237002a9bd7eb6e8b6467ffb846b77acb457dfa091eb3ce73f838f85d0
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateAuthieSessions < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :authie_sessions do |t|
|
4
|
+
t.string :token, :browser_id
|
5
|
+
t.integer :user_id
|
6
|
+
t.boolean :active, :default => true
|
7
|
+
t.text :data
|
8
|
+
t.datetime :expires_at
|
9
|
+
t.datetime :login_at
|
10
|
+
t.string :login_ip
|
11
|
+
t.datetime :last_activity_at
|
12
|
+
t.string :last_activity_ip, :last_activity_path
|
13
|
+
t.string :user_agent
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/authie.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module Authie
|
2
|
+
class Config
|
3
|
+
|
4
|
+
def session_inactivity_timeout
|
5
|
+
@session_inactivity_timeout || 12.hours
|
6
|
+
end
|
7
|
+
attr_writer :session_inactivity_timeout
|
8
|
+
|
9
|
+
def persistent_session_length
|
10
|
+
@persistent_session_length || 2.months
|
11
|
+
end
|
12
|
+
attr_writer :persistent_session_length
|
13
|
+
|
14
|
+
def user_model_class_name
|
15
|
+
@user_model_class_name || 'User'
|
16
|
+
end
|
17
|
+
attr_writer :user_model_class_name
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.config
|
22
|
+
@config ||= Config.new
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Authie
|
2
|
+
module ControllerExtension
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.helper_method :logged_in?, :current_user, :auth_session
|
6
|
+
base.before_filter :set_browser_id
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# Set a random browser ID for this browser.
|
12
|
+
# TODO: check that this is unique before setting it.
|
13
|
+
def set_browser_id
|
14
|
+
unless cookies[:browser_id]
|
15
|
+
cookies[:browser_id] = {:value => SecureRandom.uuid, :expires => 20.years.from_now}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return the currently logged in user object
|
20
|
+
def current_user
|
21
|
+
auth_session.user
|
22
|
+
end
|
23
|
+
|
24
|
+
# Set the currently logged in user
|
25
|
+
def current_user=(user)
|
26
|
+
if user.is_a?(Authie.config.user_model_class_name.constantize)
|
27
|
+
unless logged_in?
|
28
|
+
@auth_session = Session.start(self, :user => user)
|
29
|
+
end
|
30
|
+
@current_user = user
|
31
|
+
else
|
32
|
+
auth_session.destroy if logged_in?
|
33
|
+
@current_user = nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Is anyone currently logged in?
|
38
|
+
def logged_in?
|
39
|
+
auth_session.is_a?(Session)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return the currently logged in user session
|
43
|
+
def auth_session
|
44
|
+
@auth_session ||= Session.get_session(self)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Authie
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
|
4
|
+
initializer 'authie.initialize' do |app|
|
5
|
+
config.paths["db/migrate"].expanded.each do |expanded_path|
|
6
|
+
app.config.paths["db/migrate"] << expanded_path
|
7
|
+
end
|
8
|
+
|
9
|
+
ActiveSupport.on_load :active_record do
|
10
|
+
require 'authie/session'
|
11
|
+
end
|
12
|
+
|
13
|
+
ActiveSupport.on_load :action_controller do
|
14
|
+
require 'authie/controller_extension'
|
15
|
+
include Authie::ControllerExtension
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/lib/authie/error.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
module Authie
|
2
|
+
class Session < ActiveRecord::Base
|
3
|
+
|
4
|
+
# Define some errors which may be used
|
5
|
+
class InactiveSession < Error; end
|
6
|
+
class ExpiredSession < Error; end
|
7
|
+
class BrowserMismatch < Error; end
|
8
|
+
|
9
|
+
# Set table name
|
10
|
+
self.table_name = "authie_sessions"
|
11
|
+
|
12
|
+
# Relationships
|
13
|
+
belongs_to :user, :class_name => Authie.config.user_model_class_name, :foreign_key => 'user_id'
|
14
|
+
|
15
|
+
# Scopes
|
16
|
+
scope :active, -> { where(:active => true) }
|
17
|
+
scope :asc, -> { order(:last_activity_at => :desc) }
|
18
|
+
|
19
|
+
# Attributes
|
20
|
+
serialize :data, Hash
|
21
|
+
attr_accessor :controller
|
22
|
+
|
23
|
+
before_create do
|
24
|
+
self.token = SecureRandom.base64(32)
|
25
|
+
if controller
|
26
|
+
self.user_agent = controller.request.user_agent
|
27
|
+
set_cookie!
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
before_destroy do
|
32
|
+
cookies.delete(:user_session) if controller
|
33
|
+
end
|
34
|
+
|
35
|
+
# This method should be called each time a user performs an
|
36
|
+
# action while authenticated with this session.
|
37
|
+
def touch!
|
38
|
+
self.last_activity_at = Time.now
|
39
|
+
self.last_activity_ip = controller.request.ip
|
40
|
+
self.last_activity_path = controller.request.path
|
41
|
+
self.save!
|
42
|
+
end
|
43
|
+
|
44
|
+
# Sets the cookie on the associated controller.
|
45
|
+
def set_cookie!
|
46
|
+
cookies[:user_session] = {
|
47
|
+
:value => token,
|
48
|
+
:secure => controller.request.ssl?,
|
49
|
+
:httponly => true,
|
50
|
+
:expires => self.expires_at
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
# Check the security of the session to ensure it can be used.
|
55
|
+
def check_security!
|
56
|
+
if controller
|
57
|
+
if cookies[:browser_id] != self.browser_id
|
58
|
+
invalidate!
|
59
|
+
raise BrowserMismatch, "Browser ID mismatch"
|
60
|
+
end
|
61
|
+
|
62
|
+
unless self.active?
|
63
|
+
invalidate!
|
64
|
+
raise InactiveSession, "Session is no longer active"
|
65
|
+
end
|
66
|
+
|
67
|
+
if self.expires_at && self.expires_at < Time.now
|
68
|
+
invalidate!
|
69
|
+
raise ExpiredSession, "Persistent session has expired"
|
70
|
+
end
|
71
|
+
|
72
|
+
if self.expires_at.nil? && self.last_activity_at && self.last_activity_at < Authie.config.session_inactivity_timeout.ago
|
73
|
+
invalidate!
|
74
|
+
raise InactiveSession, "Non-persistent session has expired"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Allow this session to persist rather than expiring at the end of the
|
80
|
+
# current browser session
|
81
|
+
def persist!
|
82
|
+
self.expires_at = Authie.config.persistent_session_length.from_now
|
83
|
+
self.save!
|
84
|
+
set_cookie!
|
85
|
+
end
|
86
|
+
|
87
|
+
# Is this a persistent session?
|
88
|
+
def persistent?
|
89
|
+
!!expires_at
|
90
|
+
end
|
91
|
+
|
92
|
+
# Mark this session as invalid
|
93
|
+
def invalidate!
|
94
|
+
self.active = false
|
95
|
+
self.save!
|
96
|
+
if controller
|
97
|
+
cookies.delete(:user_session)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Set some additional data in this session
|
102
|
+
def set(key, value)
|
103
|
+
self.data ||= {}
|
104
|
+
self.data[key.to_s] = value
|
105
|
+
self.save!
|
106
|
+
end
|
107
|
+
|
108
|
+
# Get some additional data from this session
|
109
|
+
def get(key)
|
110
|
+
(self.data ||= {})[key.to_s]
|
111
|
+
end
|
112
|
+
|
113
|
+
# Find a session from the database for the given controller instance.
|
114
|
+
# Returns a session object or :none if no session is found.
|
115
|
+
def self.get_session(controller)
|
116
|
+
cookies = controller.send(:cookies)
|
117
|
+
if cookies[:user_session] && session = self.active.where(:token => cookies[:user_session]).first
|
118
|
+
session.controller = controller
|
119
|
+
session
|
120
|
+
else
|
121
|
+
cookies.delete(:user_session)
|
122
|
+
:none
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Create a new session and return the newly created session object.
|
127
|
+
# Any other sessions for the browser will be invalidated.
|
128
|
+
def self.start(controller, params = {})
|
129
|
+
cookies = controller.send(:cookies)
|
130
|
+
self.where(:browser_id => cookies[:browser_id]).each(&:invalidate!)
|
131
|
+
session = self.new(params)
|
132
|
+
session.controller = controller
|
133
|
+
session.browser_id = cookies[:browser_id]
|
134
|
+
session.login_at = Time.now
|
135
|
+
session.login_ip = controller.request.ip
|
136
|
+
session.save
|
137
|
+
session
|
138
|
+
end
|
139
|
+
|
140
|
+
# Cleanup any old sessions.
|
141
|
+
def self.cleanup
|
142
|
+
self.active.where("expires_at IS NULL AND last_activity_at < ?", Authie.config.session_inactivity_timeout.ago).each(&:invalidate!)
|
143
|
+
end
|
144
|
+
|
145
|
+
private
|
146
|
+
|
147
|
+
# Return all cookies on the associated controller
|
148
|
+
def cookies
|
149
|
+
controller.send(:cookies)
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: authie
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adam Cooke
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-12 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A Rails library for storing user sessions in a backend database
|
14
|
+
email:
|
15
|
+
- me@adamcooke.io
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- db/migrate/20141012174250_create_authie_sessions.rb
|
21
|
+
- lib/authie.rb
|
22
|
+
- lib/authie/config.rb
|
23
|
+
- lib/authie/controller_extension.rb
|
24
|
+
- lib/authie/engine.rb
|
25
|
+
- lib/authie/error.rb
|
26
|
+
- lib/authie/session.rb
|
27
|
+
- lib/authie/version.rb
|
28
|
+
homepage: https://github.com/adamcooke/authie
|
29
|
+
licenses:
|
30
|
+
- MIT
|
31
|
+
metadata: {}
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project:
|
48
|
+
rubygems_version: 2.2.2
|
49
|
+
signing_key:
|
50
|
+
specification_version: 4
|
51
|
+
summary: A Rails library for storing user sessions in a backend database
|
52
|
+
test_files: []
|
53
|
+
has_rdoc:
|