diff --git a/packages/app/lib/apps/auth-routes/AuthRoutes.js b/packages/app/lib/apps/auth-routes/AuthRoutes.js index db3b88a0..0ffd9602 100644 --- a/packages/app/lib/apps/auth-routes/AuthRoutes.js +++ b/packages/app/lib/apps/auth-routes/AuthRoutes.js @@ -49,7 +49,6 @@ function AuthRoutes(logger, router, securityContext) { const params = new URLSearchParams(); params.append('client_id', process.env.GITHUB_CLIENT_ID); params.append('state', state); - params.append('scope', 'public_repo,repo'); params.append('redirect_uri', appUrl('/wuffle/login/callback')); return res.redirect(`https://github.com/login/oauth/authorize?${params.toString()}`); diff --git a/packages/app/lib/apps/user-access/UserAccess.js b/packages/app/lib/apps/user-access/UserAccess.js index bf6e7a2c..c10be1e9 100644 --- a/packages/app/lib/apps/user-access/UserAccess.js +++ b/packages/app/lib/apps/user-access/UserAccess.js @@ -2,7 +2,7 @@ const { Cache } = require('../../util'); -// 10 minutes +// 30 minutes const TTL = 1000 * 60 * 10; @@ -35,6 +35,36 @@ function UserAccess(logger, githubClient, events) { return repository; } + async function fetchUserRepositories(token) { + + const github = await githubClient.getUserScoped(token); + + const installations = await github.paginate( + github.apps.listInstallationsForAuthenticatedUser.endpoint.merge({}), + res => res.data + ); + + const repositoriesByInstallation = await Promise.all(installations.map( + installation => github.paginate( + github.apps.listInstallationReposForAuthenticatedUser.endpoint.merge({ + installation_id: installation.id + }), + res => res.data + ) + )); + + return [].concat(...repositoriesByInstallation); + } + + function getUserVisibleRepositoryNames(token) { + + return cache.get(`user-repositories:${token}`, () => { + return fetchUserRepositories(token); + }).then(repositories => repositories.map(repo => { + return repo.full_name; + })); + } + /** * Show publicly accessible issues only. */ @@ -69,26 +99,24 @@ function UserAccess(logger, githubClient, events) { function createReadFilter(token) { - log.info({ token }, 'creating read filter'); + const t = Date.now(); - return githubClient.getUserScoped(token) - .then(github => { - return github.paginate( - github.repos.list.endpoint.merge({ - visibility: 'private' - }), - res => res.data - ); - }).then(repositories => { - const repositoryNames = repositories.map(fullName); + log.debug({ token }, 'creating read filter'); - log.debug({ - token, - repositories: repositoryNames - }, 'creating member filter'); + return getUserVisibleRepositoryNames(token).then(repositoryNames => { + + log.debug({ + token, + repositories: repositoryNames + }, 'creating member filter'); + + console.log(repositoryNames); + + return createMemberFilter(repositoryNames); + }).finally(() => { + log.info({ token, t: Date.now() - t }, 'created read filter'); + }); - return createMemberFilter(repositoryNames); - }); } function getReadFilter(token) {