@@ -193,6 +193,7 @@ type ContextImpl struct {
193193 authQueryHandlers map [string ]func (query * rest_model.AuthQueryDetail , response MfaCodeResponse ) error
194194
195195 events.EventEmmiter
196+ authAttemptLock sync.Mutex
196197 lastSuccessfulApiSessionRefresh time.Time
197198 routerProxy func (addr string ) * transport.ProxyConfiguration
198199
@@ -664,41 +665,50 @@ func (context *ContextImpl) refreshSessions() {
664665}
665666
666667func (context * ContextImpl ) RefreshServices () error {
667- return context .refreshServices (true )
668+ return context .refreshServices (true , false )
668669}
669670
670- func (context * ContextImpl ) refreshServices (forceCheck bool ) error {
671- if err := context .ensureApiSession (); err != nil {
672- return fmt .Errorf ("failed to refresh services: %v" , err )
671+ func (context * ContextImpl ) refreshServices (forceRefresh , refreshAfterAuth bool ) error {
672+ if ! refreshAfterAuth { // if in authenticate mutex, can't re-auth
673+ if err := context .ensureApiSession (); err != nil {
674+ return fmt .Errorf ("failed to refresh services: %v" , err )
675+ }
673676 }
674677
675678 var checkService bool
676679 var lastServiceUpdate * strfmt.DateTime
677680 var err error
678681
679682 log := pfxlog .Logger ()
680- log .Debug ("checking if service updates available" )
681- if checkService , lastServiceUpdate , err = context .CtrlClt .IsServiceListUpdateAvailable (); err != nil {
682- log .WithError (err ).Error ("failed to check if service list update is available" )
683- target := & current_api_session.ListServiceUpdatesUnauthorized {}
684- if errors .As (err , & target ) {
685- checkService = true
686- } else {
687- if err = context .Authenticate (); err != nil {
688- log .WithError (err ).Error ("unable to re-authenticate during session refresh" )
683+
684+ if ! forceRefresh {
685+ log .Debug ("checking if service updates available" )
686+ if checkService , lastServiceUpdate , err = context .CtrlClt .IsServiceListUpdateAvailable (); err != nil {
687+ log .WithError (err ).Error ("failed to check if service list update is available" )
688+ target := & current_api_session.ListServiceUpdatesUnauthorized {}
689+ if errors .As (err , & target ) {
690+ checkService = true
689691 } else {
690- if checkService , lastServiceUpdate , err = context .CtrlClt .IsServiceListUpdateAvailable (); err != nil {
691- checkService = true
692+ if err = context .Authenticate (); err != nil {
693+ log .WithError (err ).Error ("unable to re-authenticate during session refresh" )
694+ } else {
695+ if checkService , lastServiceUpdate , err = context .CtrlClt .IsServiceListUpdateAvailable (); err != nil {
696+ checkService = true
697+ }
692698 }
693699 }
694700 }
695701 }
696702
697- if checkService || forceCheck {
703+ if checkService || forceRefresh {
698704 log .Debug ("refreshing services" )
699705
700706 services , err := context .CtrlClt .GetServices ()
701707 if err != nil {
708+ if refreshAfterAuth { // in authenticate mutex, can't re-auth
709+ return err
710+ }
711+
702712 target := & service.ListServicesUnauthorized {}
703713 if errors .As (err , & target ) {
704714 log .Info ("attempting to re-authenticate" )
@@ -831,7 +841,7 @@ func (context *ContextImpl) runRefreshes() {
831841
832842 case <- svcRefreshTick .C :
833843 log .Debug ("refreshing services" )
834- if err := context .refreshServices (false ); err != nil {
844+ if err := context .refreshServices (false , false ); err != nil {
835845 log .WithError (err ).Error ("failed to load service updates" )
836846 }
837847
@@ -939,6 +949,9 @@ func (context *ContextImpl) Reauthenticate() error {
939949}
940950
941951func (context * ContextImpl ) Authenticate () error {
952+ context .authAttemptLock .Lock ()
953+ defer context .authAttemptLock .Unlock ()
954+
942955 if context .CtrlClt .GetCurrentApiSession () != nil {
943956 if time .Since (context .lastSuccessfulApiSessionRefresh ) < 5 * time .Second {
944957 return nil
@@ -1013,7 +1026,7 @@ func (context *ContextImpl) onFullAuth(apiSession apis.ApiSession) error {
10131026 context .Emit (EventAuthenticationStateFull , apiSession )
10141027
10151028 // get services
1016- if err := context .RefreshServices ( ); err != nil {
1029+ if err := context .refreshServices ( true , true ); err != nil {
10171030 doOnceErr = err
10181031 }
10191032
@@ -1668,7 +1681,7 @@ func (context *ContextImpl) createSession(service *rest_model.ServiceDetail, ses
16681681
16691682 var createSessionNotFound = & rest_session.CreateSessionNotFound {}
16701683 if errors .As (err , & createSessionNotFound ) {
1671- if refreshErr := context .refreshServices (false ); refreshErr != nil {
1684+ if refreshErr := context .refreshServices (false , false ); refreshErr != nil {
16721685 logger .WithError (refreshErr ).Info ("failed to refresh services after create session returned 404 (likely for service)" )
16731686 }
16741687 }
0 commit comments