2

I'm trying to use the apps-script-oauth2 library to access the GitHub API in a Google Apps Script. I'm creating the service like this:

function getGithubService(client_id, client_secret) {
  return OAuth2.createService("GitHub")
    .setAuthorizationBaseUrl("https://github.com/login/oauth/authorize")
    .setTokenUrl("https://github.com/login/oauth/access_token")
    .setClientId(client_id)
    .setClientSecret(client_secret)
    .setCallbackFunction("authCallback")
    .setPropertyStore(PropertiesService.getUserProperties())
    .setCache(CacheService.getUserCache())
    .setLock(LockService.getUserLock())
    .setScope("repo");
}

function authCallback(request) {
  let github_service = getGithubService();
  if (github_service.handleCallback(request)) {
    return HtmlService.createHtmlOutput("Success!");
  }
  return false;
}

I can launch the authentication endpoint okay and get a valid access token back. But the token I get doesn't seem to be authorised for any scopes. I can log the token and try to use it in a curl request:

$ token=ghu_<censored>
$ curl -i -H "Authorization: bearer ${token}" https://api.github.com/user
...
x-oauth-scopes: 
x-accepted-oauth-scopes: 
...

The result of this is that any request I make for a resource that requires an authorised scope either fails or returns an empty list. In particular, the /org/{org-name}/repos endpoint just returns [] even though I've specified the repo scope in the service configuration above.

(Update: my org only has private repos; if I request this endpoint for an org with public repos, I get a useable repo list. Apparently I need the repo scope to get private repos.)

I'm requesting the repo list like this:

  let service = getGithubService(client_id, client_secret);
  let org_name = "...";
  let url = `https://api.github.com/orgs/${org_name}/repos`;
  let response = UrlFetchApp.fetch(url, {
    headers: {
      Authorization: `token ${service.getAccessToken()}`,
      Accept: "application/vnd.github.v3+json"
    }
  });
  let repos = JSON.parse(response.getContentText());

On a possibly-related point, is there supposed to be some way to relate the scope names used in OAuth2 requests to the permissions you can give an app in the GitHub developer settings page? I'm not at all sure I've granted the right set of permissions to the GitHub app to be able to request the repo scope in an auth request, but there doesn't seem to be any documentation at all on how the two relate.

Tom
  • 7,269
  • 1
  • 42
  • 69
  • is it possible you run your flow without scopes set, and then it cached? now you added your scope to apps script call, but it keeps with old token (no scopes)? – Kos Oct 20 '21 at 14:01
  • @Kos - possible. But I've tried doing the auth flow in a combination of curl and incognito windows to try to rule this out, without any obvious change. I've also tried revoking all access tokens from the github developer settings. – Tom Oct 20 '21 at 14:03
  • Does this answer your question? [How to list organization's private repositories via GitHub API?](https://stackoverflow.com/questions/16961947/how-to-list-organizations-private-repositories-via-github-api) – Kos Oct 20 '21 at 14:23
  • specifically see https://stackoverflow.com/a/52752677/555121 – Kos Oct 20 '21 at 14:24
  • @Kos - as far as I can tell, no. I'm the administrator for the org and I haven't enabled any extra app restrictions. When I do the oauth flow to authorise the github app, I'm not offered a way to request org access. – Tom Oct 20 '21 at 16:13
  • Well if you got token and done everything correctly but it's not having scopes in it then it's caching issue or API bug – Kos Oct 20 '21 at 16:21
  • I haven't tried your code yet, but shouldn't this line `Authorization: \`token ${service.getAccessToken()}\`,` be `Authorization: \`Bearer ${service.getAccessToken()}\`,` ? – Dmitry Kostyuk Oct 20 '21 at 16:47
  • Can you try specify private in your request: `https://api.github.com/orgs/${org_name}/repos?type=private` (or `internal`). Also check this: `However, the internal value is not yet supported when a GitHub App calls this API with an installation access token.` – Kos Oct 20 '21 at 17:22
  • @DmitryKostyuk the GitHub documentation mentions both and both appear to work (as in, a request for https://api.github.com/user with an invalid token generates an error but a valid token specified with either `token` or `Bearer` works). – Tom Oct 21 '21 at 13:22
  • @Kos - Adding `?type=private` to the request does not change things. I'd be a bit surprised if it did, since the access token doesn't seem ot have the `repo` scope assigned to it. As far as I can tell, this is the basic problem. I've lodged a support request with GitHub, will see what they come back with. – Tom Oct 21 '21 at 17:17
  • Yeah, usually there no scopes info in token itself, but GitHub may have their own implementation – Kos Oct 21 '21 at 17:26
  • Got an answer back from support. What I've created is a GitHub app and not an OAuth app, though it still authenticates the user using OAuth. Permission scopes work differently for GitHub apps and the app has to be installed into the organisation and repositories _as well as_ the user giving permission. Apologies if this is what you comment above was about and I just didn't understand. – Tom Oct 22 '21 at 16:24

0 Answers0