mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-21 14:19:08 +02:00
(WIP) Migrate active_profile
This commit is contained in:
@@ -2,6 +2,7 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -69,6 +70,7 @@ func TestLogout_OtherProfileStaysGatedWhenProfilesDisabled(t *testing.T) {
|
||||
_, err := profilemanager.UpdateOrCreateConfig(profilemanager.ConfigInput{
|
||||
ConfigPath: filepath.Join(profilemanager.DefaultConfigPathDir, other+".json"),
|
||||
ManagementURL: unreachableManagementURL,
|
||||
Owner: testProfileOwner(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -86,28 +88,18 @@ func TestLogout_OtherProfileStaysGatedWhenProfilesDisabled(t *testing.T) {
|
||||
|
||||
// A legacy profile ID is a display name, so two users can hold the same ID in
|
||||
// their own profile directories. Matching on the ID alone would let one user's
|
||||
// logout pass the gate against the other user's active profile, so the username
|
||||
// is part of the comparison.
|
||||
// logout pass the gate against the other user's active profile, so the config
|
||||
// file, not the ID, decides which profile is the active one.
|
||||
func TestLogout_ForeignUserProfileStaysGatedWhenProfilesDisabled(t *testing.T) {
|
||||
s, _, _, username, _ := setupServerWithProfile(t)
|
||||
s.rootCtx = internal.CtxInitState(context.Background())
|
||||
|
||||
// A legacy-style profile whose ID is its filename stem, and an active state
|
||||
// claiming that same ID for a different user.
|
||||
shared := "shared-legacy-name"
|
||||
_, err := profilemanager.UpdateOrCreateConfig(profilemanager.ConfigInput{
|
||||
ConfigPath: filepath.Join(profilemanager.DefaultConfigPathDir, shared+".json"),
|
||||
ManagementURL: unreachableManagementURL,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, s.profileManager.SetActiveProfileState(&profilemanager.ActiveProfileState{
|
||||
ID: profilemanager.ID(shared),
|
||||
Username: "someone-else",
|
||||
}))
|
||||
plantNamesakeProfiles(t, s, shared)
|
||||
|
||||
s.profilesDisabled = true
|
||||
|
||||
_, err = s.Logout(userCtx(), &proto.LogoutRequest{
|
||||
_, err := s.Logout(userCtx(), &proto.LogoutRequest{
|
||||
ProfileName: &shared,
|
||||
Username: &username,
|
||||
})
|
||||
@@ -117,6 +109,35 @@ func TestLogout_ForeignUserProfileStaysGatedWhenProfilesDisabled(t *testing.T) {
|
||||
"another user's profile must not pass the gate on an ID match alone: %v", err)
|
||||
}
|
||||
|
||||
// plantNamesakeProfiles creates two profiles that share one legacy ID: the
|
||||
// caller's own, and another user's in that user's legacy profile directory,
|
||||
// which is the one made active. Only the caller's copy carries an owner, so
|
||||
// that is the one a handle resolves to, while the active profile stays the
|
||||
// other file.
|
||||
func plantNamesakeProfiles(t *testing.T, s *Server, id string) {
|
||||
t.Helper()
|
||||
|
||||
foreignDir := filepath.Join(profilemanager.DefaultConfigPathDir, "someone-else")
|
||||
require.NoError(t, os.MkdirAll(foreignDir, 0700))
|
||||
_, err := profilemanager.UpdateOrCreateConfig(profilemanager.ConfigInput{
|
||||
ConfigPath: filepath.Join(foreignDir, id+".json"),
|
||||
ManagementURL: unreachableManagementURL,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = profilemanager.UpdateOrCreateConfig(profilemanager.ConfigInput{
|
||||
ConfigPath: filepath.Join(profilemanager.DefaultConfigPathDir, id+".json"),
|
||||
ManagementURL: unreachableManagementURL,
|
||||
Owner: testProfileOwner(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, s.profileManager.SetActiveProfileState(&profilemanager.ActiveProfileState{
|
||||
ID: profilemanager.ID(id),
|
||||
Username: "someone-else",
|
||||
}))
|
||||
}
|
||||
|
||||
// Deregistering a namesake profile must not go out with the running config.
|
||||
// logoutFromProfile reuses the connected client's config when the target is the
|
||||
// active profile, and on an ID-only match a shared legacy ID made it reuse it
|
||||
@@ -135,15 +156,7 @@ func TestLogout_ForeignUserProfileDoesNotUseTheRunningConfig(t *testing.T) {
|
||||
s.connectClient = newDummyConnectClient(context.Background())
|
||||
|
||||
shared := "shared-legacy-name"
|
||||
_, err = profilemanager.UpdateOrCreateConfig(profilemanager.ConfigInput{
|
||||
ConfigPath: filepath.Join(profilemanager.DefaultConfigPathDir, shared+".json"),
|
||||
ManagementURL: unreachableManagementURL,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, s.profileManager.SetActiveProfileState(&profilemanager.ActiveProfileState{
|
||||
ID: profilemanager.ID(shared),
|
||||
Username: "someone-else",
|
||||
}))
|
||||
plantNamesakeProfiles(t, s, shared)
|
||||
|
||||
// Bounded so the deregistration the fixed path attempts fails on the dial
|
||||
// rather than sitting in gRPC backoff for the whole test timeout.
|
||||
@@ -165,18 +178,21 @@ func TestLogout_ForeignUserProfileDoesNotUseTheRunningConfig(t *testing.T) {
|
||||
// guardedConfigMu, which the logout path does not hold, so a login that landed
|
||||
// meanwhile must keep its connection.
|
||||
func TestCleanupAfterProfileLogout_FollowsTheCurrentActiveProfile(t *testing.T) {
|
||||
s, _, activeProfile, username, _ := setupServerWithProfile(t)
|
||||
s, _, activeProfile, _, cfgPath := setupServerWithProfile(t)
|
||||
s.rootCtx = internal.CtxInitState(context.Background())
|
||||
|
||||
state := internal.CtxGetState(s.rootCtx)
|
||||
|
||||
s.cleanupAfterProfileLogout("some-other-profile", username)
|
||||
s.cleanupAfterProfileLogout(&profilemanager.Profile{ID: "some-other-profile"})
|
||||
status, err := state.Status()
|
||||
require.NoError(t, err)
|
||||
require.NotEqual(t, internal.StatusNeedsLogin, status,
|
||||
"logging out of a profile that is not active must not ask for a new login")
|
||||
|
||||
s.cleanupAfterProfileLogout(profilemanager.ID(activeProfile), username)
|
||||
s.cleanupAfterProfileLogout(&profilemanager.Profile{
|
||||
ID: profilemanager.ID(activeProfile),
|
||||
Path: cfgPath,
|
||||
})
|
||||
status, err = state.Status()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, internal.StatusNeedsLogin, status,
|
||||
|
||||
Reference in New Issue
Block a user