2013-02-01 03:48:27 +00:00
class MacsController < ApplicationController
2013-02-01 10:37:30 +00:00
load_and_authorize_resource :mac , :except = > [ :index , :scan , :import ]
load_and_authorize_resource :user , :through = > :mac , :except = > [ :index , :show , :scan , :import ]
2013-02-01 03:33:40 +00:00
#require "active_record"
require " optparse "
#require "rubygems"
def index
2013-02-01 10:37:30 +00:00
#@active_macs = Mac.where(:active => true, :hidden => false)
#@active_macs += Mac.where(:active => true, :hidden => nil)
# De-dupe users for the public
if can? :update , Mac then
@active_macs = Mac . where ( " macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?) " , true , false ) . includes ( :user ) . order ( " users.name ASC " )
2013-02-01 10:58:26 +00:00
elsif user_signed_in? then
2013-02-01 10:37:30 +00:00
@active_macs = Mac . where ( " macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?) " , true , false ) . includes ( :user ) . order ( " users.name ASC " ) . group ( " users.name " )
2013-02-01 10:58:26 +00:00
else
@active_macs = Mac . select ( " mac, note, user_id " ) . where ( " macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?) " , true , false ) . joins ( :user ) . order ( " users.name ASC " ) . group ( " users.name " )
2013-02-01 10:37:30 +00:00
end
@hidden_macs = Mac . where ( " macs.active = ? AND macs.hidden = ? " , true , true ) . order ( " note ASC " )
2013-02-01 07:06:13 +00:00
@all_macs = Mac . find ( :all , :order = > " LOWER(mac) " )
2013-02-01 10:58:26 +00:00
respond_to do | format |
format . html
format . json {
2013-02-09 12:05:06 +00:00
@filtered_macs = Mac . select ( " macs.mac, users.name, macs.note " ) . where ( " macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?) " , true , false ) . joins ( :user )
2013-02-01 10:58:26 +00:00
render :json = > @filtered_macs
}
end
2013-02-01 03:33:40 +00:00
end
# GET /macs/1
# GET /macs/1.json
def show
@mac = Mac . find ( params [ :id ] )
respond_to do | format |
format . html # show.html.erb
format . json { render :json = > @macs }
end
end
# GET /macs/new
# GET /macs/new.json
def new
@mac = Mac . new
2013-02-01 10:37:30 +00:00
if can? :manage , Mac then
@users = User . accessible_by ( current_ability ) . sort_by ( & :name )
else
@users = [ current_user ]
end
2013-02-01 03:33:40 +00:00
respond_to do | format |
format . html # new.html.erb
format . json { render :json = > @mac }
end
end
# GET /macs/1/edit
def edit
@mac = Mac . find ( params [ :id ] )
2013-02-01 10:37:30 +00:00
if can? :manage , Mac then
@users = User . accessible_by ( current_ability ) . sort_by ( & :name )
else
@users = [ current_user ]
end
2013-02-01 03:33:40 +00:00
end
# POST /macs
# POST /user
def create
@mac = Mac . new ( params [ :mac ] )
2013-02-01 10:37:30 +00:00
authorize! :update , @mac
if can? :manage , Mac then
@users = User . accessible_by ( current_ability ) . sort_by ( & :name )
else
@users = [ current_user ]
end
2013-02-01 03:33:40 +00:00
respond_to do | format |
if @mac . save
2013-02-01 03:48:27 +00:00
format . html { redirect_to macs_path , :notice = > 'Mac was successfully created.' }
2013-02-01 03:33:40 +00:00
format . json { render :json = > @mac , :status = > :created , :location = > @mac }
else
format . html { render :action = > " new " }
format . json { render :json = > @mac . errors , :status = > :unprocessable_entity }
end
end
end
# PUT /macs/1
# PUT /macs/1.json
def update
#Log who updated this
@mac = Mac . find ( params [ :id ] )
2013-02-09 09:08:29 +00:00
@mac . assign_attributes ( params [ :mac ] )
#@mac.user_id = params[:mac][:user_id]
2013-02-01 10:37:30 +00:00
authorize! :update , @mac
if can? :manage , Mac then
@users = User . accessible_by ( current_ability ) . sort_by ( & :name )
else
@users = [ current_user ]
end
2013-02-01 03:33:40 +00:00
respond_to do | format |
2013-02-01 10:37:30 +00:00
if @mac . save
2013-02-01 07:06:13 +00:00
format . html { redirect_to macs_path , :notice = > 'Mac was successfully updated.' }
2013-02-01 03:33:40 +00:00
format . json { head :no_content }
else
format . html { render :action = > " edit " }
format . json { render :json = > @mac . errors , :status = > :unprocessable_entity }
end
end
end
def scan
Rails . logger . info " starting scan... "
# Command line arguments
options = { } ;
OptionParser . new { | opts |
opts . banner = " Usage: pamela-scanner.rb --interface=en0 "
options [ :verbose ] = true
opts . on ( " v " , " --verbose " , " Run verbosely " ) { | verbose |
options [ :verbose ] = verbose
}
options [ :interface ] = " eth0 "
opts . on ( " i " , " --interface=interface " , " Network Interface " ) { | interface |
options [ :interface ] = interface
}
options [ :max_age ] = 20
opts . on ( " a " , " --max-age=minutes " , " Minutes to keep expired macs active " ) { | max_age |
options [ :max_age ] = max_age . to_i
}
options [ :db_host ] = " configure_me "
opts . on ( " r " , " --db-host=host " , " Database Host " ) { | host |
options [ :db_host ] = host
}
options [ :db_name ] = " configure_me "
opts . on ( " n " , " --db-name=name " , " Database Name " ) { | name |
options [ :db_name ] = name
}
options [ :db_user ] = " configure_me "
opts . on ( " u " , " --db-user=user " , " Database User " ) { | user |
options [ :db_user ] = user
}
options [ :db_password ] = " configure_me "
opts . on ( " p " , " --db-password=password " , " Database Password " ) { | password |
options [ :db_password ] = password
}
} . parse!
# Open the database
#ActiveRecord::Base::establish_connection(
# :adapter => "mysql2",
# :host => options[:db_host],
# :database => options[:db_name],
# :username => options[:db_user],
# :password => options[:db_password])
#class Mac < ActiveRecord::Base
#end
#class MacLog < ActiveRecord::Base
#end
# Scan the network for mac addresses
macs = { } ;
command = sprintf ( " arp-scan -R --interface=%s --localnet " , options [ :interface ] )
if options [ :verbose ]
Rails . logger . info " Running [ #{ command } ] "
end
IO . popen ( command ) { | stdin |
Rails . logger . info " Reading stdin: " + stdin . inspect
stdin . each { | line |
next if line !~ / ^([ \ d \ .]+) \ s+([[:xdigit:]:]+) \ s / ;
macs [ $2 ] = $1 ;
}
}
# Scan the existing macs and update each record as necessary
Mac . find ( :all ) . each { | entry |
2013-02-01 07:06:13 +00:00
mac = entry . mac . downcase
2013-02-01 03:33:40 +00:00
ip = entry . ip
if macs . has_key? ( mac )
if ! entry . active || ! entry . since
Rails . logger . info " Activating #{ mac } at #{ ip } " if options [ :verbose ]
entry . since = Time . now
MacLog . new ( :mac = > mac , :ip = > ip , :action = > " activate " ) . save
end
entry . active = 1
entry . ip = ip
entry . refreshed = Time . now
entry . save
macs . delete ( mac )
next
end
# Entry is no longer current
if entry . active
ageMinutes = ( ( Time . now - entry . refreshed ) / 60 ) . to_i
next if ageMinutes < options [ :max_age ]
Rails . logger . info " Deactivating #{ mac } , #{ ageMinutes } minutes old " if options [ :verbose ]
entry . active = 0
entry . save
MacLog . new ( :mac = > mac , :ip = > ip , :action = > " deactivate " ) . save
end
}
# Add entries for any macs not already in the db
macs . each { | mac , ip |
Rails . logger . info " Activating new entry #{ mac } at #{ ip } " if options [ :verbose ]
Mac . new ( :mac = > mac , :ip = > ip , :active = > 1 , :since = > Time . now , :refreshed = > Time . now ) . save
2013-02-01 07:06:13 +00:00
Rails . logger . info MacLog . new ( :mac = > mac , :ip = > ip , :action = > " activate " ) . save
2013-02-01 03:33:40 +00:00
}
@log = MacLog . all
end #def scan
2013-02-01 07:06:13 +00:00
def import
require 'csv'
csv_text = File . read ( 'mac_log.csv' )
csv = CSV . parse ( csv_text )
@output = [ ]
csv . each do | row |
@output += [ row [ 1 ] , Mac . create ( { :mac = > row [ 0 ] , :note = > row [ 1 ] , :hidden = > row [ 2 ] } ) ]
end
end
2013-02-01 03:33:40 +00:00
end