Class: Relevance::Tarantula::FormSubmission

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

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.



22
23
24
25
26
27
28
# File 'lib/relevance/tarantula/form_submission.rb', line 22

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.



3
4
5
# File 'lib/relevance/tarantula/form_submission.rb', line 3

def action
  @action
end

#attackObject

Returns the value of attribute attack.



3
4
5
# File 'lib/relevance/tarantula/form_submission.rb', line 3

def attack
  @attack
end

#dataObject

Returns the value of attribute data.



3
4
5
# File 'lib/relevance/tarantula/form_submission.rb', line 3

def data
  @data
end

#formObject

Returns the value of attribute form.



3
4
5
# File 'lib/relevance/tarantula/form_submission.rb', line 3

def form
  @form
end

#methodObject

Returns the value of attribute method.



3
4
5
# File 'lib/relevance/tarantula/form_submission.rb', line 3

def method
  @method
end

Class Method Details

.attacksObject



6
7
8
9
10
11
12
# File 'lib/relevance/tarantula/form_submission.rb', line 6

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



13
14
15
16
17
18
# File 'lib/relevance/tarantula/form_submission.rb', line 13

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



42
43
44
# File 'lib/relevance/tarantula/form_submission.rb', line 42

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

Instance Method Details

#crawlObject



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/relevance/tarantula/form_submission.rb', line 30

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



56
57
58
59
60
61
62
# File 'lib/relevance/tarantula/form_submission.rb', line 56

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



64
65
66
# File 'lib/relevance/tarantula/form_submission.rb', line 64

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

#mutate_selects(form) ⇒ Object



72
73
74
75
76
77
78
79
# File 'lib/relevance/tarantula/form_submission.rb', line 72

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

#mutate_text_areas(form) ⇒ Object



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

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

#random_data(input) ⇒ Object



81
82
83
84
85
86
87
# File 'lib/relevance/tarantula/form_submission.rb', line 81

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



52
53
54
# File 'lib/relevance/tarantula/form_submission.rb', line 52

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

#to_sObject



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

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