Parse Server error: unauthorized and Python connection issues - python

I just set up my first Parse test server on Heroku, and am having 2 main issues:
Issue 1) https:// [MY SERVER URL] /parse is returning {error: 'unauthorized'}. I've tried using Postman to authenticate using the headers
"X-Parse-Application-Id": xxx
"X-Parse-Master-Key": yyy
where xxx and yyy are my AppID and MasterKey.
Issue 2) I am not able to connect to the API using Python. I AM able to submit successful requests from the Parse dashboard itself, and also using cURL:
curl -X GET -H "X-Parse-Application-Id: xxx" -H "X-Parse-REST-API-Key: undefined" https://[MY SERVER URL]/parse/classes/Customer (this works)
But when I use the following code (as it states in the Parse API documentation), I am not getting getting an
ConnectionResetError: [Errno 54] Connection reset by peer
This doesn't surprise me, since here is the Python script I'm using to connect:
import json,http
connection = http.client.HTTPConnection('api.parse.com', 443)
connection.connect()
connection.request('GET',
'/1/classes/Customer/', '', {
"X-Parse-Application-Id": "myAppID",
"X-Parse-REST-API-Key": "undefined"
})
result = json.loads(connection.getresponse().read())
In particular, it's the connection.getresponse() function call that is returning the error.
I know this doesn't look right since I don't see where I'm supposed to specify my server URL, and I have a suspicion these two issues are interconnected. Can someone help me shed some light on what's going on? I've read through the PARSE REST documentation pretty thoroughly (https://parseplatform.github.io/docs/rest/guide/) and followed along using the same structure for the requests.

Related

requests.exceptions.HTTPError: 401 Client Error atlassian-python-api

I am trying to connect to a Confluence page using the python wrapper on the API (as I am not familiar with any of this) but I keep getting the following error:
requests.exceptions.HTTPError: 401 Client Error
I know that people talk about this being caused by the necessity of using an API token but the page runs on an old version of Confluence and I have been told that we cannot use access tokens.
So has anyone any other idea? Here's a small code:
from atlassian import Confluence
confluence = Confluence(
url='https://address',
username='name',
password='pwd'
)
confluence.create_page(
space='Test',
title='A title',
body='something')
I have tried to use an older version of atlassian-python-api just in case there was some conflict but it got me the same error.
Your code looks ok. Authenticating to Confluence using Basic Auth should work without generating an API token, afaik.
The 401 status definitely suggests a problem with the authentication though. The obvious reason for this would be of course wrong credentials, but I assume that you have double checked that the credentials work when interactively logging into confluence with a browser.
To get a better sense of the error, you can import logging to debug your requests and response:
from atlassian import Confluence
import logging
logging.basicConfig(filename='conf_connect.log', filemode='w', level=logging.DEBUG)
try:
c = Confluence(url='https://conf.yoursystem.com', username='name', password='pwd')
# atlassian API does not raise error on init if credentials are wrong, this only happens on the first request
c.get_user_details_by_username('name')
except Exception as e:
logging.error(e)
The Confluence module internally also uses logging, so the requests and responses will appear in your conf_connect.log logfile:
DEBUG:atlassian.rest_client:curl --silent -X GET -H 'Content-Type: application/json' -H 'Accept: application/json' 'https://conf.yoursystem.com/rest/api/user?username=name'
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): conf.yoursystem.com:443
DEBUG:urllib3.connectionpool:https://conf.yoursystem.com:443 "GET /rest/api/user?username=name HTTP/1.1" 401 751
DEBUG:atlassian.rest_client:HTTP: GET rest/api/user -> 401
DEBUG:atlassian.rest_client:HTTP: Response text -> <!doctype html><html lang="en"><head><title>HTTP Status 401 – Unauthorized</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 401 – Unauthorized</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Message</b> Basic Authentication Failure - Reason : AUTHENTICATED_FAILED</p><p><b>Description</b> The request has not been applied because it lacks valid authentication credentials for the target resource.</p><hr class="line" /><h3>Apache Tomcat/9.0.33</h3></body></html>
ERROR:root:401 Client Error: for url: https://conf.yoursystem.com/rest/api/user?username=name
The response body may include some information on the reason:
HTTP Status 401 – UnauthorizedType Status ReportMessage Basic Authentication Failure - Reason : AUTHENTICATED_FAILEDDescription The request has not been applied because it lacks valid authentication credentials for the target resource.
The reason AUTHENTICATED_FAILED suggests something is likely wrong with your credentials. If you want to dig deeper into that, you can use this SO answer to also display the headers that are being sent with your request.
However, if your reason is AUTHENTICATION_DENIED the problem is likely the following: If you have too many failed authentication attempts in a row, a CAPTCHA challenge is triggered, and this error will occur until the Failed Login Count is reset. This can easily happen when you are developing a script and test it frequently. To remedy this, either open a browser and manually (re-)logon to Confluence, completing the CAPTCHA, or resolve it from the Confluence User Management.

