1+ import { AppConfig } from "./appConfig" ;
2+ import { CopilotAddResponse , GitHubId , IInstalledClient , OrgInvite } from "./gitHubTypes" ;
3+ import { IGitHubInvitations } from "./githubInvitations" ;
4+ import { OrgConfig } from "./orgConfig" ;
5+
6+ interface IGitHubSyncer {
7+ getCurrentOrgName ( ) : string ;
8+ initializeResponse ( orgName : string ) : ReturnTypeOfSyncOrg ;
9+ listCurrentInvitations ( ) : Promise < OrgInvite [ ] > ;
10+ getAllExistingTeams ( ) : Promise < Set < string > > ;
11+ getOrganizationConfiguration ( ) : Promise < OrgConfig > ;
12+ syncSecurityManagerTeams ( currentInvites : OrgInvite [ ] , securityManagerTeams : string [ ] , setOfExistingTeams : Set < string > , shortLink : string , displayNameToSourceMap : Map < string , string > ) : Promise < SuccessSync | FailedSecSync > ;
13+ handleOrganizationConfigurationErrors ( orgConfigResponse : any , response : ReturnTypeOfSyncOrg ) : ReturnTypeOfSyncOrg ;
14+ createMissingTeams ( orgName : string , teamsToCreate : string [ ] , shortLink : string ) : Promise < void > ;
15+ syncOrganizationMembersByTeam ( teamName : string , sourceTeamMap : Map < string , string > ) : Promise < void > ;
16+ syncOrganizationMembersGroup ( membersGroupName : string , orgConfig : OrgConfig , currentInvites : OrgInvite [ ] ) : Promise < GitHubId [ ] > ;
17+ syncGitHubTeams ( gitHubTeams : string [ ] , currentInvites : OrgInvite [ ] , orgConfig : OrgConfig ) : Promise < void > ;
18+ syncOrganizationOwners ( ownerGroupName : string , response : ReturnTypeOfSyncOrg ) : Promise < ReturnTypeOfSyncOrg > ;
19+ addCopilotSubscriptions ( orgConfig : OrgConfig , response : ReturnTypeOfSyncOrg ) : Promise < ReturnTypeOfSyncOrg > ;
20+ }
21+
22+ class GitHubSyncer implements IGitHubSyncer {
23+ constructor (
24+ private installedGitHubClient : IInstalledClient ,
25+ private invitationsClient : IGitHubInvitations ,
26+ private appConfig : AppConfig
27+ ) { }
28+
29+ getCurrentOrgName ( ) : string {
30+ return this . installedGitHubClient . GetCurrentOrgName ( ) ;
31+ }
32+
33+ initializeResponse ( orgName : string ) : ReturnTypeOfSyncOrg {
34+ return {
35+ message : `Initializing sync for organization: ${ orgName } ` ,
36+ status : "completed" ,
37+ orgName : orgName ,
38+ syncedSecurityManagerTeams : [ ] ,
39+ orgOwnersGroup : "" ,
40+ ignoredTeams : [ ] ,
41+ copilotTeams : [ ]
42+ } ;
43+ }
44+
45+ async listCurrentInvitations ( ) : Promise < OrgInvite [ ] > {
46+ const invites = await this . invitationsClient . ListInvites ( ) ;
47+ if ( ! invites . successful ) {
48+ throw new Error ( "Invalid response from ListInvites" ) ;
49+ }
50+ return invites . data ;
51+ }
52+
53+ async getAllExistingTeams ( ) : Promise < Set < string > > {
54+ const teams = await this . installedGitHubClient . GetAllTeams ( ) ;
55+ if ( ! teams . successful ) {
56+ throw new Error ( "Invalid response from GetAllTeams" ) ;
57+ }
58+ return new Set ( teams . data . map ( team => team . Name ) ) ;
59+ }
60+
61+ async getOrganizationConfiguration ( ) : Promise < OrgConfig > {
62+ const orgConfigResponse = await this . installedGitHubClient . GetConfigurationForInstallation ( ) ;
63+ if ( ! orgConfigResponse . successful ) {
64+ throw new Error ( "Invalid response from GetOrgConfig" ) ;
65+ }
66+ return orgConfigResponse . data ;
67+ }
68+
69+ async syncSecurityManagerTeams ( currentInvites : OrgInvite [ ] , securityManagerTeams : string [ ] , setOfExistingTeams : Set < string > , shortLink : string , displayNameToSourceMap : Map < string , string > ) : Promise < SuccessSync | FailedSecSync > {
70+ const orgName = this . getCurrentOrgName ( ) ;
71+
72+ for ( const t of securityManagerTeams ) {
73+ if ( ! setOfExistingTeams . has ( t . toUpperCase ( ) ) ) {
74+ // Log(`Creating team '${orgName}/${t}'`)
75+ await this . installedGitHubClient . CreateTeam ( t , teamDescription ( shortLink , t ) ) ;
76+ setOfExistingTeams . add ( t ) ;
77+ }
78+
79+ // Log(`Syncing Security Managers for ${installedGitHubClient.GetCurrentOrgName()}: ${t}`)
80+ const orgMembers = await this . syncOrganizationMembersByTeam ( t , this . appConfig , displayNameToSourceMap ) ;
81+
82+ if ( orgMembers . Succeeded == false ) {
83+ return {
84+ Success : false ,
85+ Message : "Failed to sync org members"
86+ } ;
87+ }
88+
89+
90+ await SynchronizeGitHubTeam ( installedGitHubClient , t , appConfig , currentInvites , displayNameToSourceMap ) ;
91+
92+ Log ( `Add Security Manager Team for ${ installedGitHubClient . GetCurrentOrgName ( ) } : ${ t } ` )
93+ const addResult = await installedGitHubClient . AddSecurityManagerTeam ( t ) ;
94+ if ( addResult ) {
95+ Log ( `Added Security Manager Team for ${ installedGitHubClient . GetCurrentOrgName ( ) } : ${ t } ` )
96+ }
97+ }
98+
99+ return {
100+ Success : true ,
101+ SyncedSecurityManagerTeams : securityManagerTeams
102+ }
103+ }
104+
105+ handleOrganizationConfigurationErrors ( orgConfigResponse : any , response : ReturnTypeOfSyncOrg ) : ReturnTypeOfSyncOrg {
106+ throw new Error ( "Method not implemented." ) ;
107+ }
108+
109+ createMissingTeams ( orgName : string , teamsToCreate : string [ ] , shortLink : string ) : Promise < void > {
110+ throw new Error ( "Method not implemented." ) ;
111+ }
112+
113+ syncOrganizationMembersByTeam ( teamName : string , sourceTeamMap : Map < string , string > ) : Promise < void > {
114+ throw new Error ( "Method not implemented." ) ;
115+ }
116+
117+ syncOrganizationMembersGroup ( membersGroupName : string , orgConfig : OrgConfig , currentInvites : OrgInvite [ ] ) : Promise < GitHubId [ ] > {
118+ throw new Error ( "Method not implemented." ) ;
119+ }
120+
121+ syncGitHubTeams ( gitHubTeams : string [ ] , currentInvites : OrgInvite [ ] , orgConfig : OrgConfig ) : Promise < void > {
122+ throw new Error ( "Method not implemented." ) ;
123+ }
124+
125+ syncOrganizationOwners ( ownerGroupName : string , response : ReturnTypeOfSyncOrg ) : Promise < ReturnTypeOfSyncOrg > {
126+ throw new Error ( "Method not implemented." ) ;
127+ }
128+
129+ addCopilotSubscriptions ( orgConfig : OrgConfig , response : ReturnTypeOfSyncOrg ) : Promise < ReturnTypeOfSyncOrg > {
130+ throw new Error ( "Method not implemented." ) ;
131+ }
132+ }
133+
134+ type ReturnTypeOfSyncOrg = {
135+ message ?: string ;
136+ status : "failed" | "completed" | "no_config" | "bad_config" ;
137+ orgName : string ;
138+ syncedSecurityManagerTeams : string [ ] ;
139+ orgOwnersGroup : string ;
140+ ignoredTeams : string [ ] ;
141+ copilotTeams : CopilotAddResponse [ ] ;
142+ }
143+
144+ type FailedSecSync = {
145+ Success : false ,
146+ Message : string
147+ }
148+
149+ type SuccessSync = {
150+ Success : true ,
151+ SyncedSecurityManagerTeams : string [ ]
152+ }
153+
154+ export { IGitHubSyncer , ReturnTypeOfSyncOrg , FailedSecSync , SuccessSync } ;
0 commit comments