@@ -73,7 +73,7 @@ func (df DataFetcher) FetchData(ctx context.Context, organization string) (*Gith
7373 steps = append (steps , & proto.Step {
7474 Title : "Get SSO Configuration" ,
7575 Description : "Fetches the SAML SSO configuration for the organization to verify identity provider enforcement" ,
76- Remarks : policy_manager .Pointer ("More information: https://docs.github.com/en/rest/orgs/orgs?apiVersion=2022-11-28#get-an- organization" ),
76+ Remarks : policy_manager .Pointer ("More information: https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-saml-single-sign-on-for-your- organization/about-identity-and-access-management-with-saml-single-sign-on " ),
7777 })
7878
7979 steps = append (steps , & proto.Step {
@@ -127,20 +127,14 @@ func (df DataFetcher) FetchData(ctx context.Context, organization string) (*Gith
127127
128128 ssoData , err := df .fetchSSO (ctx , organization )
129129 if err != nil {
130- df .logger .Warn ( "Could not fetch SSO configuration; marking SSO as disabled " , "org" , organization , "error" , err )
131- ssoData = & OrgSSO { Enabled : false }
130+ df .logger .Error ( "Error getting SSO configuration" , "org" , organization , "error" , err )
131+ return nil , nil , err
132132 }
133133
134- var ipAllowList []IPAllowListEntry
135- if org .Plan != nil && org .Plan .Name != nil && * org .Plan .Name == "enterprise" {
136- ipAllowList , err = df .fetchIPAllowList (ctx , organization )
137- if err != nil {
138- df .logger .Warn ("Could not fetch IP allow-list; treating as empty" , "org" , organization , "error" , err )
139- ipAllowList = []IPAllowListEntry {}
140- }
141- } else {
142- df .logger .Info ("Skipping IP allow-list fetch: requires GitHub Enterprise Cloud" , "org" , organization , "plan" , org .Plan )
143- ipAllowList = []IPAllowListEntry {}
134+ ipAllowList , err := df .fetchIPAllowList (ctx , organization )
135+ if err != nil {
136+ df .logger .Error ("Error getting IP allow-list" , "org" , organization , "error" , err )
137+ return nil , nil , err
144138 }
145139
146140 return & GithubData {
@@ -162,7 +156,7 @@ func (df DataFetcher) fetchSSO(ctx context.Context, organization string) (*OrgSS
162156 SAMLIdentityProvider * samlIdentityProvider `json:"saml_identity_provider"`
163157 }
164158
165- url := fmt .Sprintf ("https://api.github.com/ orgs/%s/sso" , organization )
159+ url := fmt .Sprintf ("orgs/%s/sso" , organization )
166160 req , err := df .client .NewRequest (http .MethodGet , url , nil )
167161 if err != nil {
168162 return nil , fmt .Errorf ("building SSO request: %w" , err )
@@ -190,7 +184,8 @@ func (df DataFetcher) fetchSSO(ctx context.Context, organization string) (*OrgSS
190184
191185func (df DataFetcher ) fetchIPAllowList (ctx context.Context , organization string ) ([]IPAllowListEntry , error ) {
192186 type graphqlRequest struct {
193- Query string `json:"query"`
187+ Query string `json:"query"`
188+ Variables map [string ]interface {} `json:"variables"`
194189 }
195190 type ipAllowListEntryNode struct {
196191 AllowListValue string `json:"allowListValue"`
@@ -201,7 +196,11 @@ func (df DataFetcher) fetchIPAllowList(ctx context.Context, organization string)
201196 Node ipAllowListEntryNode `json:"node"`
202197 }
203198 type ipAllowListConnection struct {
204- Edges []ipAllowListEdge `json:"edges"`
199+ Edges []ipAllowListEdge `json:"edges"`
200+ PageInfo struct {
201+ HasNextPage bool `json:"hasNextPage"`
202+ EndCursor * string `json:"endCursor"`
203+ } `json:"pageInfo"`
205204 }
206205 type orgNode struct {
207206 IPAllowListEntries ipAllowListConnection `json:"ipAllowListEntries"`
@@ -216,32 +215,66 @@ func (df DataFetcher) fetchIPAllowList(ctx context.Context, organization string)
216215 } `json:"errors"`
217216 }
218217
219- gqlQuery := graphqlRequest {
220- Query : fmt .Sprintf (`{ organization(login: "%s") { ipAllowListEntries(first: 100) { edges { node { allowListValue isActive name } } } } }` , organization ),
221- }
218+ query := `query($login: String!, $after: String) {
219+ organization(login: $login) {
220+ ipAllowListEntries(first: 100, after: $after) {
221+ edges {
222+ node {
223+ allowListValue
224+ isActive
225+ name
226+ }
227+ }
228+ pageInfo {
229+ hasNextPage
230+ endCursor
231+ }
232+ }
233+ }
234+ }`
222235
223- req , err := df .client .NewRequest (http .MethodPost , "https://api.github.com/graphql" , gqlQuery )
224- if err != nil {
225- return nil , fmt .Errorf ("building IP allow-list GraphQL request: %w" , err )
226- }
236+ var entries []IPAllowListEntry
237+ var after * string
238+ for {
239+ gqlQuery := graphqlRequest {
240+ Query : query ,
241+ Variables : map [string ]interface {}{
242+ "login" : organization ,
243+ "after" : after ,
244+ },
245+ }
227246
228- var gqlResp graphqlResponse
229- _ , err = df .client .Do (ctx , req , & gqlResp )
230- if err != nil {
231- return nil , fmt .Errorf ("executing IP allow-list GraphQL query: %w" , err )
232- }
247+ req , err := df .client .NewRequest (http .MethodPost , "graphql" , gqlQuery )
248+ if err != nil {
249+ return nil , fmt .Errorf ("building IP allow-list GraphQL request: %w" , err )
250+ }
233251
234- if len (gqlResp .Errors ) > 0 {
235- return nil , fmt .Errorf ("GraphQL error: %s" , gqlResp .Errors [0 ].Message )
236- }
252+ var gqlResp graphqlResponse
253+ _ , err = df .client .Do (ctx , req , & gqlResp )
254+ if err != nil {
255+ return nil , fmt .Errorf ("executing IP allow-list GraphQL query: %w" , err )
256+ }
257+
258+ if len (gqlResp .Errors ) > 0 {
259+ return nil , fmt .Errorf ("GraphQL error: %s" , gqlResp .Errors [0 ].Message )
260+ }
261+
262+ connection := gqlResp .Data .Organization .IPAllowListEntries
263+ for _ , edge := range connection .Edges {
264+ entries = append (entries , IPAllowListEntry {
265+ AllowListValue : edge .Node .AllowListValue ,
266+ IsActive : edge .Node .IsActive ,
267+ Name : edge .Node .Name ,
268+ })
269+ }
237270
238- entries := make ([] IPAllowListEntry , 0 , len ( gqlResp . Data . Organization . IPAllowListEntries . Edges ))
239- for _ , edge := range gqlResp . Data . Organization . IPAllowListEntries . Edges {
240- entries = append ( entries , IPAllowListEntry {
241- AllowListValue : edge . Node . AllowListValue ,
242- IsActive : edge . Node . IsActive ,
243- Name : edge . Node . Name ,
244- })
271+ if ! connection . PageInfo . HasNextPage {
272+ break
273+ }
274+ if connection . PageInfo . EndCursor == nil {
275+ return nil , fmt . Errorf ( "GraphQL response indicated another IP allow-list page without an end cursor" )
276+ }
277+ after = connection . PageInfo . EndCursor
245278 }
246279 return entries , nil
247280}
0 commit comments