@@ -113,7 +113,7 @@ func LoginWithSession(f *factory.Factory, org string, session *oauth.Session) er
113113}
114114
115115func (c * LoginCmd ) Run (kongCtx * kong.Context , globals cli.GlobalFlags ) error {
116- f , err := factory .New (factory .WithDebug (globals .EnableDebug ()))
116+ f , err := factory .New (factory .WithDebug (globals .EnableDebug ()), factory . WithoutAPIClients () )
117117 if err != nil {
118118 return err
119119 }
@@ -178,23 +178,23 @@ func (c *LoginCmd) Run(kongCtx *kong.Context, globals cli.GlobalFlags) error {
178178 return fmt .Errorf ("token exchange failed: %w" , err )
179179 }
180180
181- org , err := resolveOrganizationFromToken (ctx , f .Config .RESTAPIEndpoint (), tokenResp .AccessToken )
181+ orgs , err := resolveOrganizationsFromToken (ctx , f .Config .RESTAPIEndpoint (), tokenResp .AccessToken )
182182 if err != nil {
183183 return err
184184 }
185185
186- session := tokenResp .Session (cfg .Host , time .Now ())
187- if err := LoginWithSession (f , org . Slug , session ); err != nil {
186+ session := tokenResp .Session (cfg .Host , cfg . ClientID , time .Now ())
187+ if err := storeSessionForOrganizations (f , orgs , session ); err != nil {
188188 return err
189189 }
190190
191- fmt .Printf ("\n ✅ Successfully authenticated with organization %q\n " , org .Slug )
191+ fmt .Printf ("\n ✅ Successfully authenticated with organization %q\n " , orgs [ 0 ] .Slug )
192192 fmt .Printf (" Scopes: %s\n " , tokenResp .Scope )
193193
194194 return nil
195195}
196196
197- func resolveOrganizationFromToken (ctx context.Context , baseURL , token string ) (* buildkite.Organization , error ) {
197+ func resolveOrganizationsFromToken (ctx context.Context , baseURL , token string ) ([] buildkite.Organization , error ) {
198198 client , err := buildkite .NewOpts (
199199 buildkite .WithBaseURL (baseURL ),
200200 buildkite .WithTokenAuth (token ),
@@ -203,13 +203,64 @@ func resolveOrganizationFromToken(ctx context.Context, baseURL, token string) (*
203203 return nil , fmt .Errorf ("failed to create API client: %w" , err )
204204 }
205205
206- orgs , _ , err := client .Organizations .List (ctx , nil )
207- if err != nil {
208- return nil , fmt .Errorf ("failed to list organizations: %w" , err )
206+ var allOrgs []buildkite.Organization
207+ page := 1
208+ for {
209+ orgs , resp , err := client .Organizations .List (ctx , & buildkite.OrganizationListOptions {
210+ ListOptions : buildkite.ListOptions {Page : page },
211+ })
212+ if err != nil {
213+ return nil , fmt .Errorf ("failed to list organizations: %w" , err )
214+ }
215+ allOrgs = append (allOrgs , orgs ... )
216+ if resp == nil || resp .NextPage == 0 {
217+ break
218+ }
219+ page = resp .NextPage
209220 }
210- if len (orgs ) == 0 {
221+
222+ if len (allOrgs ) == 0 {
211223 return nil , fmt .Errorf ("no organizations found for this token" )
212224 }
213225
226+ return allOrgs , nil
227+ }
228+
229+ func resolveOrganizationFromToken (ctx context.Context , baseURL , token string ) (* buildkite.Organization , error ) {
230+ orgs , err := resolveOrganizationsFromToken (ctx , baseURL , token )
231+ if err != nil {
232+ return nil , err
233+ }
234+
214235 return & orgs [0 ], nil
215236}
237+
238+ func storeSessionForOrganizations (f * factory.Factory , orgs []buildkite.Organization , session * oauth.Session ) error {
239+ if len (orgs ) == 0 {
240+ return errors .New ("no organizations found for this token" )
241+ }
242+ if err := LoginWithSession (f , orgs [0 ].Slug , session ); err != nil {
243+ return err
244+ }
245+
246+ kr := keyring .New ()
247+ seen := map [string ]struct {}{orgs [0 ].Slug : {}}
248+ for _ , org := range orgs [1 :] {
249+ if org .Slug == "" {
250+ continue
251+ }
252+ if _ , exists := seen [org .Slug ]; exists {
253+ continue
254+ }
255+ seen [org .Slug ] = struct {}{}
256+
257+ if err := kr .SetSession (org .Slug , session ); err != nil {
258+ return fmt .Errorf ("failed to store token in keychain: %w" , err )
259+ }
260+ if err := f .Config .EnsureOrganization (org .Slug ); err != nil {
261+ return fmt .Errorf ("failed to register organization in config: %w" , err )
262+ }
263+ }
264+
265+ return nil
266+ }
0 commit comments