Skip to content

Instantly share code, notes, and snippets.

@derwiki
Last active December 2, 2016 06:56
Show Gist options
  • Select an option

  • Save derwiki/0daeb4f18b13df59c776e6eae8f4bef7 to your computer and use it in GitHub Desktop.

Select an option

Save derwiki/0daeb4f18b13df59c776e6eae8f4bef7 to your computer and use it in GitHub Desktop.
Allowing users to see/sign out other sessions in Rails
diff --git a/app/controllers/admin/profile_controller.rb b/app/controllers/admin/profile_controller.rb
index 29a7f9a..08a5ea9 100644
--- a/app/controllers/admin/profile_controller.rb
+++ b/app/controllers/admin/profile_controller.rb
@@ -24,6 +24,7 @@ class Admin::ProfileController < Admin::BaseController
def update_password
@user = current_user
if @user.update_with_password(params[:user])
+ other_sessions.destroy_all
flash.now[:success] = 'Password updated!'
sign_in @user, bypass: true
render 'update_password'
@@ -76,6 +77,11 @@ class Admin::ProfileController < Admin::BaseController
end
end
+ def sign_out_other_sessions
+ other_sessions.destroy_all
+ redirect_to edit_profile_path
+ end
+
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 51ca554..d7a1f93 100755
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -92,6 +92,18 @@ class ApplicationController < ActionController::Base
end
end
+ def active_session
+ @active_session ||=
+ current_user.user_sessions.find_by_session_id(session[:auth_id])
+ end
+ helper_method :active_session
+
+ def other_sessions
+ @other_sessions ||=
+ current_user.user_sessions.where.not(session_id: session[:auth_id])
+ end
+ helper_method :other_sessions
+
protected
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index eda56dd..074c9b8 100755
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -359,4 +359,10 @@ module ApplicationHelper
end
+ def geocode_ip_to_city(ip)
+ return unless (geocoded = Geocoder.search(ip).first)
+
+ [geocoded.city, geocoded.state_code, geocoded.country_code].join(', ')
+ end
+
end
diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb
new file mode 100644
index 0000000..67b7043
--- /dev/null
+++ b/app/helpers/profile_helper.rb
@@ -0,0 +1,10 @@
+module ProfileHelper
+ def readable_user_agent(user_session)
+ b = Browser.new(user_session.user_agent)
+ "#{b.name} on #{b.platform.name} #{b.platform.version}"
+ end
+
+ def show_sign_out_other_sessions?
+ current_user.user_sessions.count > 1
+ end
+end
diff --git a/app/views/admin/profile/edit.html.haml b/app/views/admin/profile/edit.html.haml
index 4850db7..9834b40 100644
--- a/app/views/admin/profile/edit.html.haml
+++ b/app/views/admin/profile/edit.html.haml
@@ -117,3 +117,7 @@
class: 'btn btn-default'
- else
= link_to 'Send a Text Instead', enable_two_factor_profile_path, remote: true, method: :post, class: 'btn btn-default'
+
+ .my-account-row
+ %h4 Active Sessions
+ = render 'shared/active_sessions_table'
--- /dev/null
+++ b/app/views/shared/_active_sessions_table.html.haml
@@ -0,0 +1,63 @@
+%table.table.user-session-table
+ %tr.tr.current-session
+ %td.td
+ %td.td
+ %strong Current Session
+ %td.td
+
+ %tr.tr.location
+ %td.td Location:
+ %td.td
+ - if (ip = geocode_ip_to_city(active_session.ip))
+ = ip
+ %span.text-muted (Approximate)
+ - else
+ .text-muted Can't determine location
+ %td.td
+
+ %tr.tr.ip-address
+ %td.td IP Address:
+ %td.td= active_session.ip
+ %td.td
+
+ %tr.tr.device-type
+ %td.td Device Type:
+ %td.td= readable_user_agent(active_session)
+ %td.td
+
+ - if show_sign_out_other_sessions?
+ %table.table.user-session-table
+ %tr.tr.other-active-sessions
+ %td.td
+ %td.td
+ %strong Other Active Sessions
+ %small
+ = link_to sign_out_other_sessions_profile_path, method: :post do
+ Sign out all
+ %td.td
+
+ - other_sessions.each do |user_session|
+ %tr.tr.signed-in-at
+ %td.td Signed In At:
+ %td.td= l user_session.updated_at, format: :compact
+ %td.td
+
+ %tr.tr.location
+ %td.td Location:
+ %td.td
+ - if (ip = geocode_ip_to_city(user_session.ip))
+ = ip
+ %span.text-muted (Approximate)
+ - else
+ .text-muted Can't determine location
+ %td.td
+
+ %tr.tr.ip-address
+ %td.td IP Address:
+ %td.td= user_session.ip
+ %td.td
+
+ %tr.tr.device-type
+ %td.td Device Type:
+ %td.td= readable_user_agent(user_session)
+ %td.td
diff --git a/config/routes.rb b/config/routes.rb
index 2b0d603..8e87007 100755
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -221,6 +221,7 @@ Rails.application.routes.draw do
+ post :sign_out_other_sessions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment