1
1
import * as Sentry from "@sentry/node" ;
2
2
import { PrismaClient , Repo , RepoPermissionSyncJobStatus } from "@sourcebot/db" ;
3
3
import { createLogger } from "@sourcebot/logger" ;
4
- import { BitbucketConnectionConfig } from "@sourcebot/schemas/v3/bitbucket.type" ;
5
- import { GiteaConnectionConfig } from "@sourcebot/schemas/v3/gitea.type" ;
6
- import { GithubConnectionConfig } from "@sourcebot/schemas/v3/github.type" ;
7
- import { GitlabConnectionConfig } from "@sourcebot/schemas/v3/gitlab.type" ;
4
+ import { hasEntitlement } from "@sourcebot/shared" ;
8
5
import { Job , Queue , Worker } from 'bullmq' ;
9
6
import { Redis } from 'ioredis' ;
10
- import { env } from "../env.js" ;
11
- import { createOctokitFromConfig , getUserIdsWithReadAccessToRepo } from "../github.js" ;
12
- import { RepoWithConnections , Settings } from "../types.js" ;
13
7
import { PERMISSION_SYNC_SUPPORTED_CODE_HOST_TYPES } from "../constants.js" ;
14
- import { hasEntitlement } from "@sourcebot/shared" ;
8
+ import { env } from "../env.js" ;
9
+ import { createOctokitFromToken , getRepoCollaborators } from "../github.js" ;
10
+ import { Settings } from "../types.js" ;
11
+ import { getAuthCredentialsForRepo } from "../utils.js" ;
15
12
16
13
type RepoPermissionSyncJob = {
17
14
jobId : string ;
@@ -25,6 +22,7 @@ const logger = createLogger('repo-permission-syncer');
25
22
export class RepoPermissionSyncer {
26
23
private queue : Queue < RepoPermissionSyncJob > ;
27
24
private worker : Worker < RepoPermissionSyncJob > ;
25
+ private interval ?: NodeJS . Timeout ;
28
26
29
27
constructor (
30
28
private db : PrismaClient ,
@@ -49,7 +47,7 @@ export class RepoPermissionSyncer {
49
47
50
48
logger . debug ( 'Starting scheduler' ) ;
51
49
52
- return setInterval ( async ( ) => {
50
+ this . interval = setInterval ( async ( ) => {
53
51
// @todo : make this configurable
54
52
const thresholdDate = new Date ( Date . now ( ) - this . settings . experiment_repoDrivenPermissionSyncIntervalMs ) ;
55
53
@@ -104,6 +102,9 @@ export class RepoPermissionSyncer {
104
102
}
105
103
106
104
public dispose ( ) {
105
+ if ( this . interval ) {
106
+ clearInterval ( this . interval ) ;
107
+ }
107
108
this . worker . close ( ) ;
108
109
this . queue . close ( ) ;
109
110
}
@@ -157,15 +158,17 @@ export class RepoPermissionSyncer {
157
158
158
159
logger . info ( `Syncing permissions for repo ${ repo . displayName } ...` ) ;
159
160
160
- const connection = getFirstConnectionWithToken ( repo ) ;
161
- if ( ! connection ) {
162
- throw new Error ( `No connection with token found for repo ${ id } ` ) ;
161
+ const credentials = await getAuthCredentialsForRepo ( repo , this . db , logger ) ;
162
+ if ( ! credentials ) {
163
+ throw new Error ( `No credentials found for repo ${ id } ` ) ;
163
164
}
164
165
165
166
const userIds = await ( async ( ) => {
166
- if ( connection . connectionType === 'github' ) {
167
- const config = connection . config as unknown as GithubConnectionConfig ;
168
- const { octokit } = await createOctokitFromConfig ( config , repo . orgId , this . db ) ;
167
+ if ( repo . external_codeHostType === 'github' ) {
168
+ const { octokit } = await createOctokitFromToken ( {
169
+ token : credentials . token ,
170
+ url : credentials . hostUrl ,
171
+ } ) ;
169
172
170
173
// @note : this is a bit of a hack since the displayName _might_ not be set..
171
174
// however, this property was introduced many versions ago and _should_ be set
@@ -176,7 +179,8 @@ export class RepoPermissionSyncer {
176
179
177
180
const [ owner , repoName ] = repo . displayName . split ( '/' ) ;
178
181
179
- const githubUserIds = await getUserIdsWithReadAccessToRepo ( owner , repoName , octokit ) ;
182
+ const collaborators = await getRepoCollaborators ( owner , repoName , octokit ) ;
183
+ const githubUserIds = collaborators . map ( collaborator => collaborator . id . toString ( ) ) ;
180
184
181
185
const accounts = await this . db . account . findMany ( {
182
186
where : {
@@ -268,34 +272,3 @@ export class RepoPermissionSyncer {
268
272
}
269
273
}
270
274
}
271
-
272
- const getFirstConnectionWithToken = ( repo : RepoWithConnections ) => {
273
- for ( const { connection } of repo . connections ) {
274
- if ( connection . connectionType === 'github' ) {
275
- const config = connection . config as unknown as GithubConnectionConfig ;
276
- if ( config . token ) {
277
- return connection ;
278
- }
279
- }
280
- if ( connection . connectionType === 'gitlab' ) {
281
- const config = connection . config as unknown as GitlabConnectionConfig ;
282
- if ( config . token ) {
283
- return connection ;
284
- }
285
- }
286
- if ( connection . connectionType === 'gitea' ) {
287
- const config = connection . config as unknown as GiteaConnectionConfig ;
288
- if ( config . token ) {
289
- return connection ;
290
- }
291
- }
292
- if ( connection . connectionType === 'bitbucket' ) {
293
- const config = connection . config as unknown as BitbucketConnectionConfig ;
294
- if ( config . token ) {
295
- return connection ;
296
- }
297
- }
298
- }
299
-
300
- return undefined ;
301
- }
0 commit comments