jam-cloud/ruby/lib/jam_ruby/models/download_tracker.rb

148 lines
5.2 KiB
Ruby

module JamRuby
class DownloadTracker < ActiveRecord::Base
@@log = Logging.logger[DownloadTracker]
belongs_to :user, :class_name => "JamRuby::User"
belongs_to :mixdown, :class_name => "JamRuby::JamTrackMixdownPackage", foreign_key: 'mixdown_id'
belongs_to :stem, :class_name => "JamRuby::JamTrackTrack", foreign_key: 'stem_id'
belongs_to :jam_track, :class_name => "JamRuby::JamTrack"
# one of mixdown or stem need to be specified. could validate this?
validates :user, presence:true
validates :remote_ip, presence: true
#validates :paid, presence: true
validates :jam_track, presence: :true
def self.create(user, remote_ip, target, owned, fingerprint, is_client)
dt = DownloadTracker.new
dt.user = user
dt.remote_ip = remote_ip
dt.paid = owned
dt.is_client = is_client
dt.fingerprint = fingerprint
if target.is_a?(JamTrack)
dt.jam_track_id = target.id
elsif target.is_a?(JamTrackTrack)
dt.jam_track_id = target.jam_track_id
elsif target.is_a?(JamTrackMixdownPackage)
dt.jam_track_id = target.jam_track_mixdown.jam_track_id
end
if !dt.save
@@log.error("unable to create Download Tracker: #{dt.errors.inspect}")
end
dt
end
def self.check(user, remote_ip, target, owned, fingerprint, is_client)
return false unless APP_CONFIG.guard_against_browser_fraud
return false if user.admin
return false if UserWhitelist.listed(user)
create(user, remote_ip, target, owned, fingerprint, is_client)
# let's check the following
blacklisted = alert_freebies_snarfer(remote_ip, owned)
alert_user_sharer(user)
blacklisted
end
# somebody who has shared account info with a large number of people
# high number of downloads of the same user from different IP addresses that were or were not paid for
# raw query created by this code:
# SELECT distinct(user_id), count(user_id) FROM "download_trackers" WHERE (created_at > NOW() - '30 days'::interval) GROUP BY user_id HAVING count(distinct(remote_ip)) >= 2
def self.check_user_sharer(max, user_id = nil)
query = DownloadTracker.select('distinct(user_id), count(user_id)')
query = query.where("created_at > NOW() - '#{APP_CONFIG.download_tracker_day_range} days'::interval")
if !user_id.nil?
query = query.where('user_id = ?', user_id)
end
query.group(:user_id).having("count(distinct(remote_ip)) >= #{max}")
end
# somebody who has figured out how to bypass cookie based method of identity checking, and is getting lots of free JamTracks
# high number of downloads of different jam tracks from different users for the same IP address that weren't paid for
# raw query created by this code:
# SELECT distinct(remote_ip), count(remote_ip) FROM "download_trackers" WHERE (paid = false) AND (created_at > NOW() - '30 days'::interval) GROUP BY remote_ip HAVING count(distinct(jam_track_id)) >= 2
def self.check_freebie_snarfer(max, remote_ip = nil)
query = DownloadTracker.select('distinct(remote_ip), count(remote_ip)').where("paid = false")
query = query.where("created_at > NOW() - '#{APP_CONFIG.download_tracker_day_range} days'::interval")
if !remote_ip.nil?
query = query.where('remote_ip = ?', remote_ip)
end
query.group(:remote_ip).having("count(distinct(jam_track_id)) >= #{max}")
end
def self.alert_user_sharer(user)
violation = check_user_sharer(APP_CONFIG.max_user_ip_address, user.id)[0]
if violation
body = "User has downloaded from too many IP addresses #{user.id}\n"
body << "Download Count: #{violation['count']}\n"
body << "User URL #{user.admin_url}\n"
body << "Add to blacklist: #{UserBlacklist.admin_url}"
AdminMailer.alerts({
subject:"Account IP Access Violation. USER: #{user.email}",
body:body
}).deliver_now
end
end
def self.alert_freebies_snarfer(remote_ip, owned)
if owned
return false
end
if !IpWhitelist.listed(remote_ip)
violation = check_freebie_snarfer(APP_CONFIG.max_multiple_users_same_ip, remote_ip)[0]
end
if violation
body = "IP Address: #{remote_ip}\n"
body << "Download Count: #{violation['count']}\n"
body << "Add to blacklist: #{IpBlacklist.admin_url}"
body << "Check Activity: #{IpBlacklist.admin_activity_url(remote_ip)}"
AdminMailer.alerts({
subject:"Single IP Access Violation. IP:#{remote_ip}",
body:body
}).deliver_now
# and now shut them down
if Rails.application.config.ban_jamtrack_downloaders
blacklist = IpBlacklist.new
blacklist.remote_ip = remote_ip
blacklist.notes = 'auto'
blacklist.save
return blacklist
end
end
return false
end
def admin_url
APP_CONFIG.admin_root_url + "/admin/download_trackers/" + id
end
def to_s
if stem?
"stem:#{stem} #{remote_ip} #{user}"
else
"mixdown:#{mixdown} #{remote_ip} #{user}"
end
end
end
end