@@ -20,14 +20,18 @@ import (
2020 "fmt"
2121 "net/http"
2222 "net/url"
23+ "strconv"
2324 "strings"
2425
2526 "firebase.google.com/go/internal"
27+ "google.golang.org/api/iterator"
2628)
2729
2830const (
2931 providerConfigEndpoint = "https://identitytoolkit.googleapis.com/v2beta1"
3032
33+ maxConfigs = 100
34+
3135 idpEntityIDKey = "idpConfig.idpEntityId"
3236 ssoURLKey = "idpConfig.ssoUrl"
3337 signRequestKey = "idpConfig.signRequest"
@@ -337,6 +341,65 @@ func (config *SAMLProviderConfigToUpdate) buildRequest() (nestedMap, error) {
337341 return config .params , nil
338342}
339343
344+ // SAMLProviderConfigIterator is an iterator over SAML provider configurations.
345+ type SAMLProviderConfigIterator struct {
346+ client * providerConfigClient
347+ ctx context.Context
348+ nextFunc func () error
349+ pageInfo * iterator.PageInfo
350+ configs []* SAMLProviderConfig
351+ }
352+
353+ // PageInfo supports pagination.
354+ func (it * SAMLProviderConfigIterator ) PageInfo () * iterator.PageInfo {
355+ return it .pageInfo
356+ }
357+
358+ // Next returns the next SAMLProviderConfig. The error value of [iterator.Done] is
359+ // returned if there are no more results. Once Next returns [iterator.Done], all
360+ // subsequent calls will return [iterator.Done].
361+ func (it * SAMLProviderConfigIterator ) Next () (* SAMLProviderConfig , error ) {
362+ if err := it .nextFunc (); err != nil {
363+ return nil , err
364+ }
365+
366+ config := it .configs [0 ]
367+ it .configs = it .configs [1 :]
368+ return config , nil
369+ }
370+
371+ func (it * SAMLProviderConfigIterator ) fetch (pageSize int , pageToken string ) (string , error ) {
372+ params := map [string ]string {
373+ "pageSize" : strconv .Itoa (pageSize ),
374+ }
375+ if pageToken != "" {
376+ params ["pageToken" ] = pageToken
377+ }
378+
379+ req := & internal.Request {
380+ Method : http .MethodGet ,
381+ URL : "/inboundSamlConfigs" ,
382+ Opts : []internal.HTTPOption {
383+ internal .WithQueryParams (params ),
384+ },
385+ }
386+
387+ var result struct {
388+ Configs []samlProviderConfigDAO `json:"inboundSamlConfigs"`
389+ NextPageToken string `json:"nextPageToken"`
390+ }
391+ if _ , err := it .client .makeRequest (it .ctx , req , & result ); err != nil {
392+ return "" , err
393+ }
394+
395+ for _ , config := range result .Configs {
396+ it .configs = append (it .configs , config .toSAMLProviderConfig ())
397+ }
398+
399+ it .pageInfo .Token = result .NextPageToken
400+ return result .NextPageToken , nil
401+ }
402+
340403type providerConfigClient struct {
341404 endpoint string
342405 projectID string
@@ -453,6 +516,24 @@ func (c *providerConfigClient) DeleteSAMLProviderConfig(ctx context.Context, id
453516 return err
454517}
455518
519+ // SAMLProviderConfigs returns an iterator over SAML provider configurations.
520+ //
521+ // If nextPageToken is empty, the iterator will start at the beginning. Otherwise,
522+ // iterator starts after the token.
523+ func (c * providerConfigClient ) SAMLProviderConfigs (ctx context.Context , nextPageToken string ) * SAMLProviderConfigIterator {
524+ it := & SAMLProviderConfigIterator {
525+ ctx : ctx ,
526+ client : c ,
527+ }
528+ it .pageInfo , it .nextFunc = iterator .NewPageInfo (
529+ it .fetch ,
530+ func () int { return len (it .configs ) },
531+ func () interface {} { b := it .configs ; it .configs = nil ; return b })
532+ it .pageInfo .MaxSize = maxConfigs
533+ it .pageInfo .Token = nextPageToken
534+ return it
535+ }
536+
456537func (c * providerConfigClient ) makeRequest (ctx context.Context , req * internal.Request , v interface {}) (* internal.Response , error ) {
457538 if c .projectID == "" {
458539 return nil , errors .New ("project id not available" )
0 commit comments