Quickblox getting a session receives "Unexpected signature" error - python

When getting a session, I get an "unexpected error".
Here is my code to get the signature (modified from this since that code is without some imports and notably hmac.new() is used instead of hmac() since that code doesn't work for me.
import sys
import json
import time
import random
import hashlib
import hmac
import urllib
import httplib
application_id = '3427'
auth_key = 'PLYHedAmxwdvt59'
auth_secret = '*some secret key*'
nonce = str(random.randint(1, 10000))
timestamp = str(int(time.time()))
signature_raw_body = ("application_id=" + application_id + "&auth_key=" + auth_key +
"&nonce=" + nonce + "&timestamp=" + timestamp)
signature = hmac.new(auth_secret, signature_raw_body, hashlib.sha1).hexdigest()
params = urllib.urlencode({'application_id': application_id,
'auth_key': auth_key,
'timestamp': timestamp, 'nonce' : nonce,
'signature' : signature})
conn = httplib.HTTPSConnection("api.quickblox.com")
conn.request("POST", "/session", params, {})
response = conn.getresponse()
print response.read()
print "signature = '%s'" % signature
The output:
<?xml version="1.0" encoding="UTF-8"?>
<session>
<application-id type="integer">3427</application-id>
<created-at type="datetime">2013-08-04T12:19:10Z</created-at>
<device-id type="integer" nil="true"/>
<id type="integer">3552056</id>
<nonce type="integer">5855</nonce>
<token>686840081c18c7dd0e0a779c233e0d9605bcb567</token>
<ts type="integer">1375618748</ts>
<updated-at type="datetime">2013-08-04T12:19:10Z</updated-at>
<user-id type="integer" nil="true"/>
</session>
signature = 'f08b68b645184619bbe59bac217506e66a840425'
Next I use curl to attempt to create a session:
curl -X POST -H "Content-Type: application/json" -H
"QuickBlox-REST-API-Version: 0.1.0" -d
'{"application_id":"3427","auth_key":"PLYHedAmxwdvt59","nonce":"33432","timestamp":"1375619372","signature":"f08b68b645184619bbe59bac217506e66a840425"}'
http://api.quickblox.com/session.json
I get this as a result:
{"errors":{"base":["Unexpected signature"]}}
Something went wrong?

Here is my example:
curl -X POST -H "Content-Type: application/json" -H "QuickBlox-REST-API-Version: 0.1.0" -d '{"application_id":"92","auth_key":"wJHdOcQSxXQGWx5","nonce":"315","timestamp":"1375624737","signature":"f36336b8bc8449b8252edbc0ee441cdb5856112c"}' http://api.quickblox.com/session.json
Result:
{"session":{"application_id":92,"created_at":"2013-08-04T13:59:50Z","device_id":null,"id":3553701,"nonce":315,"token":"1d423b6633e2fc82f81d88b65f3e26198853c84c","ts":1375624737,"updated_at":"2013-08-04T13:59:50Z","user_id":null}}
You should check code which generates your signature

Related

change curl cmd to python

I am a beginner. I am trying to change a curl cmd to an actually Post request in my python code.
Each time, I am getting either a 404 or 400 errors. I am a bit lost. Thanks.
Curl request : (echo -n '{"data": "'; base64 test-1.pdf; echo '", "extension": ".pdf"}') | curl -X POST -H "Content-Type: application/json" -d #- http://localhost:5000
My python code:
import json
import requests
url ='http://localhost:5000/POST'
newHeaders = {'Content-Type': 'application/json'}
response = requests.post(url, json={"data": "'; base64 test-1.pdf; echo '", "extension": ".pdf"},headers=newHeaders)
print("Status code: ", response.status_code)
response_Json = response.json()
print("Printing Post JSON data")
print(response_Json['data'])
print("Content-Type is ", response_Json['headers']['Content-Type'])
Your URL is wrong and should not have the /POST at the end, but in addition to that, you need to actually base64-encode the test-1.pdf (this is what the shell command that runs curl is doing).
You could use this (combined with the code in the question) to put the correct value into the parameters dictionary.
import base64
#...
b64 = base64.b64encode(open("test-1.pdf", "rb").read()).decode()
response = requests.post(url,
json={"data": b64,
"extension": ".pdf"},
headers=newHeaders)

How to print a Locust response (JSONDecodeError)

I have a flask app which looks like the following:
(note I have simplified it for the sake of this question)
#app.route("/app/ent/", methods=['POST'])
def methodpost():
req_data = request.get_json()
msg = req_data['msg']
output = jsonify(msg=msg)
return output
then for this, I have a locust file that looks like this:
from locust import HttpLocust, TaskSet, task, between
class MyClass(TaskSet):
#task(1)
def send_post(self):
self.client.headers['Content-Type'] = "application/json"
response = self.client.post("/app/ent/", json=
{
"msg": "test mesg example"
})
#temp
json_response_dict = response.json()
msg = json_response_dict['msg']
print("Post nessage returned is " + msg)
class MyTest(HttpLocust):
task_set = MyClass
wait_time = between(0.5, 3.0)
host = "http://localhost:5000"
I start locust as follows:
locust -f locust_myExample.py
Then when I run it using UI, I get following error:
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Any idea how I can print the "msg" that is returned by the flask app?
However, just to make sure it works, when I do manual test using cURL, it returns "msg"
curl --header "Content-Type: application/json" \
--request POST \
--data '{"msg":"test mesg example"}' \
http://localhost:5000/app/ent
test mesg example
The solution is:
The response returned was not json and when finally it came back as JSON, it works.
This line was missing:
output = jsonify(msg=msg)

Python urllib2 open request fails with urllib2.HTTPError: HTTP Error 401: Unauthorized

Below is my python code using urllib2 library and it keeps failing with an Unauthorized error although I am using the correct API key. If I user curl, the POST/GET works just fine.Anyone got ideas? Thanks.
Adding the curl commands below that works just fine
Create Credential
curl -X POST 'https://myurl.com' \
-H 'Content-Type: application/json' \
-u 'XXXXXXXXXX:' \
-d #- << EOF
{
"vendorAccountId": "1234567",
"type": "my_role"
}
EOF
Below is the python code which doesn't work.
Basically, the line of code where it is failing is: response = opener.open(request)
import boto3
import json
import logging
import signal
import requests
from urllib2 import build_opener, HTTPHandler, Request
import urllib2
LOGGER = logging.getLogger()
LOGGER.setLevel(logging.INFO)
def main():
auth_token = "XXXXXXXXXX"
account_id = "1234567"
request_type = "CreateCredentials"
content_type = ""
request_body = json.dumps({})
if request_type == "CreateCredentials":
target_url = 'https://myurl.com'
request_method = "POST"
content_type = "application/json"
request_body = json.dumps({
"vendorAccountId": account_id,
"type": "my_role"
})
handler = urllib2.HTTPHandler()
opener = urllib2.build_opener(handler)
request = urllib2.Request(target_url, data=request_body)
request.add_header("Content-Type", content_type)
request.add_header("Content-Length", len(request_body))
request.add_header("Authorization", auth_token)
request.get_method = lambda: request_method
response = opener.open(request) #*****Fails here******
if __name__ == "__main__":
main()
Finally, I figured out what the issue was. My lack of patience for not reading the vendor manuals. The HTTP request I was sending was missing some parameters that was required and I needed to send the Key in an encrypted format too.

How to send integer in POST to Tornado's AsyncHTTPTestCase.fetch()?

I'm using python's Tornado framework to test my HTTP POST endpoint. To do this, I'm using the fetch method.
data = urllib.urlencode({
'integer_arg': 1,
'string_arg': 'hello'
})
resp = AsyncHTTPTestCase.fetch('/endpoint',
method='POST',
headers={'h1': 'H1',
'h2': 'H2',
'Content-Type': 'application/json'},
body=data)
When I do this, the endpoint receives integer_arg as the string "1" even though I want it to receive it as an integer. This is understandable because urllib.urlencode converts it to a string. So how can I ensure it receives an integer?
Just eliminating the call to urllib.urlencode doesn't work.
By the way, when I hit the same endpoint with a naked curl call as shown below, the endpoint properly receives integer_arg as the integer 1.
curl \
--request POST \
--header "h1: H1" \
--header "h2: H2" \
--header "Content-Type: application/json" \
--data '{
"integer_arg": 1,
"string_arg": "hello"
}' \
"http://localhost:8000/endpoint"
The body in curl is significantly different than that in AsyncHTTPClient.fetch. With python you urlencode the data in curl there is just json. So simply change urlencode with json.dumps:
import json
from tornado.ioloop import IOLoop
from tornado.httpclient import AsyncHTTPClient
from tornado.gen import coroutine
#coroutine
def main():
client = AsyncHTTPClient()
body = json.dumps({
'integer_arg': 1,
'string_arg': 'hello'
})
yield client.fetch(
'/endpoint', method='POST', body=body,
headers={'h1': 'H1', 'h2': 'H2', 'Content-Type': 'application/json'}
)
ioloop = IOLoop.instance()
ioloop.run_sync(main)

