I am new to GitHub API and trying to create a file in my repo using API.
I am using postman to check the API first.
PUT Method:
URL:https://api.github.com/repos/KaranS-hexaware/Rapidx_Documentation/contents/text.txt
Body:{
"message":"my commit message",
"content":"bXkgbmV3IGZpbGUgY29udGVudHM="
}
Header
Authorization:Bearer ****************************************************
Content-Type:application/vnd.api+json
The response is:
{
"message": "Not Found",
"documentation_url": "https://docs.github.com/rest/reference/repos#create-or-update-file-contents"
}
Can I get some input on what I am missing here?
The create file contents API example is:
curl \
-X PUT \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token <TOKEN>" \
https://api.github.com/repos/OWNER/REPO/contents/PATH \
-d '{"message":"my commit message","committer":{"name":"Monalisa Octocat","email":"octocat#github.com"},"content":"bXkgbmV3IGZpbGUgY29udGVudHM="}'
Check if those headers (which are slightly different than yours) make a difference and allow your call to succeed.
Related
I used to be able to make the following call with a Personal Access Token (the classic token)
curl https://$PAT#raw.githubusercontent.com/$ORG/$REPO/master/$FILE
But now I just get the Github default 404 response.
If I follow a different approach the the file is accessible.
curl -H 'Authorization: token $PAT' \
-H 'Accept: application/vnd.github.v3.raw' \
-O -L https://api.github.com/$ORG/$REPO/master/$FILE
I can't find anything in the docs that states the old curl URL request has been removed. Has this method now been removed?
I have been trying to write a code using terraform which must do an API call on POST and it must get back value on post, this return value on post I must be able to use it else where in the code.
Reading a lot I noticed there are two ways to do it
Mastercard Rest API
Local-Exec and Null provider
The first one also has some issues when we try to fetch a value on post, unfortunately the API I am trying to call needs some input values to return an output. If anyone has experience in doing this using the mastercard rest api please let me know how.
My curl statement looks like this -
curl --insecure -X POST 'https://url.fqdn/get_hostname' --header 'Content-Type: application/json' --header 'Authorization: Basic tokenvalue' -d '{"key": "value","key": "value","key": "value"}'
Using local-exec and null provider
resource "null_resource" "get-hostname" {
provisioner "local-exec" {
command = <<EOF
curl --insecure -X POST 'https://url.fqdn/get_hostname' --header 'Content-Type: application/json' --header 'Authorization: Basic tokenvalue' -d '{"key1": "value1","key2": "value2"}'
EOF
}
}
How can I get the output of the command property ?
You can redirect the output of curl to a file, and process that file within another null_resource block with an explicit dependency on the one that writes the file.
I am currently working on some code to interact with images on the Google Container Registry. I have working code both using plain curl and also httpx. I am trying to build a package without 3rd party dependencies. My curiosity is around a particular endpoint from which I get a successful response in curl and httpx but a 401 Unauthorized using urllib.request.
The bash script that demonstrates what I'm trying to achieve is the following. It retrieves an access token from the registry API, then uses that token to verify that the API indeed runs version 2 and tries to access a particular Docker image configuration. I'm afraid that in order to test this, you will need access to a private GCR image and a digest for one of the tags.
#!/usr/bin/env bash
set -eu
token=$(gcloud auth print-access-token)
image=...
digest=sha256:...
get_token() {
curl -sSL \
-G \
--http1.1 \
-H "Authorization: Bearer ${token}" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
--data-urlencode "scope=repository:$1:pull" \
--data-urlencode "service=gcr.io" \
"https://gcr.io/v2/token" | jq -r '.token'
}
echo "---"
echo "Retrieving access token."
access_token=$(get_token ${image})
echo
echo "---"
echo "Testing version 2 capability with access token."
curl -sSL \
--http1.1 \
-o /dev/null \
-w "%{http_code}" \
-H "Authorization: Bearer ${access_token}" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
https://gcr.io/v2/
echo
echo "---"
echo "Retrieving image configuration with access token."
curl -vL \
--http1.1 \
-o /dev/null \
-w "%{http_code}" \
-H "Authorization: Bearer ${access_token}" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
"https://gcr.io/v2/${image}/blobs/${digest}"
I additionally created two Jupyter notebooks demonstrating my solutions in httpx and bare urllib.request. The httpx one works perfectly while somehow urllib fails on the image configuration request. I'm running out of ideas trying to spot the difference. If you run the notebook yourself, you will see that the called URL contains a token as a query parameter (is this a security issue?). When I open that link I can actually successfully download the data myself. Maybe urllib still passes along the Authorization header with the Bearer token making that last call fail with 401 Unauthorized?
Any insights are greatly appreciated.
I did some investigation and I believe the difference is that the last call to "https://gcr.io/v2/${image}/blobs/${digest}" actually contains a redirect. Inspecting the curl and httpx calls showed me that both do not include the Authorization header in the second, redirected request, whereas in the way that I set up the urllib.request in the notebook, this header is always included. It's a bit odd that this leads to a 401 but now I know how to address it.
Edit: I can now confirm that by building a urllib.request.Request instance and unlike in the linked notebook, add the authorization header with the request's add_unredirected_header method, everything works as expected.
I do have a simple AWS API Gateway implementation protected by an AWS_IAM Authorization.
I just want to test from command line via cURL :
curl --location --request GET 'https://<API_ID>.execute-api.eu-west-1.amazonaws.com/stage?type=type&category=category&lc=lc&passprhase=passprhase&product=product'
--header 'Authorization: AWS4-HMAC-SHA256 Credential=<AWS_ACCESS_KEY>/20200127/eu-west-1/execute-api/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=<AWS_SECRET_ACCESS_KEY>' --header 'Content-Type: application/json' \
--data-raw '{"query":"","variables":{}}'
but keep getting the follow error :
Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header.
Can someone advice what am I doing wrong ?
AWS V4 signature authentication is supported in curl starting from version 7.75, so you should be able to call your AWS resource this way:
curl --location --request GET 'https://$API-ID.execute-api.eu-west-1.amazonaws.com/stage?type=type&category=category&lc=lc&passprhase=passprhase&product=product' \
--header 'Content-Type: application/json' \
--user $ACCESS_KEY:$SECRET_KEY \
--aws-sigv4 "aws:amz" \
--data-raw '{"query":"","variables":{}}'
Note that you may need to add in the --aws-sigv4 value your region and service.
For example: --aws-sigv4 "aws:amz:eu-west-2:execute-api"
You can find more documentation here: https://curl.se/libcurl/c/CURLOPT_AWS_SIGV4.html
And the documentation for the CLI option here: https://curl.se/docs/manpage.html#--aws-sigv4
AWS_IAM authorization uses Sigv4 and its calculation process requires values certain headers - Date being one of them. You are passing x-amz-date as a part of the "SignedHeaders" field, but not actually passing it with the other headers.
One way to create the right curl command to invoke an API with AWS_IAM would be to use Postman application. Add in the API URL and select "AWS Signature" under Authorization tab. You can then select the "Code" option and get the full curl command which would look something like this -
curl -X POST \
https://$API-ID.execute-api.$AWS_REGION.amazonaws.com/$STAGE/$RESOURCE \
-H 'authorization: AWS4-HMAC-SHA256 Credential=$ACCESS_KEY/20200128/$AWS_REGION/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=$SIGNATURE_VALUE' \
-H 'cache-control: no-cache' \
-H 'content-type: application/x-www-form-urlencoded' \
-H 'host: API-ID.execute-api.$AWS_REGION.amazonaws.com' \
-H 'postman-token: 15f9498e-95b7-f22b-eed9-016cdea07424' \
-H 'x-amz-date: $DATE_STAMP'
Create a Canonical Request for Signature Version 4
I could suggest to use awscurl which is much easier.
To install awscurl click here. For documentation you can refer here.
Example to call apigateway to call lambda for POST query is below.
awscurl --service execute-api -X POST -d '{ "alias" : "xyx", "type" : "LDAP" }' https://.execute-api.us-west-2.amazonaws.com/Prod/user/groups/get --region us-west-2 --access_key ACCESS_KEY --secret_key mfBl0YJRsXDue4C5F5B6rz1eUpQpA8uC24RtSnsg --security_token SECURITY_TOKEN
I just setup a OneLogin account and wish to do a basic test from the command line with curl according to the docs at
https://developers.onelogin.com/api-docs/1/getting-started/working-with-api-credentials
and
https://developers.onelogin.com/api-docs/1/oauth20-tokens/generate-tokens-2
I get "unauthorized" despite many permutations of the curl command. Let me start with the curl command as included in the docs in the second link above. I do this:
curl 'https://api.us.onelogin.com/auth/oauth2/v2/token' \
-X POST \
-H "Authorization: client_id:144a1200f765fc67f1e, client_secret:d2dc92524169ee2" \
-H "Content-Type: application/json" \
-d '{
"grant_type":"client_credentials"
}'
(fake client_id and client_secret is included so that you can see the form they take in my call, i.e., spaces, encoding, etc.)
Response:
{"status":{"error":true,"code":401,"type":"Unauthorized","message":"Authentication Failure"}}
So I tried everything I could think of in terms of the "Authorization" line. Here are some examples of what I tried:
# base64 encode just the client_id and the client_secret (i.e., separately encoded and independent)
Authorization: client_id:zODU1NjYwOTRiZjYwOWFiOWJiZDQ1NGZjNg==, client_secret:WIxY2NjZWJjNWJlZDJlZDdiYmFiMDZiYTkyNzY3M2IxZQ==
# result: unauthorized
# base64 encode "Basic <client_id:client_secret>"
Authorization: Basic NjllZTIxZGRjOWU5YjFjY2NlYmM1YmVkMmVkN2JiYWIwNmJhOTI3NjczYjFl
# result: unauthorized
# use Basic without base64 encoding id and secret
Authorization: Basic 094bf609ab9bbd454fc6:c5bed2ed7bbab06ba927673b1e
# result: unauthorized
And finally... here is an image of the credentials page to demonstrate that I indeed did create the id and secret in the proper place.
I'm embarrassed to give the solution to this answer and there is no way from the question anyone could have answered this correctly except by guessing.
I accidentally swapped the client_id and client_secret early in my work flow and never went back to double check them... or at least if I did double check them I made the same error twice.
My best guess for why I swapped them is that they appear in one order (client_id, client_secret) in the docs and API, and they appear in the reverse order in the OneLogin UI (client_secret, client_id). You can see this in my OP.
The correct curl command is the first one I gave in the answer... plain text client id and secret (not base64 encoded). Here it is again for reference:
curl 'https://api.us.onelogin.com/auth/oauth2/v2/token' \
-X POST \
-H "Authorization: client_id:bed2ed7bbab06ba927673b1e, client_secret:385566094bf609ab9bbd454fc6" \
-H "Content-Type: application/json" \
-d '{
"grant_type":"client_credentials"
}'