Creating a fork with the GitHub V3 API (REST) - api

I'm trying to fork a repo using the GitHub V3 API via REST, however, I am having issues making a POST request as per the docs (https://developer.github.com/v3/repos/forks/#create-a-fork).
Basically, what I have so far:
A logged-in user with an OAuth Token
A POST request setup to the API (URL: https://api.github.com/repos/carmichaelalonso/infiniteflight/forks/) - I am testing this with hurl.it to begin with.
Headers in the request: one has the name Authorization with the value 'token ...', the other specifies Content-Type with the value application/json
A body with the following JSON: {"organization" : "shortlisthome"} (shortlisthome is the account I am trying to fork the repo to.
I am not intending to fork this to an organization, instead of a standard user account, which is where I am getting confused. When I run the request, I do not get any authentication errors or 404 errors (I previously had but I had been entering incorrect values by mistake, causing such errors).
When I run this request though, I get the following result (a 422 unprocessable request):
{
"message": "Validation Failed",
"documentation_url": "---url-to-docs---",
"errors": [
{
"resource": "Fork",
"code": "invalid",
"field": "organization"
}
]
}
I am unsure whether or not I am able to fork this to a standard user, or if it is an error with my request. Please let me know if I can provide any more info (first post here so a bit unfamiliar with the convention).
Thanks!

In order for shortlisthome to fork the repository you need to authenticate as them. The repository you're trying to fork is public, so all you need to do is obtain a OAuth token for shortlisthome and then make a similar request to the one you're making now. The only difference will be that you do not need to provide the JSON body of {"organization": "shortlisthome"}.
For what it is worth, the optional JSON body is intended for you to use when you are a member of an organization with proper permissions and you want to fork the repository to that organization. You cannot fork a repository to someone else's account unless you are authenticated as them.

I've so far avoided OAuth2, and do not know hurl. Yet, perhaps this can help.
This post shows how it can be done using cURL's -u username flag:
curl -u 'myusername' https://api.github.com/repos/carmichaelalonso/infiniteflight/forks/ -d ''
The -d (or alternatively --data) flag turns it into a POST request.
Without that flag cURL defaults to a GET request, which is not what you want.
Since, the data is part of the URI for this request, send an empty string for the data that must follow the -d param, as such: -d ''.
Of course, using -u will require you to also supply a password..
Here is what GitHub shows using OAuth2 with their API:
OAuth2 Token (sent in a header):
curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com
OAuth2 Token (sent as a parameter):
curl https://api.github.com/?access_token=OAUTH-TOKEN
Read more about OAuth2. Note that OAuth2 tokens can be acquired programmatically, for applications that are not websites.
OAuth2 Key/Secret
curl 'https://api.github.com/users/whatever?client_id=xxxx&client_secret=yyyy'
I suspect that adding -d '' (or some equivalent in hurl),
plus one of the formats above for sending OAuth2 info might get you most of the way there.

I used this command to fork on github enterprise
curl -vX POST https://git.redacted.com/api/v3/repos/<org-to-fork-from>/<repo-to-fork>/forks?access_token=<api-token> -d #gh-fork.json --header "Content-Type: application/json"
gh-fork.json is just
{
"organization": "org-to-fork-to",
"description": "",
"homepage": "https://git.redacted.com",
"private": false
}

Related

Getting GitHub Branch protection returns "404 Not Found"

I have tried to get the Branch policies using curl / Postman however I keep getting Error "404 Not Found".
Based on the documentation (https://docs.github.com/en/rest/reference/repos#get-branch-protection), I seem to be using the correct API Uri. see below commands used. Ps: Auth Token has been verified.
For Curl :
curl \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/{owner}/{repo}/branches/{branch}/protection
Postman:
https://api.github.com/repos/{owner}/{repo}/branches/{branch}/protection
I need API call to return the Branch protection. Thanks!
while at the moment not clearly documented,
this API URI requires the provided access token to have admin privileges for the repository.

Soundcloud API authentication always throws "401 - Unauthorized"

Due to the new updates of the Soundcloud API, I'm trying to update the authentication flow in my code ( the project was using login and password ).
But I'm blocked by a problem, and I'm losing my head.
I follow instructions on this page : https://developers.soundcloud.com/blog/security-updates-api
I manage to get a refresh token and an access token with this :
curl --request POST \
--url https://api.soundcloud.com/oauth2/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data client_id=CLIENT_ID \
--data client_secret=CLIENT_SECRET \
--data grant_type=client_credentials
But I'm not able to execute this request, which is an example in the mentionned page, with the access token I got with the previous request :
curl --request GET \
--url 'https://api.soundcloud.com/me/tracks?limit=1' \
--header 'Authorization: OAuth ACCESS_TOKEN'
The request response is always :{"code":401,"message":"","link":"https://developers.soundcloud.com/docs/api/explorer/open-api","status":"401 - Unauthorized","errors":[],"error":null}
I tried with a refresh of my access token, and with the url "https://api.soundcloud.com/me" instead of "https://api.soundcloud.com/me/tracks?limit=1".
And always returning the same error.
Can someone help me ?
Thanks by advance, and thanks for reading.
OK, I think I got it, thanks to this question on github :
https://github.com/soundcloud/api/issues/76
"The client_credentials auth flow is meant only for server-side integration and allows access to public endpoints only. Meaning that for endpoint /me or any other user-related endpoint you have to use the Authorization Code flow which provides the client-side integration."
And here : https://developers.soundcloud.com/docs/api/guide#authentication :
"if your app needs to access only public resources, you can use the OAuth Client Credentials Flow"
I'm done with the error messages too blurry... and with me reading too fast !
I will add the correct authentication method in comments later.
UPDATE : "manual" authentication flow
As the project is behind a VPN, I can't use normal authentication flow ( redirect_uri can't be called by soundcloud !)
So :
Get a "code"
First, authenticate on SoundCloud with the account you want to access ( or ask your customer to do it )
In your browser, type this url :
https://api.soundcloud.com/connect?client_id=YOUR_CLIENT_ID&response_type=code&scope=&state=[random_string]&redirect_uri=YOUR_REDIRECT_URI
Accept the demand and this will redirect you to an URL with the code inside : code=YOUR_CODE. Keep it. If this is done by your customer, simply ask him to copy-paste the url.
That's not really secure, but you can't avoid it if your redirect uri is not accessible from Soundcloud.
Obtain a refresh token and an access token :
With curl, to keep your Client Secret, or App Secret, secret ( indeed :D ). And also the access token.
curl -X POST "https://api.soundcloud.com/oauth2/token"
-H "accept: application/json; charset=utf-8"
-H "Content-Type: application/x-www-form-urlencoded"
-d "grant_type=authorization_code&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&redirect_uri=YOUR_REDIRECT_URI&code=YOUR_CODE"
This last request will answer in json format. Inside, you'll find an access token, and a refresh token.
Register the refresh token in your projet to reuse it to refresh your access token when needed !

GCP REST api authentication missing

I have created a job of JDBC to BigQuery using the web interface and it worked just fine.
Now I want to create the same job from the REST API of GCP so I took the rest equivalent of the request from the site and tried to send it from Postman.
I'm sending POST request for the following URL:
https://dataflow.googleapis.com/v1b3/projects/test-data-308414/templates:launch?gcsPath=gs://dataflow-templates/latest/Jdbc_to_BigQuery
which I got from the example in the GCP documentation.
I also pass the JSON that the GCP gave me in the body.
And the API key as get parameter in the next format "?key=[API_KEY]"
I'm getting 401 response from the server with the following message:
Request is missing required authentication credential. Expected OAuth
2 access token, login cookie or other valid authentication credential.
See
https://developers.google.com/identity/sign-in/web/devconsole-project.
With a status of:
UNAUTHENTICATED
I looked up at the link and found a tutorial on how to create google authentication on the front end
witch is not helpful to me.
I'm pretty sure that I'm passing the API key in the wrong format and that the reason it failed to authenticate.
But I couldn't find any documentation that says how to do it correctly.
PS> I have also tried passing it at the headers as I saw in one place
in the next format
Authorization : [API_KEY]
but it failed with the same message
Few days back I was trying to integrate GCP into MechCloud and struggling to figure out how to invoke a microservice ( which is acting as a proxy to GCP) with credentials for different projects which will be passed to this microservice on the fly. I was surprised that in spite of spending good amount of time I could not figure out how to achieve it because GCP documentation is focused on working with one project credentials at a time using application default credentials. Another frustrating thing is that API explorer shows both OAuth 2.0 and API Key by default for all the APIs when the fact is that API Key is hardly supported for any API. Finally I found the solution for this problem here.
Here are the steps to invoke a GCP rest api -
Create a service account for your project and download the json file associated with it.
Note down values of client_email, private_key_id and private_key attribues from service account json file.
Define following environment variables using above values -
GCP_SERVICE_ACCOUNT_CLIENT_EMAIL=<client_email>
GCP_SERVICE_ACCOUNT_PRIVATE_KEY_ID=<private_key_id>
GCP_SERVICE_ACCOUNT_PRIVATE_KEY=<private_key>
Execute following python code to generate jwt_token -
import time, jwt, os
iat = time.time()
exp = iat + 3600
client_email = os.getenv('GCP_SERVICE_ACCOUNT_CLIENT_EMAIL')
private_key_id = os.getenv('GCP_SERVICE_ACCOUNT_PRIVATE_KEY_ID')
private_key = os.getenv('GCP_SERVICE_ACCOUNT_PRIVATE_KEY')
payload = {
'iss': client_email,
'sub': client_email,
'aud': 'https://compute.googleapis.com/',
'iat': iat,
'exp': exp
}
private_key1 = private_key.replace('\\n', '\n')
# print(private_key1)
additional_headers = {'kid': private_key_id}
signed_jwt = jwt.encode(
payload,
private_key1,
headers=additional_headers,
algorithm='RS256'
)
print(signed_jwt)
Use generated jwt token from previous step and use it as a bearer token to invoke any GCP rest api. E.g.
curl -X GET --header 'Authorization: Bearer <jwt_token>' 'https://compute.googleapis.com/compute/v1/projects/{project}/global/networks'
The best practice to authenticate a request is to use your application credentials. Just make sure you installed the google cloud SDK.
curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-d #request.json \
https://dataflow.googleapis.com/v1b3/projects/PROJECT_ID/templates:launch?gcsPath=gs://dataflow-templates/latest/Jdbc_to_BigQuery

How to use "user context access token" that I get from Twitter OAuth 1.0a in my request?

I have successfully (?) implement the Twitter three-legged authentication process to obtain user access token. The problem is the access token appears invalid... or I use it wrong. I already able to get the app's access token, which can access limited Twitter API. I use it by adding "Authentication: Bearer 'access token'" on the header. But when I did the same thing with the user context access token and did the same request, I always get error code 89 Invalid or expired token.
The access token I obtained has a structure of [several numerics]-[some alpha numeric chars]. Like 12345678-asd98f798asdf79asdfa9sdfs9df7a9sdf7. This looks similar with the access token example in step 3 of https://developer.twitter.com/en/docs/basics/authentication/oauth-1-0a/obtaining-user-access-tokens.
I also notice that the example request there is like this:
POST statuses/update.json
oauth_consumer_key=cChZNFj6T5R0TigYB9yd1w
oauth_token=7588892-kagSNqWge8gB1WwE3plnFsJHAZVfxWD7Vb57p0b4
Which I presume those two additional parameters are to be added to the body instead of the header. But, how if my request is a GET request? Like request to get home timeline, which absolutely requiring user context access token?
https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-home_timeline
From this API ref, the example only give the GET url, and not how to supply the user context access token. Please help. I have the feeling that the solution is very simple (like a fix on the header), but I can't see it.
This is my current request:
curl -X GET \
'https://api.twitter.com/1.1/users/show.json?screen_name=huffpost' \
-H 'Authorization: Bearer 12345678-as3d12a3d1a3sd1232ads13asd123as1d23as3d32,Bearer 12345678-as3d12a3d1a3sd1232ads13asd123as1d23as3d32' \
This is the result:
{
"errors": [
{
"code": 89,
"message": "Invalid or expired token."
}
]
}
The user access token requires signing a request which includes parameters and headers.
https://developer.twitter.com/en/docs/basics/authentication/oauth-1-0a/authorizing-a-request
You can use a library like https://github.com/twitter/joauth to generate the signature.
For Java+OkHttp - you can use this library https://github.com/yschimke/okurl/blob/master/src/main/kotlin/com/baulsupp/okurl/services/twitter/joauth/Signature.kt#L33

Google Sheets API v4 append request receives HTTP 401 response for public feeds using API Key

This is extremely similar to another question answered here about how to GET spreadsheet data, but I'm trying to append data to a spreadsheet. Here's my sample curl request:
curl -H "Content-Type: application/json" -X POST -d '{"range":"A1","majorDimension":"ROWS","values":["Frank2"]}' https://sheets.googleapis.com/v4/spreadsheets/{SPREADSHEET_ID}/values/A1:append?valueInputOption=RAW&key={API-KEY}
Here's the response:
{
"error": {
"code": 401,
"message": "The request does not have valid authentication credentials.",
"status": "UNAUTHENTICATED"
}
}
Can this be done only using an API Key or am I doing something wrong? The documentation suggests it is possible if the spreadsheet is shared publicly.
Requests that write to the spreadsheet require authentication credentials. Even if the spreadsheet is shared publicly, when writing through the API the write must be attributed to a user.
This is currently broken. You can not edit the document (even if public) with only an APIKey.
https://issuetracker.google.com/issues/73974970
https://developers.google.com/sheets/api/guides/authorizing#APIKey
The page above states the following:
Your application must use OAuth 2.0 to authorize requests. No other authorization protocols are supported. If your application uses Google Sign-In, some aspects of authorization are handled for you.