How do you use asana api with faraday? - api

I'm trying to connect to the Asana api with the Faraday gem. My http request works using curl but I get a completely different response with Faraday. What did I do wrong:
require 'faraday'
require 'base64'
require 'net/https'
module Asana
def self.get_tasks(project_asana_id)
conn = create_connection
response = conn.get "/tasks", {"project" => 14790966979027}, {"Content-Type" => "text/plain", "User-Agent"=>"Chrome/25.0.1364.160", "Accept" => "application/json"}
p response.body
end
def self.create_connection
Faraday.new(:url => ENV['ASANA_URL']) do |faraday|
faraday.request :url_encoded # form-encode POST params
faraday.response :logger # log requests to STDOUT
faraday.request :basic_auth, ENV['ASANA_API_KEY'], ''
faraday.adapter :net_http # make requests with Net::HTTP
end
end
end
My response:
"<html>\n<head>\n<title>Asana - Log In</title><script>__FILE__=\"(none)\";var config = {\n\"CLUSTER\": \"prod\",\n\"PRETTY_JS_CODEGEN\": false\n};</script><link rel=\"shortcut icon\" href=\"/-/static/luna/browser/images/favicon.ico\" />\n\n<script type=\"text/javascript\" src=\"https://use.typekit.com/sli4yxq.js\"></script><script>__FILE__=\"(none)\";try{Typekit.load();}catch(e){}</script>\n<script>__FILE__=\"(none)\";req = reqLazy = function(file_path) { var m = modules[file_path]; return (m !== undefined) ? m.exports : undefined; }; modules = {}; globals = window;</script>\n<link type=\"text/css\" rel=\"stylesheet\" href=\"/-/static/build/css/apps/asana/css/dialog_page_root.css\" />\n<link type=\"text/css\" rel=\"stylesheet\" href=\"/-/static/build/css/apps/asana/css/login.css\" />\n<script>__FILE__=\"3rdparty/mochikit/MochiKit/Base.js\";module = { id: __FILE__, exports: {} };exports = module.exports;modules[module.id] = module;</script>\n<script type=\"text/javascript\" src=\"/-/static/3rdparty/mochikit/MochiKit/Base.js\" charset=\"utf-8\"></script>\n<script>__FILE__=\"3rdparty/mochikit/MochiKit/Iter.js\";module = { id: __FILE__, exports: {} };exports = module.exports;modules[module.id] = module;</script>\n<script type=\"text/javascript\" src=\"/-/static/3rdparty/mochikit/MochiKit/Iter.js\" charset=\"utf-8\"></script>\n<script>__FILE__=\"3rdparty/mochikit/MochiKit/Async.js\";module = { id: __FILE__, exports: {} };exports = module.exports;modules[module.id] = module;</script>\n<script type=\"text/javascript\" src=\"/-/static/3rdparty/mochikit/MochiKit/Async.js\" charset=\"utf-8\"></script>\n<script>__FILE__=\"3rdparty/mochikit/MochiKit/DOM.js\";module = { id: __FILE__, exports: {} };exports = module.exports;modules[module.id] = module;</script>\n<script type=\"text/javascript\" src=\"/-/static/3rdparty/mochikit/MochiKit/DOM.js\" charset=\"utf-8\"></script>\n<script>__FILE__=\"3rdparty/mochikit/MochiKit/Style.js\";module = { id: __FILE__, exports: {} };exports = module.exports;modules[module.id] = module;</script>\n<script type=\"text/javascript\" src=\"/-/static/3rdparty/mochikit/MochiKit/Style.js\" charset=\"utf-8\"></script>\n<script>__FILE__=\"luna/common/lib/minimochi.js\";module = { id: __FILE__, exports: {} };exports = module.exports;modules[module.id] = module;</script>\n<script type=\"text/javascript\" src=\"/-/static/luna/common/lib/minimochi.js\" charset=\"utf-8\"></script>\n</head>\n<body>\n<!-- DEBUG-TAG: login -->\n<div id=\"Flags\" class=\"enable_experiment_enrollment_logging enable_delete_session_objects enable_oauth enable_new_billing_page enable_expanded_team_browser log_api_metrics_to_graphite enable_separator_between_far_apart_stories enable_mobile_sections enable_rph_search enable_rph_search_topbar enable_fast_query_dependencies enable_list_caching enable_reset_view_state_on_switches enable_task_caching enable_asanarama enable_key_combos enable_promote_tasks_with_due_dates enable_sort_by_alpha enable_hypertext_ime enable_spooky_theme enable_winter_theme enable_google_tags_iframe enable_box_attachments enable_hacks enable_sync_without_promises\"><script type=\"text/javascript\" src=\"/-/static/luna/browser/browser_google_auth.js\"></script><script>BrowserGoogleAuth.init();</script><script type=\"text/javascript\" src=\"/-/static/luna/browser/dialog.js/?v=3\"></script><div id=\"dialog_wrapper\"><div id=\"bg_pattern\" class=\"bg-pattern\"></div><script>\n if (navigator.userAgent.indexOf('WebKit') > 0) {\n document.getElementById(\"dialog_wrapper\").className += ' webkit';\n }\nDialog.event_name_to_url[\"BrowserLogin-GoogleAuth-Redirect\"] = \"https://app.asana.com/app/asana/-/log?se=%7B%22name%22%3A%22BrowserLogin-GoogleAuth-Redirect%22%2C%22user_agent%22%3A%22Chrome%2F25.0.1364.160%22%7D&cb=1409177825638&hash=08fa47a0cd77d30807017aea9003b9803d22525eb78f4af4f51d8de4c29094ff\";\nDialog.event_name_to_url[\"BrowserLogin-GoogleAuth-Popup-Start\"] = \"https://app.asana.com/app/asana/-/log?se=%7B%22name%22%3A%22BrowserLogin-GoogleAuth-Popup-Start%22%2C%22user_agent%22%3A%22Chrome%2F25.0.1364.160%22%7D&cb=1409177825642&hash=ee5cf64e6b5c72f7c8ba4bf62dd63adf5974fba3dfc8393eff7ae9c5601a0c45\";\nDialog.event_name_to_url[\"BrowserLogin-GoogleAuth-Popup-NotAuthorized\"] = \"https://app.asana.com/app/asana/-/log?se=%7B%22name%22%3A%22BrowserLogin-GoogleAuth-Popup-NotAuthorized%22%2C%22user_agent%22%3A%22Chrome%2F25.0.1364.160%22%7D&cb=1409177825644&hash=cf830e279ad33bc2190b41ad25e8374968655300e4376fbde003bb2ccf31d927\";\nDialog.event_name_to_url[\"BrowserLogin-GoogleAuth-Popup-Authorized\"] = \"https://app.asana.com/app/asana/-/log?se=%7B%22name%22%3A%22BrowserLogin-GoogleAuth-Popup-Authorized%22%2C%22user_agent%22%3A%22Chrome%2F25.0.1364.160%22%7D&cb=1409177825645&hash=b771dc185c05ea808f8b189c1036175ab7c1988928ef6d72f1297170bed46f9c\";</script><div class=\"dialog-page auto-fill-height-0\"><div class=\"formpage-header\"><div class=\"formpage-spacer\"></div></div><div class=\"sidebars\" id=\"sidebars\"><div class=\"dialog-container clearfix\" id=\"dialog-container\"><div class=\"formpage-content\"><div class=\"title\">Log In</div><div class=\"title-bottom\"><span/></div><div class=\"dialog-text\"><table width=\"100%\"><tr><td class=\"content\"><form id=\"dialog_form\" action=\"https://app.asana.com/app/asana/-/login\" method=\"post\"><input type=\"hidden\" name=\"u\" value=\"https://app.asana.com/tasks?project=14790966979027\"/><input type=\"hidden\" name=\"i\" value=\"password\"><input type=\"hidden\" name=\"src\" value=\"login\"/><input type=\"hidden\" name=\"auth\"/><input type=\"hidden\" name=\"xsrf_token\" value=\"0cebe1ed6682122da9fd6a68d061ee6b:1409177825636\"/><div class=\"form-view\"><table><tr id=\"google_auth_row\"><td/><td class=\"buttons\" colspan=\"2\"><div tabindex=0 class=\"asana-button enabled primary button\" id=\"google_auth_button\" onclick=\"return Dialog.Login.loginWithGoogle(false, 'https://app.asana.com/-/oauth2callback', 'https://app.asana.com/tasks?project=14790966979027')\"><span class=\"button-text\">Log In with Google Account</span></div></td></tr><tr><td colspan=\"3\"><div id=\"google_auth_separator\" class=\"separator login-page-separator\"><div class=\"or_separator\">or</div></div></td></tr><tr id=\"email_row\"><td class=\"field-name email\">Email Address</td><td class=\"field-value email\"><input class=\"generic-input showing\" type=\"email\" name=\"e\" id=\"email_input\" value=\"\" onfocus=\"Dialog.setFocusedRow('email_row', true);\" onblur=\"Dialog.setFocusedRow('email_row', false);\"/></td><td class=\"field-no-status\"></td></tr><tr><td colspan=\"2\" class=\"spacer\"/></tr><tr id=\"password_row\"><td class=\"field-name password\">Password</td><td class=\"field-value password\"><input class=\"generic-input showing\" type=\"password\" name=\"p\" id=\"password_input\" onfocus=\"Dialog.setFocusedRow('password_row', true);\" onblur=\"Dialog.setFocusedRow('password_row', false);\"/></td><td class=\"field-no-status\"></td></tr><tr><td></td><td class=\"field-description\">Forgot your password?</td></tr><tr><td></td><td class=\"buttons\" colspan=\"2\"><div tabindex=0 class=\"asana-button enabled primary button\" id=\"submit_button\" onclick=\"Dialog.submit();\"><span class=\"button-text\">Log In</span></div></td></tr></table></div><script>Dialog.makeElementSubmit('email_input');Dialog.makeElementSubmit('password_input'); Dialog.makeElementSubmit('submit_button');</script></form></td></tr></table></div></div><div class=\"trailer\"><div class=\"formpage-footer\"><a class=\"footer-link\" href=\"http://asana.com\" target=\"_blank\">About Asana</a>|<a class=\"footer-link\" href=\"http://asana.com/blog\" target=\"_blank\">Blog</a>|<a class=\"footer-link\" href=\"http://asana.com/jobs\" target=\"_blank\">Jobs</a>|<a class=\"footer-link\" href=\"http://asana.com/help\" target=\"_blank\">Help</a>|<a class=\"footer-link\" href=\"http://asana.com/terms\" target=\"_blank\">Terms</a></div><div class=\"login-link\"><!-- DEBUG-TAG: login-signup -->Don’t have an account? <a class=\"footer-link\" href=\"http://www.asana.com/?utm_source=unknown&utm_campaign=app.asana.com\">Sign Up</a></div><!-- Commenting out FBConnect for now.<td class=\"facebook-label\">Or, Connect with Facebook</td><td class=\"facebook-button\"><img src=\"/-/static/luna/browser/images/connect.gif\" alt=\"Facebook Connect\" />--></div></div></div></div></div></div><script>var initial_focused_element = 'email_input';</script><script>\n document.getElementById(initial_focused_element).focus();\n\n</script>\n<div id=\"debug_page_load_marker\" name=\"login\" style=\"display:none\"></div>\n</body>\n</html>"

