2015-10-23 19:42:51 +00:00
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 )
dt = DownloadTracker . new
dt . user = user
dt . remote_ip = remote_ip
dt . paid = owned
if 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 )
2015-10-26 21:03:43 +00:00
return unless APP_CONFIG . guard_against_browser_fraud
2015-10-23 19:42:51 +00:00
create ( user , remote_ip , target , owned )
# let's check the following
alert_freebies_snarfer ( remote_ip )
alert_user_sharer ( user )
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 "
2015-10-23 20:08:54 +00:00
body << " Add to blacklist: #{ UserBlacklist . admin_url } "
2015-10-23 19:42:51 +00:00
AdminMailer . alerts ( {
subject : " Account IP Access Violation. USER: #{ user . email } " ,
body : body
} ) . deliver
end
end
def self . alert_freebies_snarfer ( remote_ip )
violation = check_freebie_snarfer ( APP_CONFIG . max_multiple_users_same_ip , remote_ip ) . first
if violation
body = " IP Address: #{ remote_ip } \n "
body << " Download Count: #{ violation [ 'count' ] } \n "
2015-10-23 20:08:54 +00:00
body << " Add to blacklist: #{ IpBlacklist . admin_url } "
2015-10-23 19:42:51 +00:00
AdminMailer . alerts ( {
subject : " Single IP Access Violation. IP: #{ remote_ip } " ,
body : body
} ) . deliver
end
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