ZAP automation :undefined method `[]' for nil:NilClass (NoMethodError) - ruby

ZAP automation :undefined method `[]' for nil:NilClass (NoMethodError)
I am getting the above error while trying to get the response of zap using ruby. below is my code:
Then(/^I should be able to see security warnings$/) do
#Get response from via RestClient framework method.
begin
response = JSON.parse RestClient.get "http://#{$zap_proxy}:#{$zap_proxy_port}/json/core/view/alerts"
rescue RestClient::ServerBrokeConnection
#Classify the alerts
events = response['alerts']
high_risks = events.select{|x| x['risk'] == 'High'}
high_count = high_risks.size
medium_count = events.select{|x| x['risk'] == 'Medium'}.size
low_count = events.select{|x| x['risk'] == 'Low'}.size
informational_count = events.select{|x| x['risk'] == 'Informational'}.size
end
#Check high alert count and print them
if high_count > 0
high_risks.each { |x| p x['alert'] }
end
#Expect high alert count equal to 0
expect(high_count).to eq 0
#Print alerts with risk levels
site = Capybara.app_host
response = JSON.parse RestClient.get "http://#{$zap_proxy}:#{$zap_proxy_port}/json/core/view/alerts",
params: { zapapiformat: 'JSON', baseurl: site }
response['alerts'].each { |x| p "#{x['alert']} risk level: #{x['risk']}"}
end
some one please help me. my intention is to print the security alerts and display them on my command prompt

I think you have nil value in events and you try to get value x['...'] from nil .
it would take a little more detail including the line.
edit:
try events = response['alerts'].reject { |x| x.nil? }

Related

Ruby - no implicit conversion of Array into String

I am getting an error when executing my test.
Failure/Error: expect(industry_sic_code).to include page.sic_code
TypeError:
no implicit conversion of Array into String
# ./spec/os/bal/company/company_filter_clean_harbors_industries_stub.rb:62:in `block (2 levels) in <top (required)>'
The Method:
def sic_code
subtables = #b.table(:class => 'industry-codes').tables(:class => 'industry-code-table')
subtables.each do |subtable|
if subtable.tbody.h4.text == "US SIC 1987:"
subtable.tr.next_siblings.each do |tr|
codes = tr.cell
puts codes.text.to_s
end
end
end
end
The Test:
it 'Given I search for a random Clean Harbors Industry' do
#Pick a random clean industry from the file
data = CSV.foreach(file_path, headers: true).map{ |row| row.to_h }
random = data.sample
random_industry = random["Class"]
industry_sic_code = random["SIC Code"]
end
it 'Then the result has the expected SIC code' do
page = DetailPage.new(#b)
page.view
expect(industry_sic_code).to include page.sic_code
end
I have tried to implicitly change each variable to a string but it still complain about the array issue.
When I include some puts statments, I get some really wonky responses. The method itself returns the expected result.
When I used the method in the test I end up with the code gibberish below.
here are the sic codes from the method
5511
Here are the codes from the test
#<Watir::Table:0x00007fa3cb23f020>
#<Watir::Table:0x00007fa3cb23ee40>
#<Watir::Table:0x00007fa3cb23ec88>
#<Watir::Table:0x00007fa3cb23ead0>
#<Watir::Table:0x00007fa3cb23e918>
#<Watir::Table:0x00007fa3cb23e738>
#<Watir::Table:0x00007fa3cb23e580>
Your sic_code method returns subtables array, that's why you have this error. It doesn't matter that the method puts something, every method in ruby implicitly returns result of its last line, in your case it is subtables.each do ... end, so you have an array.
You need to explicitly return needed value. Not sure if I correctly understood what are you doing in your code, but try something like this:
def sic_code
subtables = #b.table(:class => 'industry-codes').tables(:class => 'industry-code-table')
result = [] # you need to collect result somewhere to return it later
subtables.each do |subtable|
if subtable.tbody.h4.text == "US SIC 1987:"
subtable.tr.next_siblings.each do |tr|
codes = tr.cell
result << codes.text.to_s
end
end
end
result.join(', ')
end

Undefined method when trying to square each element in array

I am trying to write a method called square_digits that squares every digit in a given number. I wrote:
def square_digits(num)
number_array = num.to_s.split("")
num_to_int = number_array.to_i
num_squared = num_to_int.each{|n| n**2}
return num_squared.join("")
end
When trying to run square_digits(3212), which should return 9414, I get the following error message:
`block in square_digits': undefined method `**' for "3":String (NoMethodError)
from `each'
from `square_digits'
from `
'
I'm not quite sure what I should do to fix it; any suggestions?
Hmm there are a few problems here:
With the input 123 it should error on:
num_to_int = number_array.to_i
With:
NoMethodError: undefined method 'to_i' for ["1","2","3"]:Array
You want:
num_to_int = number_array.map(&:to_i)
Also
num_squared = num_to_int.each{|n| n**2}
doesn't return the results of each just the original array.
So with the first fix it will just return "123"
you want:
num_squared = num_to_int.map{|n| n**2}
So the final function looks like:
def square_digits(num)
number_array = num.to_s.split("")
num_to_int = number_array.map(&:to_i)
num_squared = num_to_int.map{|n| n**2}
return num_squared.join("")
end
Although i'm confused about what you are trying to achieve.
You can also try this ;)
def square_digits(num)
num.to_s.split('').map { |n| n.to_i ** 2 }.join("")
end
Or
def square_digits(num)
num.to_s.chars.map { |n| n.to_i ** 2 }.join("")
end

NoMethodError in from Mechanize

running this code with mecahnize 2.7.3 and ruby 2.3.0dev:
require 'mechanize'
agent = Mechanize.new
agent.keep_alive = false
agent.open_timeout = 2
agent.read_timeout = 2
agent.ignore_bad_chunking = true
agent.gzip_enabled = false
url = 'http:%5C%5Cwww.scouts.org.uk'
agent.head(url)
Gives me this NoMethodError:
~/.rvm/gems/ruby-head/gems/mechanize-2.7.3/lib/mechanize/http/agent.rb:648:in resolve': undefined
methodlength' for nil:NilClass (NoMethodError)
from ~/.rvm/gems/ruby-head/gems/mechanize-2.7.3/lib/mechanize/http/agent.rb:223:in `fetch'
from ~/.rvm/gems/ruby-head/gems/mechanize-2.7.3/lib/mechanize.rb:459:in `head
Is this a bug in mechanize or am I doing something wrong? If so how can it be fixed?
EDIT: the url is obviously worng, but im reading a lot of urls from a file and some of them might be wrong.
EDIT2: lets say I have a file like this http://pastie.org/9934756
I need to get the head of all the urls that are correct and ignore the others
You write a wrong url, try this: url = 'http://scouts.org.uk'
Your target site is doing a redirect and uses meta refresh. Update your code to include those methods:
require 'mechanize'
agent = Mechanize.new
agent.keep_alive = false
agent.follow_meta_refresh = true
agent.redirect_ok = true
agent.open_timeout = 10
agent.read_timeout = 10
agent.ignore_bad_chunking = true
agent.gzip_enabled = false
url = 'http:%5C%5Cwww.scouts.org.uk'
begin
page_head = agent.head(url)
rescue Exception => exception
puts "Caught exception: #{exception.message}"
end
Result:
=> #Caught exception: undefined method `length' for nil:NilClass
You can add this method to check valid url or not :
require 'uri'
def valid?(url)
uri = URI.parse(url)
if uri.kind_of?(URI::HTTP) == true
puts '+'
else
puts '-'
end
rescue URI::InvalidURIError
puts 'false '
end
['http://web.de',
'http://web.de/',
'http:%5c%5cweb.de',
'http:web.de',
'foo://web.de',
'http://we b.de',
'http://|web.de'].each { |i|
valid?(i)
}
+
+
+
+
false
false

Error: undefined local variable or method 'foo' for main:Object (NameError)

I am trying to find the needle in the haystack. I already received the dictionary with the two values and keys.
ruby haystack.rb
{"haystack"=>["D0zVh", "F1PFc", "j1WMn", "Ebz3k", "SE7gZ", "kOa7j", "0vCJb", "px18q", "NJSyl", "nRsOK", "T7t8F", "2jvwZ", "5414s", "q5z8U", "TI2Zm", "v4Bn9", "5dRcM", "M84vp", "8nQ0o", "OxEKw"], "needle"=>"v4Bn9"}
The first value, needle, is the string. The second value, haystack, is an array of strings.
The next step is to tell the API where the needle is in the haystack array.
I need to post my result to "api/validateneedle", using the key token for my token, and the key needle for the integer representing where the needle is in the haystack array.
When I run this file, I get the following error:
haystack.rb:59:in `<main>': undefined local variable or method `token' for main:Object (NameError)
Can anyone tell me why I'm receiving this error message? I really appreciate any help/feedback!
token_info = {:token => "SVilLuY0OU"}
require 'net/http'
http = Net::HTTP.new("challenge.code2040.org")
# Sending json in body of http request
# Creating a request that will use the post http method
require "json"
body = token_info.to_json
request = Net::HTTP::Post.new("/api/haystack")
# Setting the request body to be our json
request.body = body
# Storing my token in a variable
response = http.request(request)
# Printing my token to complete rest of assignment
#Printing the body of the response
response_hash = JSON.parse(response.body)
puts response_hash["result"]
def getIndex(response)
needle = response["result"]["needle"]
haystack = response["result"]["haystack"]
i = 0
while i < haystack.length
# if we find it, break the loop and return i
if haystack[i] == needle
return i.to_s
end
i += 1
end
return "not found"
end
def sendIndex(token)
response = getItems(token)
index = getIndex(response)
params = {'token' => token, 'needle' => index}
request = Net::HTTP::Post.new("/api/validateneedle")
end
sendIndex(token)
The error message is self-explanatory: on line 59, you are passing the argument token to the method sendIndex, but token isn't defined, neither as a method nor as a local variable.

Issue parsing web page data from twitter for dashing ruby app

I think my issue is the same as that in Having problems with Ruby file from Dashing which as to date no answer.
Full problem is when I start dashing I get.
scheduler caught exception:
undefined method `[]' for nil:NilClass
/home/bhladmin/Shopify-dashing-e672d84/dashboard/jobs/twitter_user.rb:19:in `block in <top (required)>'
/usr/lib64/ruby/gems/1.9.1/gems/rufus-scheduler-2.0.23/lib/rufus/sc/jobs.rb:230:in `call'
/usr/lib64/ruby/gems/1.9.1/gems/rufus-scheduler-2.0.23/lib/rufus/sc/jobs.rb:230:in `trigger_block'
/usr/lib64/ruby/gems/1.9.1/gems/rufus-scheduler-2.0.23/lib/rufus/sc/jobs.rb:204:in `block in trigger'
/usr/lib64/ruby/gems/1.9.1/gems/rufus-scheduler-2.0.23/lib/rufus/sc/scheduler.rb:430:in `call'
/usr/lib64/ruby/gems/1.9.1/gems/rufus-scheduler-2.0.23/lib/rufus/sc/scheduler.rb:430:in `block in trigger_job'
Something isn't right on line 19, but I can't work out what...
The full section of code is below...
#!/usr/bin/env ruby
require 'net/http'
# Track public available information of a twitter user like follower, follower
# and tweet count by scraping the user profile page.
# Config
# ------
twitter_username = ENV['TWITTER_USERNAME'] || 'foobugs'
SCHEDULER.every '2m', :first_in => 0 do |job|
http = Net::HTTP.new("twitter.com", Net::HTTP.https_default_port())
http.use_ssl = true
response = http.request(Net::HTTP::Get.new("/#{twitter_username}"))
if response.code != "200"
puts "twitter communication error (status-code: #{response.code})\n#{response.body}"
else
tweets = /profile["']>[\n\t\s]*<strong>([\d.,]+)/.match(response.body)[1].delete('.,').to_i
following = /following["']>[\n\t\s]*<strong>([\d.,]+)/.match(response.body)[1].delete('.,').to_i
followers = /followers["']>[\n\t\s]*<strong>([\d.,]+)/.match(response.body)[1].delete('.,').to_i
send_event('twitter_user_tweets', current: tweets)
send_event('twitter_user_followers', current: followers)
send_event('twitter_user_following', current: following)
end
end
From the previous question it looks like the way of extracting the data from the webpage is the problem, but I don't know Ruby well enough. I've tried removing the ENV['TWITTER_USERNAME'] section to make sure the username I used (not the one above) is being used. If I dump out the raw html data then it contains the info I'm searching for so I know that part is working.
I think I've solved this myself, by going about it a different way. I've changed the code to use the twitter API rather than page scraping. Details below... The auth checking and timeout isn't great so if anyone has hints on making that better they'd be welcome...
#### Get your twitter keys & secrets:
#### https://dev.twitter.com/docs/auth/tokens-devtwittercom
Twitter.configure do |config|
config.consumer_key = 'YOUR_CONSUMER_KEY'
config.consumer_secret = 'YOUR_CONSUMER_SECRET'
config.oauth_token = 'YOUR_OAUTH_TOKEN'
config.oauth_token_secret = 'YOUR_OAUTH_SECRET'
end
twitter_username = 'foobugs'
MAX_USER_ATTEMPTS = 10
user_attempts = 0
SCHEDULER.every '10m', :first_in => 0 do |job|
begin
tw_user = Twitter.user("#{twitter_username}")
if tw_user
tweets = tw_user.statuses_count
followers = tw_user.followers_count
following = tw_user.friends_count
send_event('twitter_user_tweets', current: tweets)
send_event('twitter_user_followers', current: followers)
send_event('twitter_user_following', current: following)
end
rescue Twitter::Error => e
user_attempts = user_attempts +1
puts "Twitter error #{e}"
puts "\e[33mFor the twitter_user widget to work, you need to put in your twitter API keys in the jobs/twitter_user.rb file.\e[0m"
sleep 5
retry if(user_attempts < MAX_USER_ATTEMPTS)
end
end

Resources