@@ -193,6 +193,7 @@ type ContextImpl struct {
193
193
authQueryHandlers map [string ]func (query * rest_model.AuthQueryDetail , response MfaCodeResponse ) error
194
194
195
195
events.EventEmmiter
196
+ authAttemptLock sync.Mutex
196
197
lastSuccessfulApiSessionRefresh time.Time
197
198
routerProxy func (addr string ) * transport.ProxyConfiguration
198
199
@@ -664,41 +665,50 @@ func (context *ContextImpl) refreshSessions() {
664
665
}
665
666
666
667
func (context * ContextImpl ) RefreshServices () error {
667
- return context .refreshServices (true )
668
+ return context .refreshServices (true , false )
668
669
}
669
670
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
+ }
673
676
}
674
677
675
678
var checkService bool
676
679
var lastServiceUpdate * strfmt.DateTime
677
680
var err error
678
681
679
682
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
689
691
} 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
+ }
692
698
}
693
699
}
694
700
}
695
701
}
696
702
697
- if checkService || forceCheck {
703
+ if checkService || forceRefresh {
698
704
log .Debug ("refreshing services" )
699
705
700
706
services , err := context .CtrlClt .GetServices ()
701
707
if err != nil {
708
+ if refreshAfterAuth { // in authenticate mutex, can't re-auth
709
+ return err
710
+ }
711
+
702
712
target := & service.ListServicesUnauthorized {}
703
713
if errors .As (err , & target ) {
704
714
log .Info ("attempting to re-authenticate" )
@@ -831,7 +841,7 @@ func (context *ContextImpl) runRefreshes() {
831
841
832
842
case <- svcRefreshTick .C :
833
843
log .Debug ("refreshing services" )
834
- if err := context .refreshServices (false ); err != nil {
844
+ if err := context .refreshServices (false , false ); err != nil {
835
845
log .WithError (err ).Error ("failed to load service updates" )
836
846
}
837
847
@@ -939,6 +949,9 @@ func (context *ContextImpl) Reauthenticate() error {
939
949
}
940
950
941
951
func (context * ContextImpl ) Authenticate () error {
952
+ context .authAttemptLock .Lock ()
953
+ defer context .authAttemptLock .Unlock ()
954
+
942
955
if context .CtrlClt .GetCurrentApiSession () != nil {
943
956
if time .Since (context .lastSuccessfulApiSessionRefresh ) < 5 * time .Second {
944
957
return nil
@@ -1013,7 +1026,7 @@ func (context *ContextImpl) onFullAuth(apiSession apis.ApiSession) error {
1013
1026
context .Emit (EventAuthenticationStateFull , apiSession )
1014
1027
1015
1028
// get services
1016
- if err := context .RefreshServices ( ); err != nil {
1029
+ if err := context .refreshServices ( true , true ); err != nil {
1017
1030
doOnceErr = err
1018
1031
}
1019
1032
@@ -1668,7 +1681,7 @@ func (context *ContextImpl) createSession(service *rest_model.ServiceDetail, ses
1668
1681
1669
1682
var createSessionNotFound = & rest_session.CreateSessionNotFound {}
1670
1683
if errors .As (err , & createSessionNotFound ) {
1671
- if refreshErr := context .refreshServices (false ); refreshErr != nil {
1684
+ if refreshErr := context .refreshServices (false , false ); refreshErr != nil {
1672
1685
logger .WithError (refreshErr ).Info ("failed to refresh services after create session returned 404 (likely for service)" )
1673
1686
}
1674
1687
}
0 commit comments