Faraday interprets /tasks as being an absolute path on the server, so you should see
$ ASANA_URL="https://app.asana.com/api/1.0/" ruby test.rb
I, [2014-08-28T11:18:31.830026 #49279] INFO -- : get https://app.asana.com/tasks?project=14790966979027
Note the URL is wrong - it should be https://app.asana.com/api/1.0/tasks?project=14790966979027. Which is what you get if you replace conn.get "/tasks" => conn.get "tasks" on line 8.
Always good to check the debug output to make sure the URL matches with what you were sending with curl :-)

Related

Selenium Perl handle shadow DOM

There are plenty examples using Selenium Python to handle shadow DOM. I'd like to do the same in Perl.
Perl's Selenium::Remote::Driver doesn't have shadow DOM support, but I should be able to do it through JavaScript. I got my inspiration from
accessing-shadow-dom-tree-with-selenium.
The following is my code in Perl
#!/usr/bin/env perl
use Selenium::Chrome;
my $driver = Selenium::Chrome->new (
startup_timeout => 60,
custom_args => "--log-path=/tmp/selenium_chromedriver",
logfile => "/tmp/selenium_chromedriver2",
debug_on => 1,
extra_capabilities => {
'goog:chromeOptions' => {
args => [
'--no-sandbox',
'--disable-dev-shm-usage',
'--window-size=1260,720',
'--user-data-dir=/tmp/selenium_chrome',
],
},
},
);
$driver->get("chrome-search://local-ntp/local-ntp.html"); # chrome new tab
my $shadow_host = $driver->find_element("html/body/ntp-app", "xpath");
my $shadow_root = $driver->execute_script('return arguments[0].shadowRoot', $shadow_host);
for my $e ( #{$shadow_root->find_elements(':host > *', 'css')} ) {
# error: Can't call method "find_elements" on unblessed reference
print "found\n";
}
$driver->shutdown_binary();
But I got error: Can't call method "find_elements" on unblessed reference.
How can I overcome this error?
Thank you for any help.
My environment is: ubuntu 18, Perl 5.26, Selenium:Chrome 1.46, Chrome
99, chromedriver 99.
The same mechanism is tested working with Python
3.8.5.
Why I am not using Python? because the server in my work place only has Perl, no Python 3.
the following code works
#!/usr/bin/env perl
use Selenium::Chrome;
my $driver = Selenium::Chrome->new (
startup_timeout => 60,
custom_args => "--log-path=/tmp/selenium_chromedriver",
logfile => "/tmp/selenium_chromedriver2",
debug_on => 1,
extra_capabilities => {
'goog:chromeOptions' => {
args => [
'--no-sandbox',
'--disable-dev-shm-usage',
'--window-size=1260,720',
'--user-data-dir=/tmp/selenium_chrome',
],
},
},
);
$driver->get("chrome-search://local-ntp/local-ntp.html"); # chrome new tab
my $shadow_host = $driver->find_element("html/body/ntp-app", "xpath");
package MyShadow {
sub new {
my ($class, %attrs) = #_;
my $shadow_root = $attrs{driver}->execute_script('return arguments[0].shadowRoot', $attrs{shadow_host});
return undef if ! $shadow_root;
$attrs{shadow_root} = $shadow_root;
bless \%attrs, $class;
}
sub find_element {
my ($self, $target, $scheme) = #_;
die "scheme=$scheme is not supported. Only css is supported" if $scheme ne 'css';
return $self->{driver}->execute_script(
"return arguments[0].querySelector(arguments[1])",
$self->{shadow_root},
$target
);
}
sub find_elements {
my ($self, $target, $scheme) = #_;
die "scheme=$scheme is not supported. Only css is supported" if $scheme ne 'css';
return $self->{driver}->execute_script(
"return arguments[0].querySelectorAll(arguments[1])",
$self->{shadow_root},
$target
);
}
};
my $shadow_driver = MyShadow->new(driver=>$driver, shadow_host=>$shadow_host);
if ($shadow_driver) {
for my $e ( #{$shadow_driver->find_elements(':host > *', 'css')} ) {
print "found\n";
}
}
$driver->shutdown_binary();
Key points:
For Selenium, no matter Python or Perl, they are wrappers to
javascript. As long as you get correct javascript, you can do
whatever you want.
For Shadow driver, all you need to implement is the find_element() and find_elements().
I only implemented 'css', no 'xpath', because that's what Python does as of 2022/09/19.

How to fix integration issue Magento store with POS system after site migration?

We migrated our Magento site (Magento 1.8.1.0) from old server to a new server.
But, we can't use the Winepos integration extension any more.
Our site is connected with Winepos system, and this Magento extension had been operated before migrating work.
This is Winepos API manual.
At this time, we think some PHP modules were not installed on our new server.
But, we don't know which PHP modules were not installed. It seems all PHP modules were installed on our new server.
The Magento extension to integrate with Winepos are as follow. This extension is consisted with two files.
Config.xml
<config>
<global>
<events>
<checkout_onepage_controller_success_action>
<observers>
<igor_winepos_order_success_observer>
<type>singleton</type>
<class>igor_Winepos_Model_Wineposobserver</class>
<method>checkoutSuccessObserve</method>
</igor_winepos_order_success_observer>
</observers>
</checkout_onepage_controller_success_action>
</events>
</global>
</config>
wineposobserver.php
class igor_Winepos_Model_Wineposobserver extends Varien_Event_Observer {
function customlog($obj) {
ob_start();
var_dump($obj);
$out1 = ob_get_contents();
ob_end_clean();
$f = fopen('/tmp/log.txt', 'ab');
fwrite($f, $out1);
fclose($f);
}
public function __construct() {
}
public function checkoutSuccessObserve($observer) {
// $event = $observer->getEvent();
$order_ids = $observer->getData('order_ids');
if(gettype($order_ids) == 'array' && count($order_ids) == 1) {
$the_order = Mage::getModel('sales/order')->load($order_ids[0]);
Mage::helper('globalfunc')->registerOrderWithWinePOSAsynchronousWithTimeout($the_order);
}
}
}
I am getting the following in the Apache log:
PHP Warning: PHP Startup: apc.shm_segments setting ignored in MMAP mode in Unknown on line 0 [Sun Apr 30 06:32:30 2017] [notice] Apache/2.2.22 (Ubuntu) mod_ssl/2.2.22 OpenSSL/1.0.1 configured -- resuming normal operations
285: function registerOrderWithWinePOSAsynchronousWithTimeout($the_order) {
286 try {
287 $items = $the_order->getAllItems();
...
426 $ordered_raw_item = $ordered_products_raw_items[$ordered_product_id];
428: $product_winepos_id = trim(strval($product->getResource()->getAttribute('winepos_id')->getFrontend()->getValue($product)));
429
430 $item_element = $doc->createElement('item');
432 $item_num_element = $doc->createElement('item-num');
433: $item_num_element->appendChild($doc->createTextNode(strval($product_winepos_id)));
434 $item_element->appendChild($item_num_element);
...
466 $the_xml = $doc->saveXML();
468: // $post_result = Mage::helper('globalfunc')->post_to_api_winepos('https://wines-in-november.vznlink.com/orders', $the_xml, 'admin276975', '8dc670fb943dc2c0a1415405cdf00e3ec579c4e6', 8, 10);
470: return Mage::helper('globalfunc')->delayed_post_to_winepos($the_xml);
471 } catch(Exception $e) {
472 $this->customlog($e);
...
475 }
I created a new module to integrate with POS system and implemented inventory synchronization successfully.
This work should be done by cron job. To do it, I created three individual script files.
Also, POS provider should provide ordered product information including inventory information as txt file via ftp in every time interval.
lftp -u [username],[password] -e'set ftp:passive-mode false; cd files; put data.txt; quit' [folder name]
The cron job operating blocks are as follow.
cron_file_mover.php
$start = microtime(true);
shell_exec('cp /home/files/data.txt /var/www/vhosts/magento/');
shell_exec('chown -R www-data:www-data /var/www/vhosts/magento/');
$end = microtime(true);
echo 'Run time: '.round($end-$start, 4).'s';
cron_pos_post_script.php
Utils::initMagento(); $MAX_RETRIES = 5;
$delayed_jobs = Utils::mageGetRows("select * from delayed_jobs where job_type = 'pos_order' and status = 'todo' order by created_at DESC");
$current_index = 0;
foreach($delayed_jobs as $delayed_job) {
$current_index += 1;
$retry_count = intval($delayed_job['retry_count']);
$retry_count += 1;
$post_result = Mage::helper('globalfunc')->post_to_api_pos('https://vznlink.com/orders', $delayed_job['job_details'], 'admin', 'fd93d2de58ab', 8, 10);
Utils::mageSqlExecute("update delayed_jobs set status = 'done' where id = " . $delayed_job['id']);
Utils::mageSqlExecute("update delayed_jobs set status = '" . $new_status . "', retry_count = " . $retry_count . " where id = " . $delayed_job['id']);
}
cron_pos_update_script.php
$PATH_TO_FILE = '/var/www/vhosts/magento/data.txt';
function read_pos_file($path_to_file) {
$min_count_required_for_product = 12;
$f = fopen($path_to_file, 'rb');
$text = trim(fread($f, 100000000));
fclose($f);
$lines = preg_split('/\r\n|\r|\n/i', $text);
$products = array();
foreach($lines as $line) {
$product = preg_split('/\t/i', trim($line));
if(count($product) >= $min_count_required_for_product) {
$product[0] = strval(trim($product[0]));
$product[1] = strval(trim($product[1]));
$product[2] = strval(trim($product[2]));
$product[11] = intval(strval(trim($product[11])));
$products []= $product;
}
}
return $products;
}
function update_stock_for_stock_item($product_id, $new_stock) {
$stock_item = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product_id);
$stock_item->setData('qty', $new_stock);
if($new_stock > 0) {
$stock_item->setData('is_in_stock', 1);
}
$stock_item->save();
}
$products = read_pos_file($PATH_TO_FILE);
$total_count = 0; $processed_count = 0;
foreach($products as $product) {
$total_count += 1;
$item_number = $product[0];
$new_stock = $product[11];
if($new_stock < 0) {
$new_stock = 0;
}
$products_matching_item_number = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect('pos_id')->addFieldToFilter('pos_id', $item_number)->getItems();
if(count($products_matching_item_number) == 1) {
$products_matching_item_number = array_values($products_matching_item_number);
$matching_product = $products_matching_item_number[0];
$matching_product_id = $matching_product->getId();
update_stock_for_stock_item($matching_product_id, $new_stock);
$processed_count += 1;
}
}
The cron job settings are as follows.
10 * * * * /usr/bin/php /var/www/vhosts/magento/pos/cron_winepos_post_script.php &> /dev/null
10 * * * * /usr/bin/php /var/www/vhosts/magento/pos/cron_winepos_update_script.php &> /dev/null
20 * * * * /usr/bin/php /var/www/vhosts/magento/pos/cron_pos_file_mover.php &> /dev/null
Keep in mind, checking POS data provided from POS system, cron job setting, checking update script operations.

AttributeError: 'unicode' object has no attribute 'key'

I'm very new to Python coding and have run into an issue while trying to upgrade some code. I'm working with an app that pulls data via an API from stored data from a scan.
here is the code as it sits working
def _collect_one_host_scan_info(self, host_id, sid, scan_info):
"""
The method to collect all the vulnerabilities of one host and generate the event data.
"""
count = 0
host_uri = self.endpoint + '/' + str(sid) + '/hosts/' + str(host_id)
result = self.client.request(host_uri).get("content")
# if there is exception in request, return None
if result is None:
_LOGGER.info("There is exception in request, return None")
return None
else:
host_info = result.get("info", {})
host_end_time = host_info.get("host_end", "")
if self.ckpt.is_new_host_scan(host_end_time,
self.config.get("start_date")):
self.source = self.url + self.endpoint + '/' + str(
sid) + '/hosts/' + str(host_id)
for vuln in result.get("vulnerabilities", []):
vuln["sid"] = sid
vuln["host_id"] = host_id
#get the port info
plugin_id = vuln.get("plugin_id", "")
port_info = []
if plugin_id:
plugin_uri = "{}/plugins/{}".format(host_uri,
plugin_id)
plugin_outputs = self.client.request(plugin_uri).get(
"content", {}).get("outputs")
ports = []
for output in plugin_outputs:
ports.extend(output.get("ports", {}).keys())
for port in ports:
port_elem = {}
port_items = re.split(r"\s*/\s*", port)
port_elem["port"] = int(port_items[0])
if port_items[1]:
port_elem["transport"] = port_items[1]
if port_items[2]:
port_elem["protocol"] = port_items[2]
port_info.append(port_elem)
vuln = dict(vuln, **scan_info)
vuln = dict(vuln, **host_info)
if port_info:
vuln["ports"] = port_info
entry = NessusObject(
vuln.get("timestamp"), self.sourcetype, self.source,
vuln)
self._print_stream(entry)
count += 1
return count
The data that is being pulled from looks like this
"outputs": [
{
"ports": {
"445 / tcp / cifs": [
{
"hostname": "computer.domain.com"
}
]
},
"has_attachment": 0,
"custom_description": null,
"plugin_output": "\nPath : c:\\program files (x86)\\folder\\bin\\fax.exe\nUsed by services : RFDB\nFile write allowed for groups : Domain Users\nFull control of directory allowed for groups : Domain Users\n\nPath : c:\\program files (x86)\\folder\\bin\\faxrpc.exe\nUsed by services : RFRPC\nFile write allowed for groups : Domain Users\nFull control of directory allowed for groups : Domain Users\n\nPath : c:\\program files (x86)\\folder\\bin\\faxserv.exe\nUsed by services : RFSERVER\nFile write allowed for groups : Domain Users\nFull control of directory allowed for groups : Domain Users\n`,
"hosts": null,
"severity": 3
}
with the working code the return is
ports{}.port 445
ports{}.protocol tcp
ports{}.transport cifs
What I really would like is to grab the "plugin_output" data with the "port" data
I'm currently just trying to replace the "port" data with "plugin_output" data
#get the output info
plugin_id = vuln.get("plugin_id", "")
output_info = []
if plugin_id:
plugin_uri = "{}/plugins/{}".format(host_uri,
plugin_id)
plugin_outputs = self.client.request(plugin_uri).get(
"content", {}).get("outputs")
outputs = []
for output in plugin_outputs:
outputs.extend(output.get("plugin_output", "").keys())
for plugin in plugin_outputs:
plugin_elem = {}
plugin_items = re.split(r"nPath\s*", plugin)
plugin_elem["location1"] = plugin_items[0]
if plugin_items[1]:
plugin_elem["location2"] = plugin_items[1]
if plugin_items[2]:
plugin_elem["location3"] = plugin_items[2]
output_info.append(plugin_elem)
vuln = dict(vuln, **scan_info)
vuln = dict(vuln, **host_info)
if output_info:
vuln["plugin_output"] = output_info
entry = NessusObject(
vuln.get("timestamp"), self.sourcetype, self.source,
vuln)
self._print_stream(entry)
count += 1
what I've done as you can see if just replace the "ports" data with "plugin_output" data and the error received is
AttributeError: 'unicode' object has no attribute key
Well after further efforts I was able to figure out what I needed to do with the code. It was much easier than I thought it would be but sometime when learning a new language its hard to envision what is needed. Code posted below.
def _collect_one_host_scan_info(self, host_id, sid, scan_info):
"""
The method to collect all the vulnerabilities of one host and generate
the event data.
"""
count = 0
host_uri = self.endpoint + '/' + str(sid) + '/hosts/' + str(host_id)
result = self.client.request(host_uri).get("content")
# if there is exception in request, return None
if result is None:
_LOGGER.info("There is exception in request, return None")
return None
else:
host_info = result.get("info", {})
host_end_time = host_info.get("host_end", "")
if self.ckpt.is_new_host_scan(host_end_time,
self.config.get("start_date")):
self.source = self.url + self.endpoint + '/' + str(
sid) + '/hosts/' + str(host_id)
for vuln in result.get("vulnerabilities", []):
vuln["sid"] = sid
vuln["host_id"] = host_id
plugin_id = vuln.get("plugin_id", "")
# get plugin_output data
plugin_output_info = []
if plugin_id:
plugin_uri = "{}/plugins/{}".format(host_uri,
plugin_id)
plugin_outputs = self.client.request(plugin_uri).get(
"content", {}).get("outputs", [])
data_output = []
for output in plugin_outputs:
items = output.get("plugin_output", 'no value')
item = str(items)
#clean = re.sub('[^a-zA-Z0-9-()_*.(:\\)]', ' ', item)
plugin_output_info.append(item)
# get the port info
port_info = []
if plugin_id:
plugin_uri = "{}/plugins/{}".format(host_uri,
plugin_id)
plugin_outputs = self.client.request(plugin_uri).get(
"content", {}).get("outputs", [])
ports = []
for output in plugin_outputs:
ports.extend(output.get("ports", {}).keys())
for port in ports:
port_elem = {}
port_items = re.split(r"\s*/\s*", port)
port_elem["port"] = int(port_items[0])
if port_items[1]:
port_elem["transport"] = port_items[1]
if port_items[2]:
port_elem["protocol"] = port_items[2]
port_info.append(port_elem)
vuln = dict(vuln, **scan_info)
vuln = dict(vuln, **host_info)
if port_info:
vuln["ports"] = port_info
if plugin_output_info:
vuln["plugin_output"] = plugin_output_info
entry = NessusObject(
vuln.get("timestamp"), self.sourcetype, self.source,
vuln)
self._print_stream(entry)
count += 1
return count

How to print from odoo/openERP via XML-RPC

Has anybody used openERP/ odoo for printing invoices via XML-RPC. I've been trying to create an xml rpc method for printing with no success.
function printInvoice($values,$model){
$print = new xmlrpc_client($this->server."report");
$print->return_type = 'phpvals';
foreach($values as $k=>$v){
$nval[$k] = new xmlrpcval( $v, xmlrpc_get_type($v) );
}
$msg = new xmlrpcmsg('report');
$msg->addParam(new xmlrpcval($this->database, "string"));
$msg->addParam(new xmlrpcval($this->uid, "int"));
$msg->addParam(new xmlrpcval($this->password, "string"));
$msg->addParam(new xmlrpcval($model, "string"));
$msg->addParam(new xmlrpcval("report", "string"));
$msg->addParam(new xmlrpcval(87, "int"));
$msg->addParam(new xmlrpcval($nval,"struct"));
$resp = $print->send($msg);
if ($resp->faultCode())
return $resp->faultString();
else
return $resp->value();
}
this is the code that I have so far, first of all i want to generate a report and then print it.
I figured it out a simple way to do it, you just pass the id of invoice or order in the links and this dynamically creates a pdf for the report, or instead of the pdf you can use 'html' which generates an html ready for print for the invoice like this:
http://serverurl:port/report/html/account.report_invoice/(id of invoice);
Here is the code if it helps someone.
function printInvoice($id,$type){
if($type == 'invoice')
{
return "http://serverurl:port/report/pdf/account.report_invoice/".$id;
}
else if($type == 'order')
{
return "http://serverurl:port/report/pdf/sale.report_saleorder/".$id;
}
else
{
return false;
}
}
There is another way that works even when session_id is missing. You should add a function on the server side which will return a pdf:
from openerp import models, api
from openerp.http import request
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
#api.multi
def json_pdf(self):
request.website_multilang = False
pdf = self.env['report'].get_pdf(self, 'account.report_invoice')
if pdf:
return {'data': pdf.encode('base64'), 'name': self.number}
else:
return {'error': 'Attachment not found', 'name': self.number}
In python...
import time
import base64
printsock = xmlrpclib.ServerProxy('http://server:8069/xmlrpc/report')
model = 'account.invoice'
id_report = printsock.report(dbname, uid, pwd, model, ids, {'model': model, 'id': ids[0], 'report_type':'pdf'})
time.sleep(5)
state = False
attempt = 0
while not state:
report = printsock.report_get(dbname, uid, pwd, id_report)
state = report['state']
if not state:
time.sleep(1)
attempt += 1
if attempt>200:
print 'Printing aborted, too long delay !'
string_pdf = base64.decodestring(report['result'])
file_pdf = open('/tmp/file.pdf','w')
file_pdf.write(string_pdf)
file_pdf.close()

Puppet: Syntax error with '$x.each...'

I have the code below:
define keepalived::vrrp_instance(
$state,
$interface,
$virtual_addresses,
$virtual_router_id,
$priority = $::keepalived::params::priority,
$advert_int = $::keepalived::params::advert_int,
$password = $::keepalived::params::password,
$notify_master = $::keepalived::params::notify_master,
$notify_backup = $::keepalived::params::notify_backup,
$notify_fault = $::keepalived::params::notify_fault,
$notify_all = $::keepalived::params::notify_all,
$smtp_alert = $::keepalived::params::smtp_alert,
) {
...
$virtual_addresses.each |$address| {
$splitted_address = split($address,' ')
if !is_ip_address($splitted_address[0]) {
fail("Error virtual_address Value: \"${address}\" not an ip address!")
}
}
...
}
$virtual_addresses is something like ['127.0.0.1 dev eth0','fd00::1 dev eth0']
Running the code I get the following error:
Syntax error at '.'; expected '}' at /etc/puppet/environments/ip6_dev/modules_custom/keepalived/manifests/vrrp_instance.pp:136 on node
Line 136 is "$virtual_addresses.each |$address| {"
I can't find a mistake (https://docs.puppetlabs.com/references/3.stable/function.html#each)
I am using Puppet 3.3.2
"note requires parser = future"
Ensure you are using future parser in puppet.
Set parser = future in your puppet.conf file or add the command line switch --parser=future
UPDATE:
Wrap your verification function:
define verify::wrapper ()
{
$ip_address = split($name,' ')
if !is_ip_address("${ip_address[0]}") {
fail("Error virtual_address Value: \"${ip_address[0]}\" not an ip address!")
}
}
Next use it:
define keepalived::vrrp_instance(...)
{
...
verify::wrapper{ $virtual_addresses : }
...
}