Last active
December 2, 2016 06:56
-
-
Save derwiki/0daeb4f18b13df59c776e6eae8f4bef7 to your computer and use it in GitHub Desktop.
Allowing users to see/sign out other sessions in Rails
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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