Skip to content

Commit

Permalink
Gracefully handle invalid access tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
sorenlouv committed May 8, 2019
1 parent fce7a4f commit be4a012
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 7 deletions.
6 changes: 2 additions & 4 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ Access tokens can be created here: https://github.com/settings/tokens/new

Please select the necessary access scopes:

- _repo:status (required for private repos)_
- _repo_deployment (required for private repos)_
- **public_repo (required)**
- _repo:invite (required for private repos)_
- `repo` (for public and private repos)
- `public_repo` (for public repos only)

CLI: `--accessToken myAccessToken`

Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getOptions } from './options/options';
async function init() {
try {
const options = await getOptions(process.argv);
return initSteps(options);
return await initSteps(options);
} catch (e) {
if (e.name === 'HandledError') {
console.error(e.message);
Expand Down
38 changes: 38 additions & 0 deletions src/services/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,44 @@ export async function addLabelsToPullRequest(
}
}

export async function verifyAccessToken(
owner: string,
repoName: string,
accessToken: string
) {
try {
return await axios.head(
`https://api.github.com/repos/${owner}/${repoName}?access_token=${accessToken}`
);
} catch (e) {
const error = e as GithubApiError;
const statusCode = error.response && error.response.status;

const grantedScopes = get(error, 'response.headers["x-oauth-scopes"]');
const requiredScopes = get(
error,
'response.headers["x-accepted-oauth-scopes"]'
);

switch (statusCode) {
case 401:
throw new HandledError(
`Please check your access token and make sure it is valid`
);
default:
if (grantedScopes === requiredScopes) {
throw new HandledError(
`The repository "${owner}/${repoName}" doesn't exist`
);
}

throw new HandledError(
`You do not have access to the repository "${owner}/${repoName}". Please make sure your access token has the required scopes.\n\nRequired scopes: ${requiredScopes}\nAccess token scopes: ${grantedScopes}`
);
}
}
}

export function setAccessToken(token: string) {
accessToken = token;
}
Expand Down
3 changes: 2 additions & 1 deletion src/steps/steps.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { setAccessToken } from '../services/github';
import { setAccessToken, verifyAccessToken } from '../services/github';
import { doBackportVersions } from './doBackportVersions';
import { BackportOptions } from '../options/options';
import { getCommits } from './getCommits';
Expand All @@ -7,6 +7,7 @@ import { maybeSetupRepo } from './maybeSetupRepo';

export async function initSteps(options: BackportOptions) {
const [owner, repoName] = options.upstream.split('/');
await verifyAccessToken(owner, repoName, options.accessToken);
setAccessToken(options.accessToken);

const commits = await getCommits(options);
Expand Down
22 changes: 21 additions & 1 deletion test/steps/__snapshots__/steps.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,27 @@ Object {
"xsrfHeaderName": "X-XSRF-TOKEN",
},
],
"head": Array [],
"head": Array [
Object {
"data": undefined,
"headers": Object {
"Accept": "application/json, text/plain, */*",
},
"maxContentLength": -1,
"method": "head",
"timeout": 0,
"transformRequest": Object {
"0": [Function],
},
"transformResponse": Object {
"0": [Function],
},
"url": "https://api.github.com/repos/elastic/kibana?access_token=myAccessToken",
"validateStatus": [Function],
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
},
],
"list": Array [],
"options": Array [],
"patch": Array [],
Expand Down
16 changes: 16 additions & 0 deletions test/steps/steps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ function mockGetPullRequest(
});
}

function mockVerifyAccessToken(
axiosMock: MockAdapter,
owner: string,
repoName: string,
accessToken: string
) {
return axiosMock
.onHead(
`https://api.github.com/repos/${owner}/${repoName}?access_token=${accessToken}`
)
.reply(200);
}

function mockGetCommits(
axiosMock: MockAdapter,
{
Expand Down Expand Up @@ -111,6 +124,9 @@ describe('run through steps', () => {
});

axiosMock = new MockAdapter(axios);

mockVerifyAccessToken(axiosMock, owner, repoName, accessToken);

mockGetCommits(axiosMock, {
owner,
repoName,
Expand Down

0 comments on commit be4a012

Please sign in to comment.