trabajo-afectivo/app/models/user_device.rb

212 lines
5.6 KiB
Ruby
Raw Normal View History

2016-10-19 03:11:36 +00:00
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
2015-08-17 13:25:41 +00:00
class UserDevice < ApplicationModel
store :device_details
store :location_details
validates :name, presence: true
=begin
store new device for user if device not already known
2015-08-17 13:25:41 +00:00
user_device = UserDevice.add(
2015-08-17 13:25:41 +00:00
'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,
2015-08-18 22:36:58 +00:00
'fingerprintABC123',
'session', # session|basic_auth|token_auth|sso
2015-08-17 13:25:41 +00:00
)
=end
2015-08-18 22:36:58 +00:00
def self.add(user_agent, ip, user_id, fingerprint, type)
2016-03-01 14:45:33 +00:00
# since gem browser 2 is not handling nil for user_agent, set it to ''
if user_agent.nil?
user_agent = ''
end
2015-08-18 22:36:58 +00:00
# get location info
location_details = Service::GeoIp.location(ip)
location = 'unknown'
if location_details && location_details['country_name']
location = location_details['country_name']
end
2015-08-18 22:36:58 +00:00
# find device by fingerprint
device_exists_by_fingerprint = false
2015-08-18 22:36:58 +00:00
if fingerprint
user_devices = UserDevice.where(
2015-08-18 22:36:58 +00:00
user_id: user_id,
fingerprint: fingerprint,
)
2016-06-30 20:04:48 +00:00
user_devices.each { |local_user_device|
device_exists_by_fingerprint = true
next if local_user_device.location != location
return action(local_user_device.id, user_agent, ip, user_id, type) if local_user_device
}
2015-08-18 22:36:58 +00:00
end
# for basic_auth|token_auth search for user agent
device_exists_by_user_agent = false
2015-08-18 22:36:58 +00:00
if type == 'basic_auth' || type == 'token_auth'
user_devices = UserDevice.where(
2015-08-18 22:36:58 +00:00
user_id: user_id,
user_agent: user_agent,
)
2016-06-30 20:04:48 +00:00
user_devices.each { |local_user_device|
device_exists_by_user_agent = true
next if local_user_device.location != location
return action(local_user_device.id, user_agent, ip, user_id, type) if local_user_device
}
2015-08-18 22:36:58 +00:00
end
2015-08-17 13:25:41 +00:00
# get browser details
2016-03-01 14:45:33 +00:00
browser = Browser.new(user_agent, accept_language: 'en-us')
2015-08-17 13:25:41 +00:00
browser = {
plattform: browser.platform.to_s.camelize,
name: browser.name,
version: browser.version,
full_version: browser.full_version,
}
# generate device name
if browser[:name] == 'Generic Browser'
browser[:name] = user_agent
end
2015-08-19 00:46:14 +00:00
name = ''
if browser[:plattform] && browser[:plattform] != 'Other'
name = browser[:plattform]
end
if browser[:name] && browser[:name] != 'Other'
if name && !name.empty?
2015-08-17 13:25:41 +00:00
name += ', '
end
name += browser[:name]
end
2015-08-18 22:36:58 +00:00
# if not identified, use user agent
2015-08-19 00:46:14 +00:00
if !name || name == '' || name == 'Other, Other' || name == 'Other'
2015-08-18 22:36:58 +00:00
name = user_agent
browser[:name] = user_agent
end
2015-08-17 13:25:41 +00:00
# check if exists
2015-08-21 21:53:53 +00:00
user_device = find_by(
2015-08-18 22:36:58 +00:00
user_id: user_id,
2015-08-17 13:25:41 +00:00
os: browser[:plattform],
browser: browser[:name],
2015-08-18 22:36:58 +00:00
location: location,
2016-04-11 07:35:27 +00:00
fingerprint: fingerprint,
2015-08-17 13:25:41 +00:00
)
2015-08-18 22:36:58 +00:00
if user_device
return action(user_device.id, user_agent, ip, user_id, type) if user_device
2015-08-17 13:25:41 +00:00
end
# create new device
2015-08-21 21:53:53 +00:00
user_device = create(
2015-08-17 13:25:41 +00:00
user_id: user_id,
name: name,
os: browser[:plattform],
browser: browser[:name],
2015-08-18 22:36:58 +00:00
location: location,
2015-08-17 13:25:41 +00:00
device_details: browser,
2015-08-18 22:36:58 +00:00
location_details: location_details,
user_agent: user_agent,
ip: ip,
fingerprint: fingerprint,
2015-08-17 13:25:41 +00:00
)
2015-08-18 22:36:58 +00:00
# send notification if needed
user_devices = UserDevice.where(user_id: user_id).count
if user_devices >= 2
# notify on now device of if country has changed
if device_exists_by_fingerprint || device_exists_by_user_agent
user_device.notification_send('user_device_new_location')
else
user_device.notification_send('user_device_new')
end
end
user_device
2015-08-18 22:36:58 +00:00
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,
'session', # session|basic_auth|token_auth|sso
2015-08-18 22:36:58 +00:00
)
=end
def self.action(user_device_id, user_agent, ip, user_id, type)
user_device = UserDevice.lookup(id: user_device_id)
2015-08-18 22:36:58 +00:00
# update location if needed
if user_device.ip != ip
user_device.ip = ip
location_details = Service::GeoIp.location(ip)
# if we do not have any data from backend (e. g. geo ip ist out of service), ignore log
if location_details && location_details['country_name']
user_device.location_details = location_details
location = location_details['country_name']
# notify if country has changed
if user_device.location != location
return UserDevice.add(
user_agent,
ip,
user_id,
user_device.fingerprint,
type,
)
end
end
2015-08-18 22:36:58 +00:00
end
# only update updated_at every 5 min.
return user_device if type != 'session' && (user_device.updated_at + 5.minutes) > Time.zone.now
2015-08-18 22:36:58 +00:00
# update attributes
user_device.updated_at = Time.zone.now # force update, also if no other attribute has changed
user_device.save!
2015-08-18 22:36:58 +00:00
user_device
2015-08-17 13:25:41 +00:00
end
=begin
send user notification about new device or new location for device
user_device = UserDevice.find(id)
user_device.notification_send('user_device_new_location')
=end
def notification_send(template)
user = User.find(user_id)
Rails.logger.debug "Send notification (#{template}) to: #{user.email}"
2016-04-13 23:40:37 +00:00
NotificationFactory::Mailer.notification(
template: template,
user: user,
objects: {
user_device: self,
user: user,
}
)
end
2015-08-17 13:25:41 +00:00
end