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.
@@ -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
@@ -0,0 +1,4 @@
1
+ require 'authie/version'
2
+ require 'authie/engine'
3
+ require 'authie/config'
4
+ require 'authie/error'
@@ -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
@@ -0,0 +1,4 @@
1
+ module Authie
2
+ class Error < StandardError
3
+ end
4
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module Authie
2
+ VERSION = '1.0.0'
3
+ 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: