Migrating Authorization Mechanics ClientLogin to OAuth2 Google AdWords v201206 Perl - perl

So I previously was using ClientLogin for authorization in the Google AdWords API but after looking at AuthForInstalledApps it says that this mechanism has been deprecated in favor of OAuth2.0
I have registered my application in the API Consoles. Now I am trying to follow the perl example of how to set this up:
use_oauth2.pl
I cannot place the AdWords Client, credentials in ~/adwords.properties since I have multiple accounts that I will be doing Campaign Management operations on, and therefore multiple client ids.
But for now I tried to follow this example by using just one of my client's info like this:
my $client = Google::Ads::AdWords::Client->new(
{
version => 'v201206',
developer_token => TOKEN,
client_id => $google_account_id
}
);
$client->get_auth_token_handler()->set_email($login);
$client->get_auth_token_handler()->set_password($password);
However when I step through this, when it tries to initialize the Client object it throws this error:
Can't use an undefined value as a HASH reference at (eval 845)[/usr/lib/perl5/vendor_perl/5.8.8/HTTP/Message.pm:371] line 1. at (eval 845)[/usr/lib/perl5/vendor_perl/5.8.8/HTTP/Message.pm:371] line 1
HTTP::Message::__ANON__[(eval 845)[/usr/lib/perl5/vendor_perl/5.8.8/HTTP/Message.pm:371]:1]() called at /home/etienne/backend/libs/Google/Ads/Common/HTTPTransport.pm line 30
Google::Ads::Common::HTTPTransport::client('Google::Ads::Common::HTTPTransport=HASH(0xb59b830)', 'Google::Ads::AdWords::Client=SCALAR(0x9b9bb60)') called at /home/etienne/backend/libs Google/Ads/AdWords/Client.pm line 180
Google::Ads::AdWords::Client::START('Google::Ads::AdWords::Client=SCALAR(0x9b9bb60)', 1, 'HASH(0xb582e70)') called at /usr/lib/perl5/site_perl/5.8.8/Class/Std/Fast.pm line 251
Class::Std::Fast::__ANON__[/usr/lib/perl5/site_perl/5.8.8/Class/Std/Fast.pm:252]() called at /usr/lib/perl5/site_perl/5.8.8/Class/Std/Fast.pm line 287
Class::Std::Fast::new('Google::Ads::AdWords::Client', 'HASH(0xb54c210)') called at /home/etienne/backend/search_marketing/data_exchange/lib/GoogleAPIv2.pm line 3555
GoogleAPIv2::get_adwords_client('GoogleAPIv2=HASH(0xb556d10)', 4202697829) called at /home/etienne/backend/search_marketing/data_exchange/lib/GoogleAPIv2.pm line 230
GoogleAPIv2::add_campaign('GoogleAPIv2=HASH(0xb556d10)', 'name', 'API Upgrade Test Campaign - 1348613850', 'google_account_id', 4202697829, 'account_id', 207, 'country_code', 'US', ...) called at google_add_campaign.t line 110
main::main() called at google_add_campaign.t line 26
scalar context return from CODE(0x9b909c0): *Class::Std::Fast::_cache
1..3
I am using Perl v5.8.8 . I have installed the latest Adwords Perl Client Library v2.7.2 . Is there some kind of dependency issue?
And how can I go about resolving this issue. Any information you can provide would be very helpful. Thanks.

It looks like I just needed to have the latest HTTP/Message.pm v6.0.3 module installed since the version I had installed did not have the method decode() which was being passed to the AUTOLOAD() subroutine in the HTTP/Message.pm module.

Related

IBM Language Translator returns 403 Forbidden upon identify()

I followed the official documentation to create a multilingual Watson assistant outlined here:
https://github.com/with-watson/multilingual-chatbot
However, after deploying the function on IBM Cloud and testing the deployed function via IBM Cloud CLI with the below command, I am getting an error (logs below):
bx wsk action invoke translator --result --param text "Hallo, ich habe eine Frage."
{
"error": "The action did not return a dictionary."
}
"2020-01-13T12:54:57.787506Z stderr: Traceback (most recent call last):",
"2020-01-13T12:54:57.787554Z stderr: File \"pythonrunner.py\", line 88, in run",
"2020-01-13T12:54:57.787560Z stderr: exec('fun = %s(param)' % self.mainFn, self.global_context)",
"2020-01-13T12:54:57.787564Z stderr: File \"<string>\", line 1, in <module>",
"2020-01-13T12:54:57.787568Z stderr: File \"__main__.py\", line 98, in main",
"2020-01-13T12:54:57.787571Z stderr: response = translator.identify( text )",
"2020-01-13T12:54:57.787575Z stderr: File \"/action/virtualenv/lib/python3.6/site-packages/watson_developer_cloud/language_translator_v3.py\", line 193, in identify",
"2020-01-13T12:54:57.787579Z stderr: accept_json=True)",
"2020-01-13T12:54:57.787583Z stderr: File \"/action/virtualenv/lib/python3.6/site-packages/watson_developer_cloud/watson_service.py\", line 587, in request",
"2020-01-13T12:54:57.787587Z stderr: info=error_info, httpResponse=response)",
"2020-01-13T12:54:57.787591Z stderr: watson_developer_cloud.watson_service.WatsonApiException: Error: Forbidden, Code: 403",
"2020-01-13T12:54:57.788Z stderr: The action did not initialize or run as expected. Log data might be missing."
Looks like the API key is recognized but not permitted to be used for this action, however the key being used does return the right values when used via cURL.
The code executed in main is the same as provided on the Github above, I did not make any changes.
Any ideas on how to fix this issue? Thanks!
The key string used by curl is a bearer token. The API key needed by the cloud function is probably one provided by Identity and Access Management, IAM.
In the https://cloud.ibm.com console GUI in the top click Manage > Access (IAM) then select the IBM Cloud API keys on the left and select an API key. This creates an API key that represents you, just like login name and credentials. This is the simplest way to get this to work, but is not great for production.
For production consider using a Service ID and probably in combination with Access Group.
Here's what worked for me with additional changes
I have run the below command to update the packages mentioned in the environment.yml file
conda update --all
The conda version on my machine is 4.8.1
cloud-functions/wsk/functions/fn plugin version is 1.0.36
While creating Language Translator instance make sure to choose the right region.
It worked for me after I changed it.

Setting up SimpleSAMLphp as a SP for CodeIgniter

I have to continue on an already existing CodeIgniter 3 application (not written by me) which contains multiple applications for different customers, the project structure looks a little like this:
root/
applications/
customer1/
config/, controllers/, models/, views/, ...
third_party/
SimpleSAMLphp/
config/, metadata/, www/, ...
lib/
_autoload.php
customer2/
...
assets/, bundle/, ...
customers/
customer1/
assets/, index.php, ...
customer2/
...
system/
vendor/
composer/
autoload.php
Now for one of the applications I have to replace the ion_auth system with an SSO (setup as a Service Provider from their IdP metadata). I googled a lot and tought SimpleSAMLphp would be my best option.
But I am really struggling just even putting the SimpleSAMLphp SP API into my application and the documentation isn't great.
-I "include_once" the third_party/SimpleSAMLphp/lib/_autoload.php file in the customers/customer1/index.php file (before require_once BASEPATH...)
-I modified third_party/SimpleSAMLphp/lib/_autoload.php so it finds the vendor/autoload.php file
I expect to be able to use the methods of the SimpleSAMLphp library but instead I get the following errors:
-If I follow the code in this guide:
Fatal error: Call to undefined function SimpleSAML\Auth\Simple()
-If use include APPPATH . 'third_party\SimpleSAMLphp\www\index.php in my controller just above the code from above tutorial:
Fatal error: Class 'SimpleSAML\Error\Assertion' not found in
What am I doing wrong in my setup?

Unable to authenticate using google cloud service account key created by python API

The sample below demonstrates failure to authenticate to google service account using the key created just the few lines above using python api.
I was not able to find any document on how these, programmatic keys, can be used.
The keys created by clicking thru console UI are working just fine.
However, for our use case, we need to create the keys using programmatic ways.
There is unanswered issue at github as well: https://github.com/googleapis/google-cloud-python/issues/7824
logger.info("Created new service account: {}".format(ret))
logger.info("Getting the new service account key")
request=iam.projects().serviceAccounts().keys().create(name=ret['name'],
body={'privateKeyType':'TYPE_GOOGLE_CREDENTIALS_FILE'})
key=request.execute()
>>>print json.dumps(key, indent=4) #just to verify what we got
{
"keyOrigin": "GOOGLE_PROVIDED",
"name": "goodandvalidname",
"validBeforeTime": "2029-06-28T15:09:59Z",
"privateKeyData": "datadata",
"privateKeyType": "TYPE_GOOGLE_CREDENTIALS_FILE",
"keyAlgorithm": "KEY_ALG_RSA_2048",
"validAfterTime": "2019-07-01T15:09:59Z"
}
>>> credentials = google.oauth2.service_account.Credentials.from_service_account_info(key)
Traceback (most recent call last):
File "/home/user/.p2/pool/plugins/org.python.pydev.core_7.2.1.201904261721/pysrc/_pydevd_bundle/pydevd_exec.py", line 3, in Exec
exec exp in global_vars, local_vars
File "<console>", line 1, in <module>
File "/home/user/.local/lib/python2.7/site-packages/google/oauth2/service_account.py", line 193, in from_service_account_info
info, require=['client_email', 'token_uri'])
File "/home/user/.local/lib/python2.7/site-packages/google/auth/_service_account_info.py", line 51, in from_dict
'fields {}.'.format(', '.join(missing)))
ValueError: Service account info was not in the expected format, missing fields token_uri, client_email.
Any help appreciated.
Answering my own issue and probably helping others...
The 'key' we get from python APIs is NOT the 'json key' as obtained from gcloud. The dict we get from iam.projects().serviceAccounts().keys().create() contains the field privateKeyData which itself contains ENTIRE 'json key' one needs to authenticate to google cloud.
The data in this field is base64 encoded and needs decoding, and subsequently dumping to json. Below is the snippet from functional code, demonstrating the credentials are loaded back from such key:
request=iam.projects().serviceAccounts().keys().create(name=ret['name'],
body={'privateKeyType':'TYPE_GOOGLE_CREDENTIALS_FILE'})
key=request.execute()
key=base64.decodestring(key['privateKeyData'])
key=json.loads(key)
credentials = google.oauth2.service_account.Credentials.from_service_account_info(key)
I figured this out by stepping thru gcloud service account key creating, line by line, using python debugger. Hope this helps others.

Io Language : Exception: Object does not respond to 'URL'