RESTFUL POST with Python request to Glassfish Server

I'm having a difficulty trying to make a Python REST POST to a webservice running on Glassfish. I have verified that POST works ok using CURL but having no luck with Python.
Here is the CURL request that works ok.
curl -X POST -H "Content-Type: application/json" -d '{"id":1,"lastname":"smith"}'
http://192.168.0.20:8080/field1/resources/com.field1entity.field1
Here is the Python code to make the POST request
import urllib
import httplib2
def call():
http = httplib2.Http()
url = 'http://192.168.0.20:8080/field1/resources/com.field1entity.field1'
params = urllib.urlencode({"id":11111,"lastname":"oojamalip"})
response, content = http.request(url, 'POST', params, headers={'Content-type':'application/json'})
print "lets stop here to have a looksy at the variables"
print content
if __name__ == '__main__':
namesPage = call()
print namesPage
Output from console,
Unexpected character ('l' (code 108)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: org.apache.catalina.connector.CoyoteInputStream#18f494d; line: 1, column: 2]
Hope someone can shed some light on the problem.
thanks
Nick
You are url encoding the prams and then telling the server it is json encoded
import json
params = json.dumps({"id":11111,"lastname":"oojamalip"})
# then
response, content = http.request(url, 'POST', body=params, headers={'Content-type':'application/json'})

Categories