authie 1.0.0

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