Commit be11ff52
Changed files (7)
app
controllers
models
views
sessions
spec
controllers
app/controllers/application_controller.rb
@@ -6,8 +6,8 @@ class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
helper_method :current_user, :user_signed_in?
- def user_session(session_id = cookies.signed[:cookie_monster])
- UserSession.find_by(id: session_id)
+ def user_session(session_key = cookies.signed[:cookie_monster])
+ UserSession.authenticate(session_key)
end
def current_user
app/controllers/sessions_controller.rb
@@ -5,7 +5,8 @@ class SessionsController < ApplicationController
def create
if @session = UserSession.login(session_params[:username], session_params[:password])
- cookies.signed[:cookie_monster] = @session.id
+ @session.access(request)
+ cookies.signed[:cookie_monster] = @session.key
redirect_to my_dashboard_path
else
flash[:error] = "invalid credentials"
app/models/user_session.rb
@@ -1,7 +1,31 @@
class UserSession < ActiveRecord::Base
belongs_to :user
+ before_validation :set_unique_key
+ scope :active, -> { where("accessed_at >= ?", 2.weeks.ago).where(revoked_at: nil) }
+
+ def revoke!
+ self.revoked_at = Time.now
+ save!
+ end
+
+ def access(request)
+ self.accessed_at = Time.now
+ self.ip = request.ip
+ self.user_agent = request.user_agent
+ save
+ end
+
+ private
+
+ def set_unique_key
+ self.key = SecureRandom.urlsafe_base64(32)
+ end
class << self
+ def authenticate(key)
+ self.active.find_by(key: key)
+ end
+
def login(username, password)
user = User.find_by(email: username)
return false if user.nil?
app/views/sessions/new.html.erb
@@ -25,7 +25,7 @@
</div>
</div>
<div class="span6">
- <%= form_for(@session, html: { class: "well form-inline"}) do |f| %>
+ <%= form_for(@session, url: sessions_path(@session), html: { class: "well form-inline"}) do |f| %>
<legend>Got an account? Login!</legend>
<%= email_field_tag 'session[username]', '', :placeholder => 'Email', :class=> "input-medium" %>
<%= password_field_tag 'session[password]', '', :placeholder => 'Password', :class=> "input-medium" %>
db/migrate/20140814031349_add_accessed_at_and_revoked_at_to_user_sessions.rb
@@ -0,0 +1,11 @@
+class AddAccessedAtAndRevokedAtToUserSessions < ActiveRecord::Migration
+ def change
+ change_table :user_sessions do |t|
+ t.column :key, :string
+ t.column :ip, :string
+ t.column :user_agent, :string
+ t.column :accessed_at, :datetime
+ t.column :revoked_at, :datetime, null: true
+ end
+ end
+end
db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20140814030250) do
+ActiveRecord::Schema.define(version: 20140814031349) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -162,6 +162,11 @@ ActiveRecord::Schema.define(version: 20140814030250) do
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
+ t.string "key"
+ t.string "ip"
+ t.string "user_agent"
+ t.datetime "accessed_at"
+ t.datetime "revoked_at"
end
create_table "users", force: true do |t|
spec/controllers/sessions_controller_spec.rb
@@ -22,7 +22,7 @@ describe SessionsController do
it "returns a valid session" do
expect(cookies.signed[:cookie_monster]).to_not be_nil
- expect(cookies.signed[:cookie_monster]).to eql(user_session.id)
+ expect(cookies.signed[:cookie_monster]).to eql(user_session.key)
end
it "redirects to the dashboard" do