Today I'm exercising an Io example of "seven language of seven weeks."
Example code:
futureResult := URL with("http://google.com/") #fetch
writeln("Do something immediately while fetch goes on in background...")
writeln("This will block until the result is available.")
writeln("fetched ", futureResult size, " bytes")
Running with exception:
Io$ io future.io
Exception: Object does not respond to 'URL'
---------
Object URL future.io 1
CLI doFile Z_CLI.io 140
CLI run IoState_runCLI() 1
Directly run URL in io with following error:
~$ io
Io 20110905
Io> URL
Exception: Object does not respond to 'URL'
---------
Object URL Command Line 1
Io>
My environment is:
Ubuntu 14.04
Followed post , I have done following:
$ sudo apt-get install libevent-dev
$ ./build.sh
$ ./build.sh install
URL error is fixed.
But following error thrown:
Do something immediately while fetch goes on in background... This
will block until the result is available. fetched Exception: Error
does not respond to 'size' --------- Error size
future.io 6 Error size future.io 6 CLI
doFile Z_CLI.io 140 CLI run
IoState_runCLI() 1
Post help to install Io
For anyone else like me who is years later running into this issue (or any other "Exception: Object does not respond to X" issue) while following along with Bruce Tate's Seven Languages in Seven Weeks, the solution may be this:
There are some Objects/libraries which seem like they would be included in core Io based on the documentation, but are not. You must install them as addons with eerie.
To do so, follow the instructions here. Basically, you have to look for the correct addon under the IoLanguage group on Github, and install it.
This particular issue with the URL Object is further complicated by a couple of problems I will expound upon below.
There is no addon for URL, instead the functionality for URL is covered by an addon called Socket (located here.)
To get eerie to install Socket, you first need to install something called libevent. I did this by going to the libevent website, downloading the most recent stable version, extracting the files to a directory, and then following the instructions on how to build libevent with CMake on the libevent github page.
The Socket object seems to not have support for https. The number of websites that still use http is dwindling. Google, the website used in the example in Seven Languages in Seven Weeks, moved away from http years and years ago. The first website I was able to come across that still uses http is a Chinese news website, but you can find other examples by googling around for "Websites still using http."
After accounting for all of these issues, I finally got my version of the code to work.
url := URL with("http://xinhuanet.com/")
// Had to find a website still using http, https is unsupported by Socket.
futureResult := url #fetch
// Moved this call to own line for personal clarity
writeln("Do something immediately while fetching.")
writeln("The below statement will block until the result is available.")
writeln("fetched ", futureResult size, " bytes") // Blocks until complete
And my output looks like:
Do something immediately while fetching.
The below statement will block until the result is available.
fetched 99992 bytes

Fatal error: Class 'PEAR' not found in /home/user1/public_html/go-pear.php on line 697

When trying to install PEAR by running go-pear.php (from the root of a cPanel GoDaddy hosted account), I get the following error:
Starting installation ... Loading zlib: ok
Bootstrapping Installer...................
Bootstrapping PEAR5.php............(remote) ok
Bootstrapping PEAR.php............(remote) ok
Bootstrapping Archive/Tar.php............(remote) ok
Bootstrapping Console/Getopt.php............(remote) ok
Fatal error: Class 'PEAR' not found in /home/alessio1/public_html/go-pear.php on line 697
line 697 is the following: PEAR::setErrorHandling(PEAR_ERROR_DIE,
"\n%s\n");
The file go-pear.php was taken directly from http://pear.php.net/go-pear without any modification.
What am I doing wrong?
I had the same error, and managed to solve it replacing the links stored in $bootstrap_files to :
$bootstrap_files = array(
'PEAR5.php' => 'https://raw.githubusercontent.com/pear/pear-core/master/PEAR5.php',
'PEAR.php' => 'https://raw.githubusercontent.com/pear/pear-core/master/PEAR.php',
'Archive/Tar.php' => 'https://raw.githubusercontent.com/pear/Archive_Tar/master/Archive/Tar.php',
'Console/Getopt.php' => 'https://raw.githubusercontent.com/pear/Console_Getopt/master/Console/Getopt.php',
);
I also had this error and found that KevinD's fix didn't work for me, but was able to figure something out based on it. To solve the problem I replaced the line
'Console/Getopt.php' => 'https://raw.github.com/pear/Console_Getopt/trunk/Console/Getopt.php',
with
'Console/Getopt.php' => 'https://raw.githubusercontent.com/pear/Console_Getopt/trunk/Console/Getopt.php',
The install completed nearly instantly for me after this change.
Use the .phar file: http://pear.php.net/go-pear.phar
It should work better.
Pay attenction: Sometimes the problem is caused because of the blocking of fsocket() php function.
Server-to-server communication is sometimes used to commit abuses for example internet attacks.
Many free hosting companies block fsocket() function by default, and sometimes you have to authenticate yourself (providing information about you) to use this function.