Return an empty token where an installation owner is not allowed

While this is less obvious to the user this facilitates anonymous access
to (public) files where the app is installed but the owner is not in the
allowed list.

Signed-off-by: Iain Billett <iain@roadie.io>
This commit is contained in:
Iain Billett
2022-01-18 18:01:07 +00:00
parent 5387ea8f0d
commit 2030b5e80d
2 changed files with 39 additions and 3 deletions
@@ -136,6 +136,44 @@ describe('SingleInstanceGithubCredentialsProvider tests', () => {
expect(token).toEqual('secret_token');
});
it('does not return a token where the organisation is not in the allowedInstallationsList', async () => {
github = SingleInstanceGithubCredentialsProvider.create({
host: 'github.com',
apps: [
{
appId: 1,
privateKey: 'privateKey',
webhookSecret: '123',
clientId: 'CLIENT_ID',
clientSecret: 'CLIENT_SECRET',
allowedInstallationOwners: ['backstage'],
},
],
});
octokit.apps.listInstallations.mockResolvedValue({
headers: {
etag: '123',
},
data: [
{
id: 1,
repository_selection: 'all',
account: {
login: 'backstage',
},
},
],
} as RestEndpointMethodTypes['apps']['listInstallations']['response']);
const { token, headers } = await github.getCredentials({
url: 'https://github.com/RoadiehHQ',
});
expect(headers).toEqual(undefined);
expect(token).toEqual(undefined);
});
it('should not fail to issue tokens for an organization when the app is installed for a single repo', async () => {
octokit.apps.listInstallations.mockResolvedValue({
headers: {
@@ -96,9 +96,7 @@ class GithubAppManager {
const { installationId, suspended } = await this.getInstallationData(owner);
if (this.allowedInstallationOwners) {
if (!this.allowedInstallationOwners?.includes(owner)) {
throw new Error(
`The GitHub application for ${owner} is not included in the allowed installation list (${installationId}).`,
);
return { accessToken: '' }; // An empty token allows anonymous access to public repos
}
}
if (suspended) {