ipn/ipnlocal: account for ControlURL when merging profiles
We merge/dedupe profiles based on UserID and NodeID, however we were not accounting for ControlURLs. Updates #713 Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
parent
adc302f428
commit
82ad585b5b
|
@ -98,21 +98,25 @@ func (pm *profileManager) matchingProfiles(f func(*ipn.LoginProfile) bool) (out
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *profileManager) findProfilesByNodeID(nodeID tailcfg.StableNodeID) []*ipn.LoginProfile {
|
// findProfilesByNodeID returns all profiles that have the provided nodeID and
|
||||||
|
// belong to the same control server.
|
||||||
|
func (pm *profileManager) findProfilesByNodeID(controlURL string, nodeID tailcfg.StableNodeID) []*ipn.LoginProfile {
|
||||||
if nodeID.IsZero() {
|
if nodeID.IsZero() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return pm.matchingProfiles(func(p *ipn.LoginProfile) bool {
|
return pm.matchingProfiles(func(p *ipn.LoginProfile) bool {
|
||||||
return p.NodeID == nodeID
|
return p.NodeID == nodeID && p.ControlURL == controlURL
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *profileManager) findProfilesByUserID(userID tailcfg.UserID) []*ipn.LoginProfile {
|
// findProfilesByUserID returns all profiles that have the provided userID and
|
||||||
|
// belong to the same control server.
|
||||||
|
func (pm *profileManager) findProfilesByUserID(controlURL string, userID tailcfg.UserID) []*ipn.LoginProfile {
|
||||||
if userID.IsZero() {
|
if userID.IsZero() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return pm.matchingProfiles(func(p *ipn.LoginProfile) bool {
|
return pm.matchingProfiles(func(p *ipn.LoginProfile) bool {
|
||||||
return p.UserProfile.ID == userID
|
return p.UserProfile.ID == userID && p.ControlURL == controlURL
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,9 +201,9 @@ func (pm *profileManager) SetPrefs(prefsIn ipn.PrefsView) error {
|
||||||
if pm.isNewProfile {
|
if pm.isNewProfile {
|
||||||
pm.isNewProfile = false
|
pm.isNewProfile = false
|
||||||
// Check if we already have a profile for this user.
|
// Check if we already have a profile for this user.
|
||||||
existing := pm.findProfilesByUserID(newPersist.UserProfile.ID)
|
existing := pm.findProfilesByUserID(prefs.ControlURL(), newPersist.UserProfile.ID)
|
||||||
// Also check if we have a profile with the same NodeID.
|
// Also check if we have a profile with the same NodeID.
|
||||||
existing = append(existing, pm.findProfilesByNodeID(newPersist.NodeID)...)
|
existing = append(existing, pm.findProfilesByNodeID(prefs.ControlURL(), newPersist.NodeID)...)
|
||||||
if len(existing) == 0 {
|
if len(existing) == 0 {
|
||||||
cp.ID, cp.Key = newUnusedID(pm.knownProfiles)
|
cp.ID, cp.Key = newUnusedID(pm.knownProfiles)
|
||||||
} else {
|
} else {
|
||||||
|
@ -217,6 +221,7 @@ func (pm *profileManager) SetPrefs(prefsIn ipn.PrefsView) error {
|
||||||
} else {
|
} else {
|
||||||
cp.Name = up.LoginName
|
cp.Name = up.LoginName
|
||||||
}
|
}
|
||||||
|
cp.ControlURL = prefs.ControlURL()
|
||||||
cp.UserProfile = newPersist.UserProfile
|
cp.UserProfile = newPersist.UserProfile
|
||||||
cp.NodeID = newPersist.NodeID
|
cp.NodeID = newPersist.NodeID
|
||||||
pm.knownProfiles[cp.ID] = cp
|
pm.knownProfiles[cp.ID] = cp
|
||||||
|
|
|
@ -131,15 +131,22 @@ func TestProfileList(t *testing.T) {
|
||||||
if lp := pm.findProfileByName(carol.Name); lp != nil {
|
if lp := pm.findProfileByName(carol.Name); lp != nil {
|
||||||
t.Fatalf("found profile for user2 in user1's profile list")
|
t.Fatalf("found profile for user2 in user1's profile list")
|
||||||
}
|
}
|
||||||
if lp := pm.findProfilesByNodeID(carol.NodeID); lp != nil {
|
if lp := pm.findProfilesByNodeID(carol.ControlURL, carol.NodeID); lp != nil {
|
||||||
t.Fatalf("found profile for user2 in user1's profile list")
|
t.Fatalf("found profile for user2 in user1's profile list")
|
||||||
}
|
}
|
||||||
if lp := pm.findProfilesByUserID(carol.UserProfile.ID); lp != nil {
|
if lp := pm.findProfilesByUserID(carol.ControlURL, carol.UserProfile.ID); lp != nil {
|
||||||
t.Fatalf("found profile for user2 in user1's profile list")
|
t.Fatalf("found profile for user2 in user1's profile list")
|
||||||
}
|
}
|
||||||
|
|
||||||
pm.SetCurrentUserID("user2")
|
pm.SetCurrentUserID("user2")
|
||||||
checkProfiles(t, "carol")
|
checkProfiles(t, "carol")
|
||||||
|
if lp := pm.findProfilesByNodeID(carol.ControlURL, carol.NodeID); lp == nil {
|
||||||
|
t.Fatalf("did not find profile for user2 in user2's profile list")
|
||||||
|
}
|
||||||
|
if lp := pm.findProfilesByUserID(carol.ControlURL, carol.UserProfile.ID); lp == nil {
|
||||||
|
t.Fatalf("did not find profile for user2 in user2's profile list")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestProfileManagement tests creating, loading, and switching profiles.
|
// TestProfileManagement tests creating, loading, and switching profiles.
|
||||||
|
|
|
@ -741,4 +741,8 @@ type LoginProfile struct {
|
||||||
// It is only relevant on Windows where we have a multi-user system.
|
// It is only relevant on Windows where we have a multi-user system.
|
||||||
// It is assigned once at profile creation time and never changes.
|
// It is assigned once at profile creation time and never changes.
|
||||||
LocalUserID WindowsUserID
|
LocalUserID WindowsUserID
|
||||||
|
|
||||||
|
// ControlURL is the URL of the control server that this profile is logged
|
||||||
|
// into.
|
||||||
|
ControlURL string
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue