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).first 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).first 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