I'm writing a Github API client and a webhook.
Is there any way to distinguish if an event (i.e assignment, issue open, etc etc) is trigered by API or by user directly (i.e via git's web ui) ?
I read what payload github will send on it's webhook call, but could not find one.
sincerely
-bino-
I'm not sure what it looks on the server side, but at least when using the UI, the POST payload seems to be form-data, and with API it is JSON-formatted.
From my tests with UI:
...
Content-Disposition: form-data; name="issue[user_assignee_ids][]"
28
------
and from GitHub API documentation:
{
"assignees": [
"hubot",
"other_user"
]
}
This also means that the requests content-type header is different: for form data it is content-type: multipart/form-data; ... and for JSON it should be content-type: application/json.
Related
I'm using the Connexion framework for my Python Flask project. In the API spec (using the yaml file format) I defined "consumes" and "produces" field like this:
produces:
- application/json
consumes:
- application/json
The Connexion documentanation says that Connexion automatically validates the request based on the API specification, so I thought that it would automatically verify that incoming "Accept" (or "Content-Type") headers would match "application/json" using the above data as example.
However, this doesn't seem to be the case. If I omit the Accept header and Content-Type header, or add them with random values, there are no warnings or errors or anything.
Have other Connexion users gotten Connexion to validate media types data? Or do you handle this explicitly in your code?
EDIT: Seems like this bug report addresses this issue.
I'm using the versions:
connexion == 1.5.3 swagger
spec-validator == 2.4.0
When I execute an operation in this scenario where I wait for "application/json" and send a different Content I get a 415 with the body:
{
"detail": "Invalid Content-type (application/javascript), expected JSON data",
"status": 415,
"title": "Unsupported Media Type",
"type": "about:blank"
}
In this case i sent a request with the Content "application/javascript"
I have built an application using python django rest framework and Vue js.
The rest framework link is something similar like this 198.123.1.1:8001/test i am using this link to get records in Vuejs.
when i call this link generally 198.123.1.1:8001/test
GET /test/
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"test_id": 11,
"test_n_key": "as-all-1",
}
i am getting the below response now i want to hide this response to outside world and what will be the better way to do it.
1)I don't want to show this url to outside world.
2)when someone is calling this from browser other than application it should not show it
if the API is exposed to the outside world you cant hide it, add an authentication to the API and prevent external request.
Add authentication and CORS:
CORS-Headers
Authentication
I have created RESTFul APIs using django-rest-framework. The user endpoint is: /api/v1/users
I want to create a new user, so I send the user data in JSON format:
{
"username": "Test1",
"email": "test1#gmail.com",
"first_name": "Test1",
"last_name": "Test2",
"password":"12121212"
}
I am using Google Chrome extension Postman to test the API. But, after sending the request, the user data is not saving. The response contains this error:
{
"detail": "Unsupported media type \"text/plain;charset=UTF-8\" in request."
}
This is what the request details look like in Postman:
You have missed adding the Content-Type header in the headers section. Just set the Content-Type header to application/json and it should work.
See the below image:
Also, you might also need to include a CSRF token in the header in case you get an error {"detail": "CSRF Failed: CSRF token missing or incorrect."} while making a POST request using Postman. In that case, add an X-CSRFToken header also with value as the CSRF token value.
I'm posting this answer in case someone is facing a problem like mine.
I'm working on a Front-End app using Angular 2 with an API made with Django Rest Framework and I used to send requests with the following headers:
'Content-Type': 'application/json'
And it was working fine until I tried it on Fire Fox and I couldn't load the needed data and I solved it with adding the following headers
'Content-Type': 'application/json',
'Accept': 'application/json'
Here's an explanation, Content-Type tells the server what is the content type of data is while Accept tells it what content type the client side will accpet.
Here's a nice clear answer about this issue:
https://webmasters.stackexchange.com/questions/31212/difference-between-the-accept-and-content-type-http-headers
You need to do two step to done this issue:
Add Content-Type header with application/json value
Add Authorization header with Token {YOUR_CUSTOM_TOKEN} value to pass CSRFToken
Note: if you want to authenticate with session, you don't need to do second step, but if you want use this API for mobile, you have to pass Authorization header to server
I hope it helps
You need to define content type by setting the appropriate headers. In case of Postman you need to set the following values under url field:
Header: "Content-Type"
Value: application/json
I had to add the following to get this to work (I'm using node-fetch btw from the client side to do a POST):
supportHeaderParams: true,
headers: { "Content-Type": "application/json; charset=UTF-8" },
Couple of things to do if you want to accept JSON Data using Django Rest Framework.
Make sure application/json headers are sent:
'Content-Type: application/json'
JSON Parser is selected in settings.py
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
],
}
I have been able to view the attributes of the PreparedRequest that botocore sends, but I'm wondering how I can view the exact request string that is sent to AWS. I need the exact request string to be able to compare it to another application I'm testing AWS calls with.
You could also enable debug logging in boto3. That will log all requests and responses as well as lots of other things. Its a bit obscure to enable it:
import boto3
boto3.set_stream_logger(name='botocore')
The reason you have to specify botocore as the name to log is that all of the actual requests and responses happen at the botocore layer.
So what you probably want to do is to send your request through the proxy (mitmproxy, squid). Then check the proxy for what was sent.
Since HTTPS data is encrypted you must first decrypt it, then log the response, then encrypt it back and send to AWS. One of the options is to use mitmproxy. ( It's really easy to install )
Run mitmproxy
Open up another terminal and point proxy to mitmproxys port:
export http_proxy=127.0.0.1:8080
export https_proxy=$http_proxy
Then set verify=False when creating session/client
In [1]: import botocore.session
In [2]: client = botocore.session.Session().create_client('elasticache', verify=False)
Send request and look at the output of mitmproxy
In [3]: client.describe_cache_engine_versions()
The result should be similar to this:
Host: elasticache.us-east-1.amazonaws.com
Accept-Encoding: identity
Content-Length: 53
Content-Type: application/x-www-form-urlencoded
Authorization: AWS4-HMAC-SHA256 Credential=FOOOOOO/20150428/us-east-1/elasticache/aws4_request, SignedHeaders=host;user-agent;x-amz-date, Signature=BAAAAAAR
X-Amz-Date: 20150428T213004Z
User-Agent: Botocore/0.103.0 Python/2.7.6 Linux/3.13.0-49-generic
<?xml version='1.0' encoding='UTF-8'?>
<DescribeCacheEngineVersionsResponse
xmlns="http://elasticache.amazonaws.com/doc/2015-02-02/">
<DescribeCacheEngineVersionsResult>
<CacheEngineVersions>
<CacheEngineVersion>
<CacheParameterGroupFamily>memcached1.4</CacheParameterGroupFamily>
<Engine>memcached</Engine>
<CacheEngineVersionDescription>memcached version 1.4.14</CacheEngineVersionDescription>
<CacheEngineDescription>memcached</CacheEngineDescription>
<EngineVersion>1.4.14</EngineVersion>
I implemented the experimental OAuth support for Google App Engine using Python, and have it working locally, but the endpoints are throwing a 400 when I deploy to appspot.
For example, the url http(s)://my-app.appspot.com/_ah/OAuthGetRequestToken returns a 400, but locally that url pattern behaves as expected.
I have tried both http and https, and assumed that appspot handles the ssl cert.
UPDATE
I've been using the OAuth Playground to test my code. Despite documentation, it seems Registering your app is required. Go here for instructions on how to register. According to documentation during the registration process, certificate is not required when running on App Engine. Playground is showing more detail on the error - "signature invalid". If I understand correctly, the signature is produced from a signature base string. In this case I am using the base string 7DYB6MJ2s-IQcd7VJYJUmcct .
GET /accounts/OAuthGetRequestToken?scope=https%3A%2F%2Fmail.google.com%2Fmail%2Ffeed%2Fatom HTTP/1.1
Host: www.google.com
Accept: */*
Authorization: OAuth oauth_version="1.0", oauth_nonce="168cfd60a93a46caa38dddfdcedd9de9", oauth_timestamp="1305315895", oauth_consumer_key="xxxxxxx.appspot.com", oauth_callback="http%3A%2F%2Fgooglecodesamples.com%2Foauth_playground%2Findex.php", oauth_signature_method="HMAC-SHA1", oauth_signature="4J5faUujE0VNaybyvFCiEPY7DQ8%3D"
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=UTF-8
Date: Fri, 13 May 2011 19:44:55 GMT
Expires: Fri, 13 May 2011 19:44:55 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Length: 451
Server: GSE
**signature_invalid**
base_string:GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_callback%3Dhttp%253A%252F%252Fgooglecodesamples.com%252Foauth_playground%252Findex.php%26oauth_consumer_key%3Dxxxxxx.appspot.com%26oauth_nonce%3D168cf60a94caa38e2defdcedd9de9%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1305315895%26oauth_version%3D1.0%26scope%3Dhttps%253A%252F%252Fmail.google.com%252Fmail%252Ffeed%252Fatom
FINAL UPDATE
There were two things causing the 400. First, the app was not registered. Google's documentation says it's optional, but that is not the case apparently. Secondly, the Request was not properly signed. Here is an excellent debugging tool to test your OAuth Requests: Oauth Playground
You must register your domain in order to have OAuth working on production.
Although the following docs state that Registering is Optional:
http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html
It doesn't work without the Registration since January.
Look at the link above and Register your domain/application. You don't need to submit a certificate, this is still optional.
Which request method it is? In dev_appserver_oauth.py I see:
if method != 'GET' and method != 'POST':
outfile.write('Status: 400\r\n')
return
So it'll only work for GET or POST requests.
First ensure you have enabled Federated Login in your Application Settings.
From your description it sounds like you might just be performing a direct GET request to /_ah/OAuthGetRequestToken without any of the other required parameters of oAuth. This will work on the dev_appserver as it is simply a mockup of oAuth to let you flesh out your code.
See the parameters listed on the OAuthGetRequestToken description page for what is required and how to deal with signing. I believe you can ignore scope for GAE though