Golang: Get request sends me html contents but works fine from python and curl

I am trying to call a simple api by using golang. But, each time it sends me html content of login page instead of actual data. But same get request works from python and curl.
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://www.lrn.com", nil)
if err != nil {
os.Exit(1)
}
q := req.URL.Query()
q.Add("phoneList", "XXXXXX")
q.Add("output", "json")
q.Add("version", "5")
//req.URL.RawQuery = q.Encode()
req.Header.Set("loginId", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
fmt.Println(req.URL.String())
resp, err := client.Do(req)
if err != nil {
fmt.Println("Errored when sending request to the server")
return
}
defer resp.Body.Close()
resp_body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(resp.Status)
fmt.Println(string(resp_body))
}
Above script gives me html content of login page. But if i use python, it works just fine.
import requests
r=requests.get("https://www.lrn.com", params = {'version':'5', "phoneList":"XXXXXX", "output":"json"}, headers={"loginId":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"})
print r.text
Could someone please explain me what might be wrong in my golang script.
//req.URL.RawQuery = q.Encode()
req.Header.Set("loginId", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
fmt.Println(req.URL.String())
The last line outputs the URL it uses. With the code above this will be https://www.lrn.com. Given that you want to have query parameters the expected value would be instead https://www.lrn.com?output=json&... though. So something is clearly missing from your construction of the URL.
When activating the line you've explicitly commented out the result is very different:
req.URL.RawQuery = q.Encode() // activate this line
...
fmt.Println(req.URL.String())
In this case I get https://www.lrn.com?output=json&phoneList=XXXXXX&version=5, which is the expected value. And with this value the result from the server is for me the same as for your Python code.
But this seems to be only the first problem. Based on input in the comments I could track down the second problem, which was caused by a broken server together with header normalization by Golang. Based on the comments I've now used a different URL https://www.dncscrub.com/app/main/rpc/scrub where the Python code worked and the Golang code again did not work.
By comparing the HTTP requests used by both and reducing to their essential difference it showed, that the server erroneously interpreted a HTTP request header in a case-sensitive way. This worked
GET /app/main/rpc/scrub?version=5&phoneList=2123727200 HTTP/1.1
Host: www.dncscrub.com
loginId: 0610A62F
And resulted in the expected HTTP/1.1 401 Invalid credentials. While this did not work
GET /app/main/rpc/scrub?version=5&phoneList=2123727200 HTTP/1.1
Host: www.dncscrub.com
Loginid: 0610A62F
but resulted in a redirect HTTP/1.1 302 Found.
The only difference between these requests is the use of loginId: ... vs. Loginid: .... The server is clearly broken by treating HTTP header fields as case-sensitive, see Are HTTP headers case-sensitive?
which also links to the relevant standards.
Since req.Header.Set will normalize the header field one cannot use it. A work around is to manipulate the dictionary instead, which is usually not a good idea:
req.Header["loginId"] = []string{"0610A62F"}
See also GoLang: Case-sensitive HTTP Headers with net/http for a similar problem.

Python Django ConnectionAbortedError [WinError 10053]

So im facing a weird issue while making a request to my api. It works fine using something like postman. I get my response no issue but if I make a request from my frontend(on a seperate domain) the connection gets closed for some reason.
Here is my code
I make ajax request using axios
axios.get(mydomain/api/oauth)
.then(response => {
console.log(response)
}).catch(error => {
console.log(error.response.data)
})
which hits my backend method that should return a response like so
def oauth(request):
auth_client = AuthClient(
settings.CLIENT_ID,
settings.CLIENT_SECRET,
settings.REDIRECT_URI,
settings.ENVIRONMENT
)
url = auth_client.get_authorization_url([Scopes.ACCOUNTING])
request.session['state'] = auth_client.state_token
return HttpResponse(url)
But at this point I get this alarm
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
And like I said if I make this same request through postman I get my response. So I don't know what I am missing. I have applied cors thinking maybe its because my frontend is on seperate domain from backend but no luck. Plus the alarm is kind of vague... anybody face similar issue?

GET request via python script with access token

I'm facing some difficulties executing GET request with access token via python.
For some reason when I execute the request from POSTMAN I get the expected result, however, when using python I get connection error :
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
I believe that my script is being blocked by the server to prevent scrapping attempts, but I'm not sure.
This is what I'm running via POSTMAN :
https://www.operation.io/web/alerts?access_token=6ef06fee265de1fa640b6a444ba47--z&envId=58739be2c25e76a202c9dd3e&folderId=active&sortBy=status
And this is what I'm running from inside the script :
response = requests.get('https://www.operation.io/web/alerts', headers={'Authorization': 'access_token 6ef06fee265de1fa640b6a444ba47--z'})
Please notice that the url and the access token are not real, so please don't try to use.
How can I make it work via the script and not only via postman?
Thank you for your help/
It's hard to tell without actually being able to test the solutions, but I would suggest 2 hacks that worked for me in the past:
Change "Authorization" to "authorization"
Change "6ef06fee265de1fa640b6a444ba47--z" to "Token 6ef06fee265de1fa640b6a444ba47--z" (add a space as well)
Put it all together:
response = requests.get('https://www.operation.io/web/alerts', headers={'authorization': 'Token 6ef06fee265de1fa640b6a444ba47--z'})
Since via postman you're sending the token as query param(as opposed to header), you can try this :
response = requests.get('https://www.operation.io/web/alerts', params={'access_token': '6ef06fee265de1fa640b6a444ba47--z'})
Assuming the API you're using accepts it as query param rather than as headers (which is my guess from the postman request)

How can I target a specific application server using the HTTP "Host" header (using GoLang)

The question:
Why can't I target a server using it's IP address in the request URL and the hostname as the "Host" header using GoLang?
Why does the same thing work using python? (2.7.6 - urllib2)
Background:
I'm writing a systems test that will send HTTP requests to several specific application servers that I'm testing and inspect the results for correctness. Each application server has the same function and should return the same response data. These servers are grouped behind load balancers. These load balancers are then resolved by DNS and the traffic is forwarded to the backend servers as appropriate. In order to target each server independently (for the tests) I am using each server's IP address in the URL instead of the usual hostname and I'm setting the "Host" HTTP header to be the hostname that usually goes in the url. This is to make sure the SSL cert
can decode the secure (HTTPS) request.
Current status:
I already have a python script that sends these test requests. Here's the basic idea of that script:
headers = {"Host": "<hostname>"} # this <hostname> is usually what would go in the URL on the next line
request = urllib2.Request('https://<ip-address>/path?query=123', headers=headers)
response = urllib2.urlopen(request)
# etc...
This code has been working fine for several months now. I've verified that it is indeed targeting the correct servers, based on IP address.
Goal:
I want to replicate this script in golang to make use of the concurrent capabilities of go. The reason I'm using go is that I'd like to send lots more requests at a time (using goroutines).
Problem:
Using the same technique as shown above (but in Go) I get the following error:
Get https://<ip-address>/path?query=123: x509: cannot validate certificate for <ip-address> because it doesn't contain any IP SANs
Here's an example of the kind of code I have written:
request, _ := http.NewRequest("GET", "https://<ip-address>/path?query=123", nil)
request.Header.Set("Host", "<hostname>")
client := &http.Client{}
response, err := client.Do(request)
// etc...
Again, why does the python code work while the GoLang code returns an error?
As per the python documentation:
Warning: HTTPS requests do not do any verification of the server’s certificate.
To replicate this behavior in Go see: https://stackoverflow.com/a/12122718/216488

Categories

Resources