Improved device logging.
This commit is contained in:
parent
2760137eef
commit
72bb0eb067
7 changed files with 145 additions and 38 deletions
|
@ -2,6 +2,7 @@ class App.Auth
|
|||
|
||||
@login: (params) ->
|
||||
App.Log.notice 'Auth', 'login', params
|
||||
params.data['fingerprint'] = App.Browser.fingerprint()
|
||||
App.Ajax.request(
|
||||
id: 'login'
|
||||
type: 'POST'
|
||||
|
@ -21,12 +22,15 @@ class App.Auth
|
|||
)
|
||||
|
||||
@loginCheck: ->
|
||||
params =
|
||||
fingerprint: App.Browser.fingerprint()
|
||||
App.Log.debug 'Auth', 'loginCheck'
|
||||
App.Ajax.request(
|
||||
id: 'login_check'
|
||||
async: false
|
||||
type: 'GET'
|
||||
type: 'POST'
|
||||
url: App.Config.get('api_path') + '/signshow'
|
||||
data: JSON.stringify(params)
|
||||
success: (data, status, xhr) =>
|
||||
|
||||
# set login (config, session, ...)
|
||||
|
|
|
@ -14,10 +14,10 @@ class ApplicationController < ActionController::Base
|
|||
:model_index_render
|
||||
|
||||
skip_before_action :verify_authenticity_token
|
||||
before_action :set_user, :session_update, :check_user_device
|
||||
before_action :set_user, :session_update
|
||||
before_action :cors_preflight_check
|
||||
|
||||
after_action :set_access_control_headers
|
||||
after_action :user_device_update, :set_access_control_headers
|
||||
after_action :trigger_events
|
||||
|
||||
# For all responses in this controller, return the CORS access control headers.
|
||||
|
@ -95,8 +95,8 @@ class ApplicationController < ActionController::Base
|
|||
session[:user_agent] = request.env['HTTP_USER_AGENT']
|
||||
end
|
||||
|
||||
# check user device
|
||||
def check_user_device
|
||||
# user device recent action update
|
||||
def user_device_update
|
||||
|
||||
# return if we are in switch to user mode
|
||||
return if session[:switched_from_user_id]
|
||||
|
@ -104,21 +104,46 @@ class ApplicationController < ActionController::Base
|
|||
# only if user_id exists
|
||||
return if !session[:user_id]
|
||||
|
||||
# only if write action
|
||||
# only with user device
|
||||
if !session[:user_device_id]
|
||||
if params[:fingerprint]
|
||||
return false if !user_device_log(current_user, 'session')
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
# check if entry exists / only if write action
|
||||
return if request.method == 'GET' || request.method == 'OPTIONS'
|
||||
|
||||
# only update if needed
|
||||
return if session[:check_user_device_at] && session[:check_user_device_at] > Time.zone.now - 5.minutes
|
||||
session[:check_user_device_at] = Time.zone.now
|
||||
return if session[:user_device_update_at] && session[:user_device_update_at] > Time.zone.now - 5.minutes
|
||||
session[:user_device_update_at] = Time.zone.now
|
||||
|
||||
user_device = UserDevice.add(
|
||||
UserDevice.action(
|
||||
session[:user_device_id],
|
||||
session[:user_agent],
|
||||
session[:remote_id],
|
||||
session[:user_id],
|
||||
)
|
||||
if user_device.id != session[:check_user_device_id]
|
||||
session[:check_user_device_id] = user_device.id
|
||||
end
|
||||
|
||||
def user_device_log(user, type)
|
||||
|
||||
# for sessions we need the fingperprint
|
||||
if !params[:fingerprint] && type == 'session'
|
||||
render json: { error: 'Need fingerprint param!' }, status: :unprocessable_entity
|
||||
return false
|
||||
end
|
||||
|
||||
# add defice if needed
|
||||
user_device = UserDevice.add(
|
||||
request.env['HTTP_USER_AGENT'],
|
||||
request.remote_ip,
|
||||
user.id,
|
||||
params[:fingerprint],
|
||||
type,
|
||||
)
|
||||
session[:user_device_id] = user_device.id
|
||||
end
|
||||
|
||||
def authentication_check_only(auth_param)
|
||||
|
@ -130,7 +155,8 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
# already logged in, early exit
|
||||
if session.id && session[:user_id]
|
||||
userdata = User.find( session[:user_id] )
|
||||
|
||||
userdata = User.find(session[:user_id])
|
||||
current_user_set(userdata)
|
||||
|
||||
return {
|
||||
|
@ -143,11 +169,10 @@ class ApplicationController < ActionController::Base
|
|||
# check sso
|
||||
sso_userdata = User.sso(params)
|
||||
if sso_userdata
|
||||
session[:persistent] = true
|
||||
|
||||
current_user_set(sso_userdata)
|
||||
|
||||
session[:persistent] = true
|
||||
|
||||
return {
|
||||
auth: true
|
||||
}
|
||||
|
@ -161,8 +186,9 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
next if !userdata
|
||||
|
||||
# set basic auth user to current user
|
||||
current_user_set(userdata)
|
||||
user_device_log(userdata, 'basic_auth')
|
||||
|
||||
return {
|
||||
auth: true
|
||||
}
|
||||
|
@ -180,8 +206,8 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
next if !userdata
|
||||
|
||||
# set token user to current user
|
||||
current_user_set(userdata)
|
||||
user_device_log(userdata, 'token_auth')
|
||||
|
||||
return {
|
||||
auth: true
|
||||
|
@ -216,9 +242,6 @@ class ApplicationController < ActionController::Base
|
|||
return false
|
||||
end
|
||||
|
||||
# store current user id into the session
|
||||
session[:user_id] = current_user.id
|
||||
|
||||
# return auth ok
|
||||
true
|
||||
end
|
||||
|
|
|
@ -30,6 +30,9 @@ class SessionsController < ApplicationController
|
|||
# set session user
|
||||
current_user_set(user)
|
||||
|
||||
# log device
|
||||
return if !user_device_log(user, 'session')
|
||||
|
||||
# log new session
|
||||
user.activity_stream_log( 'session started', user.id, true )
|
||||
|
||||
|
@ -85,6 +88,9 @@ class SessionsController < ApplicationController
|
|||
# subsequent requests
|
||||
user = User.find( user_id )
|
||||
|
||||
# log device
|
||||
return if !user_device_log(user, 'session')
|
||||
|
||||
# auto population of default collections
|
||||
collections, assets = SessionHelper.default_collections(user)
|
||||
|
||||
|
|
|
@ -4,18 +4,18 @@ class UserDevicesController < ApplicationController
|
|||
before_action :authentication_check
|
||||
|
||||
def index
|
||||
devices = UserDevice.where(user_id: current_user.id).order('updated_at DESC')
|
||||
devices = UserDevice.where(user_id: current_user.id).order('created_at DESC')
|
||||
devices_full = []
|
||||
devices.each {|device|
|
||||
attributes = device.attributes
|
||||
if device.location_details['city']
|
||||
attributes['location'] += ", #{device.location_details['city']}"
|
||||
if device.location_details['city_name']
|
||||
attributes['location'] += ", #{device.location_details['city_name']}"
|
||||
end
|
||||
attributes.delete('created_at')
|
||||
attributes.delete('device_details')
|
||||
attributes.delete('location_details')
|
||||
|
||||
if session[:check_user_device_id] == device.id
|
||||
if session[:user_device_id] == device.id
|
||||
attributes['current'] = true
|
||||
end
|
||||
devices_full.push attributes
|
||||
|
@ -24,6 +24,7 @@ class UserDevicesController < ApplicationController
|
|||
end
|
||||
|
||||
def destroy
|
||||
|
||||
# find device
|
||||
user_device = UserDevice.find_by(user_id: current_user.id, id: params[:id])
|
||||
|
||||
|
@ -31,8 +32,8 @@ class UserDevicesController < ApplicationController
|
|||
if user_device
|
||||
SessionHelper.list.each {|session|
|
||||
next if !session.data['user_id']
|
||||
next if !session.data['check_user_device_id']
|
||||
next if session.data['check_user_device_id'] != user_device.id
|
||||
next if !session.data['user_device_id']
|
||||
next if session.data['user_device_id'] != user_device.id
|
||||
SessionHelper.destroy( session.id )
|
||||
}
|
||||
user_device.destroy
|
||||
|
|
|
@ -13,11 +13,37 @@ store device for user
|
|||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.107 Safari/537.36',
|
||||
'172.0.0.1',
|
||||
user.id,
|
||||
'fingerprintABC123',
|
||||
'session', # session|basic_auth|token_auth|sso
|
||||
)
|
||||
|
||||
=end
|
||||
|
||||
def self.add(user_agent, ip, user_id)
|
||||
def self.add(user_agent, ip, user_id, fingerprint, type)
|
||||
|
||||
# get location info
|
||||
location_details = Service::GeoIp.location(ip)
|
||||
location = location_details['country_name']
|
||||
|
||||
# find device by fingerprint
|
||||
if fingerprint
|
||||
user_device = UserDevice.find_by(
|
||||
user_id: user_id,
|
||||
fingerprint: fingerprint,
|
||||
location: location,
|
||||
)
|
||||
return action(user_device.id, user_agent, ip, user_id) if user_device
|
||||
end
|
||||
|
||||
# for basic_auth|token_auth search for user agent
|
||||
if type == 'basic_auth' || type == 'token_auth'
|
||||
user_device = UserDevice.find_by(
|
||||
user_id: user_id,
|
||||
user_agent: user_agent,
|
||||
location: location,
|
||||
)
|
||||
return action(user_device.id, user_agent, ip, user_id) if user_device
|
||||
end
|
||||
|
||||
# get browser details
|
||||
browser = Browser.new(:ua => user_agent, :accept_language => 'en-us')
|
||||
|
@ -37,21 +63,22 @@ store device for user
|
|||
name += browser[:name]
|
||||
end
|
||||
|
||||
# get location info
|
||||
location = Service::GeoIp.location(ip)
|
||||
country = location['country_name']
|
||||
# if not identified, use user agent
|
||||
if name == 'Other, Other'
|
||||
name = user_agent
|
||||
browser[:name] = user_agent
|
||||
end
|
||||
|
||||
# check if exists
|
||||
exists = self.find_by(
|
||||
:user_id => user_id,
|
||||
user_device = self.find_by(
|
||||
user_id: user_id,
|
||||
os: browser[:plattform],
|
||||
browser: browser[:name],
|
||||
location: country,
|
||||
location: location,
|
||||
)
|
||||
|
||||
if exists
|
||||
exists.touch
|
||||
return exists
|
||||
if user_device
|
||||
return action(user_device.id, user_agent, ip, user_id) if user_device
|
||||
end
|
||||
|
||||
# create new device
|
||||
|
@ -60,10 +87,45 @@ store device for user
|
|||
name: name,
|
||||
os: browser[:plattform],
|
||||
browser: browser[:name],
|
||||
location: country,
|
||||
location: location,
|
||||
device_details: browser,
|
||||
location_details: location,
|
||||
location_details: location_details,
|
||||
user_agent: user_agent,
|
||||
ip: ip,
|
||||
fingerprint: fingerprint,
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
log user device action
|
||||
|
||||
UserDevice.action(
|
||||
user_device_id,
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.107 Safari/537.36',
|
||||
'172.0.0.1',
|
||||
user.id,
|
||||
)
|
||||
|
||||
=end
|
||||
|
||||
def self.action(user_device_id, user_agent, ip, user_id)
|
||||
user_device = UserDevice.find(user_device_id)
|
||||
|
||||
# update location if needed
|
||||
if user_device.ip != ip
|
||||
user_device.ip = ip
|
||||
location_details = Service::GeoIp.location(ip)
|
||||
user_device.location_details = location_details
|
||||
|
||||
location = location_details['country_name']
|
||||
user_device.location = location
|
||||
end
|
||||
|
||||
# update attributes
|
||||
user_device.save
|
||||
user_device
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ Zammad::Application.routes.draw do
|
|||
|
||||
# sessions
|
||||
match api_path + '/signin', to: 'sessions#create', via: :post
|
||||
match api_path + '/signshow', to: 'sessions#show', via: :get
|
||||
match api_path + '/signshow', to: 'sessions#show', via: [:get, :post]
|
||||
match api_path + '/signout', to: 'sessions#destroy', via: [:get, :delete]
|
||||
|
||||
match api_path + '/sessions/switch/:id', to: 'sessions#switch_to_user', via: :get
|
||||
|
|
11
db/migrate/20150818000001_update_user_devices2.rb
Normal file
11
db/migrate/20150818000001_update_user_devices2.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
class UpdateUserDevices2 < ActiveRecord::Migration
|
||||
def up
|
||||
add_column :user_devices, :user_agent, :string, limit: 250, null: true
|
||||
add_column :user_devices, :ip, :string, limit: 160, null: true
|
||||
add_column :user_devices, :fingerprint, :string, limit: 160, null: true
|
||||
add_index :user_devices, [:fingerprint]
|
||||
add_index :user_devices, [:created_at]
|
||||
UserDevice.reset_column_information
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue