mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-14 09:29:07 +02:00
[client] Judge the SSO account against the flow that produced the token
WaitSSOLogin snapshotted the flow on entry but re-read the info, hint and accountPrompted from the live s.oauthAuthFlow afterwards, in separate critical sections. WaitToken blocks for the whole browser leg, so a concurrent Login or RequestJWTAuth could replace the flow meanwhile and the mismatch check would compare this wait's token against another flow's account: either arming the prompt spuriously or letting a wrong-account token through against an unrelated profile's hint. Take all of it in the entry snapshot.
This commit is contained in:
@@ -13,7 +13,8 @@ import (
|
||||
)
|
||||
|
||||
type stubOAuthFlow struct {
|
||||
token auth.TokenInfo
|
||||
token auth.TokenInfo
|
||||
onWait func()
|
||||
}
|
||||
|
||||
func (f *stubOAuthFlow) RequestAuthInfo(context.Context) (auth.AuthFlowInfo, error) {
|
||||
@@ -21,6 +22,9 @@ func (f *stubOAuthFlow) RequestAuthInfo(context.Context) (auth.AuthFlowInfo, err
|
||||
}
|
||||
|
||||
func (f *stubOAuthFlow) WaitToken(context.Context, auth.AuthFlowInfo) (auth.TokenInfo, error) {
|
||||
if f.onWait != nil {
|
||||
f.onWait()
|
||||
}
|
||||
return f.token, nil
|
||||
}
|
||||
|
||||
@@ -119,6 +123,31 @@ func TestSwitchProfile_DropsAccountPromptAndPendingFlow(t *testing.T) {
|
||||
require.False(t, pending, "the previous profile's extend flow leaked across a profile switch")
|
||||
}
|
||||
|
||||
func TestWaitSSOLogin_JudgesTheFlowThatProducedTheToken(t *testing.T) {
|
||||
s := newSSOTestServer(t, "user@example.com", false, "user@example.com")
|
||||
attempts := 0
|
||||
s.loginAttemptFn = func(context.Context, string, string) (internal.StatusType, error) {
|
||||
attempts++
|
||||
return "", nil
|
||||
}
|
||||
|
||||
flow := s.oauthAuthFlow.flow.(*stubOAuthFlow)
|
||||
flow.onWait = func() {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
s.oauthAuthFlow.hint = "someone-else@example.com"
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
resp, err := s.WaitSSOLogin(ctx, &proto.WaitSSOLoginRequest{UserCode: "code"})
|
||||
require.NoError(t, err, "a flow replaced mid-wait must not decide this wait's verdict")
|
||||
require.NotNil(t, resp)
|
||||
require.Equal(t, 1, attempts)
|
||||
require.False(t, s.forceAccountPrompt, "the prompt was armed off another flow's hint")
|
||||
}
|
||||
|
||||
func newSSOTestServer(t *testing.T, hint string, accountPrompted bool, tokenEmail string) *Server {
|
||||
t.Helper()
|
||||
s := New(internal.CtxInitState(context.Background()), "console", "", false, false, false, false)
|
||||
|
||||
Reference in New Issue
Block a user