Class: Relevance::Tarantula::FormSubmission

Inherits:
Object
  • Object
show all
Includes:
Relevance::Tarantula
Defined in:
lib/relevance/tarantula/form_submission.rb

Constant Summary

Constants included from Relevance::Tarantula

VERSION

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Relevance::Tarantula

#log, #rails_root, #tarantula_home, #verbose

Constructor Details

#initialize(form, attack = Relevance::Tarantula::BasicAttack.new) ⇒ FormSubmission

Returns a new instance of FormSubmission



25
26
27
28
29
30
31
# File 'lib/relevance/tarantula/form_submission.rb', line 25

def initialize(form, attack = Relevance::Tarantula::BasicAttack.new)
  @form = form
  @method = form.method
  @action = form.action
  @attack = attack
  @data = mutate_selects(form).merge(mutate_text_areas(form)).merge(mutate_inputs(form))
end

Instance Attribute Details

#actionObject

Returns the value of attribute action



6
7
8
# File 'lib/relevance/tarantula/form_submission.rb', line 6

def action
  @action
end

#attackObject

Returns the value of attribute attack



6
7
8
# File 'lib/relevance/tarantula/form_submission.rb', line 6

def attack
  @attack
end

#dataObject

Returns the value of attribute data



6
7
8
# File 'lib/relevance/tarantula/form_submission.rb', line 6

def data
  @data
end

#formObject

Returns the value of attribute form



6
7
8
# File 'lib/relevance/tarantula/form_submission.rb', line 6

def form
  @form
end

#methodObject

Returns the value of attribute method



6
7
8
# File 'lib/relevance/tarantula/form_submission.rb', line 6

def method
  @method
end

Class Method Details

.attacksObject



9
10
11
12
13
14
15
# File 'lib/relevance/tarantula/form_submission.rb', line 9

def attacks
  # normalize from hash input to Attack
  @attacks = @attacks.map do |val|
    Hash === val ? Relevance::Tarantula::Attack.new(val) : val
  end
  @attacks
end

.attacks=(atts) ⇒ Object



16
17
18
19
20
21
# File 'lib/relevance/tarantula/form_submission.rb', line 16

def attacks=(atts)
  # normalize from hash input to Attack
  @attacks = atts.map do |val|
    Hash === val ? Relevance::Tarantula::Attack.new(val) : val
  end
end

.mutate(form) ⇒ Object



45
46
47
# File 'lib/relevance/tarantula/form_submission.rb', line 45

def self.mutate(form)
  attacks.map{|attack| new(form, attack)} if attacks
end

Instance Method Details

#crawlObject



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/relevance/tarantula/form_submission.rb', line 33

def crawl
  begin
    response = form.crawler.submit(method, action, data)
    log "Response #{response.code} for #{self}"
  rescue ActiveRecord::RecordNotFound => e
    log "Skipping #{action}, presumed ok that record is missing"
    response = Relevance::Tarantula::Response.new(:code => "404", :body => e.message, :content_type => "text/plain")
  end
  form.crawler.handle_form_results(self, response)
  response
end

#create_random_data_for(form, tag_selector) ⇒ Object



59
60
61
62
63
64
65
# File 'lib/relevance/tarantula/form_submission.rb', line 59

def create_random_data_for(form, tag_selector)
  form.search(tag_selector).inject({}) do |form_args, input|
    # TODO: test
    form_args[input['name']] = random_data(input) if input['name']
    form_args
  end
end

#mutate_inputs(form) ⇒ Object



67
68
69
# File 'lib/relevance/tarantula/form_submission.rb', line 67

def mutate_inputs(form)
  create_random_data_for(form, 'input')
end

#mutate_selects(form) ⇒ Object



75
76
77
78
79
80
81
82
# File 'lib/relevance/tarantula/form_submission.rb', line 75

def mutate_selects(form)
  form.search('select').inject({}) do |form_args, select|
    options = select.search('option')
    option = options.sample
    form_args[select['name']] = option['value']
    form_args
  end
end

#mutate_text_areas(form) ⇒ Object



71
72
73
# File 'lib/relevance/tarantula/form_submission.rb', line 71

def mutate_text_areas(form)
  create_random_data_for(form, 'textarea')
end

#random_data(input) ⇒ Object



84
85
86
87
88
89
90
# File 'lib/relevance/tarantula/form_submission.rb', line 84

def random_data(input)
  case input['name']
  when /^_method$/      then input['value']
  else
    attack.input(input)
  end
end

#signatureObject

a form's signature is what makes it unique (e.g. action + fields) used to keep track of which forms we have submitted already



55
56
57
# File 'lib/relevance/tarantula/form_submission.rb', line 55

def signature
  [action, data.keys.sort, attack.name]
end

#to_sObject



49
50
51
# File 'lib/relevance/tarantula/form_submission.rb', line 49

def to_s
  "#{action} #{method} #{data.inspect} #{attack.inspect}"
end