mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-19 15:01:29 +02:00
Clean up
This commit is contained in:
@@ -83,9 +83,7 @@ func NewProfileManager() *ProfileManager {
|
||||
}
|
||||
|
||||
// GetActiveProfile returns the active profile as recorded in the local
|
||||
// user state file. Only ID is populated; the display Name is not known
|
||||
// at this layer — callers that need it should query the daemon's
|
||||
// ListProfiles RPC.
|
||||
// user state file. Only ID is populated.
|
||||
func (pm *ProfileManager) GetActiveProfile() (*Profile, error) {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
@@ -95,9 +93,7 @@ func (pm *ProfileManager) GetActiveProfile() (*Profile, error) {
|
||||
}
|
||||
|
||||
// SwitchProfile records the given profile ID as active in the local user
|
||||
// state file. The CLI calls this after the daemon has resolved the user-
|
||||
// supplied handle to a concrete ID, so the value written here is always a
|
||||
// valid profile filename stem.
|
||||
// state file.
|
||||
func (pm *ProfileManager) SwitchProfile(id string) error {
|
||||
if id != defaultProfileName && !IsValidProfileFilenameStem(id) {
|
||||
return fmt.Errorf("invalid profile ID: %q", id)
|
||||
|
||||
@@ -46,9 +46,8 @@ const (
|
||||
AmbiguityKindName
|
||||
)
|
||||
|
||||
// profileMeta is the minimal slice of a profile JSON we need for the list.
|
||||
// Using a private struct here avoids running the full Config.apply()
|
||||
// pipeline (which can rewrite the file) on every list operation.
|
||||
// profileMeta is the minimal slice of a profile JSON we need, so we avoid
|
||||
// reading all fields
|
||||
type profileMeta struct {
|
||||
Name string
|
||||
}
|
||||
@@ -87,11 +86,11 @@ func init() {
|
||||
}
|
||||
|
||||
type ActiveProfileState struct {
|
||||
// ID is the on-disk filename stem of the active profile. The JSON
|
||||
// tag stays as "name" for backwards compatibility with active state
|
||||
// files written before the ID-keyed layout. Legacy values were
|
||||
// profile names, which were also the legacy filename stems, so they
|
||||
// still resolve to the correct file on disk.
|
||||
// ID is the on-disk filename stem of the active profile. The JSON tag stays
|
||||
// as "name" for backwards compatibility with active state files written
|
||||
// before the ID-based config files. Legacy values were profile names, which
|
||||
// were also the legacy filename stems, so they still resolve to the correct
|
||||
// file on disk.
|
||||
ID string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
@@ -373,8 +372,6 @@ func (s *ServiceManager) RemoveProfile(id, username string) error {
|
||||
return fmt.Errorf("failed to remove profile config: %w", err)
|
||||
}
|
||||
|
||||
// Best-effort state file cleanup. Missing is fine — state files are
|
||||
// only created on demand.
|
||||
stateFile := filepath.Join(filepath.Dir(target.Path), id+".state.json")
|
||||
if err := os.Remove(stateFile); err != nil && !os.IsNotExist(err) {
|
||||
log.Warnf("failed to remove profile state file %s: %v", stateFile, err)
|
||||
@@ -436,8 +433,8 @@ func (s *ServiceManager) getConfigDir(username string) (string, error) {
|
||||
// by ID for a stable display order.
|
||||
//
|
||||
// Each Profile is fully populated: ID is the filename stem, Name comes
|
||||
// from the JSON's "name" field (falling back to the ID when absent), and
|
||||
// Path is built from a basename read off disk (path-traversal safe).
|
||||
// from the JSON's "name" field (falling back to the filename stem when absent)
|
||||
// and Path is built from a basename read off disk.
|
||||
func (s *ServiceManager) loadAllProfiles(username string) ([]Profile, error) {
|
||||
activeID, activeIsDefault := s.activeProfileID()
|
||||
|
||||
@@ -545,15 +542,13 @@ func (s *ServiceManager) ResolveProfile(handle, username string) (*Profile, erro
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Exact ID match wins outright — covers the default profile and any
|
||||
// legacy profile whose ID is its name.
|
||||
for i := range profiles {
|
||||
if profiles[i].ID == handle {
|
||||
return &profiles[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
// ID prefix match. Skip the default profile so a `select d` does not
|
||||
// ID prefix match. Skip the default profile so `select d` does not
|
||||
// accidentally pick it via prefix.
|
||||
var prefixMatches []Profile
|
||||
for i := range profiles {
|
||||
@@ -575,7 +570,6 @@ func (s *ServiceManager) ResolveProfile(handle, username string) (*Profile, erro
|
||||
}
|
||||
}
|
||||
|
||||
// Exact name match.
|
||||
var nameMatches []Profile
|
||||
for i := range profiles {
|
||||
if profiles[i].Name == handle {
|
||||
|
||||
@@ -4427,7 +4427,7 @@ func (x *AddProfileRequest) GetProfileName() string {
|
||||
type AddProfileResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// id is the generated on-disk ID of the new profile. CLI clients
|
||||
// display a truncated form; UI clients can ignore it.
|
||||
// display a truncated form, UI clients can ignore it.
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -4659,12 +4659,10 @@ func (x *ListProfilesResponse) GetProfiles() []*Profile {
|
||||
}
|
||||
|
||||
type Profile struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
IsActive bool `protobuf:"varint,2,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"`
|
||||
// id is the on-disk filename stem of the profile. Always set by the
|
||||
// server; older clients that ignore it continue to work via name.
|
||||
Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
IsActive bool `protobuf:"varint,2,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"`
|
||||
Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -4757,13 +4755,10 @@ func (*GetActiveProfileRequest) Descriptor() ([]byte, []int) {
|
||||
}
|
||||
|
||||
type GetActiveProfileResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// profileName carries the display name for backwards compatibility
|
||||
// with UI clients. New callers should prefer id, which is unique.
|
||||
ProfileName string `protobuf:"bytes,1,opt,name=profileName,proto3" json:"profileName,omitempty"`
|
||||
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
|
||||
// id is the on-disk filename stem of the active profile.
|
||||
Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ProfileName string `protobuf:"bytes,1,opt,name=profileName,proto3" json:"profileName,omitempty"`
|
||||
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
|
||||
Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
@@ -698,7 +698,7 @@ message AddProfileRequest {
|
||||
|
||||
message AddProfileResponse {
|
||||
// id is the generated on-disk ID of the new profile. CLI clients
|
||||
// display a truncated form; UI clients can ignore it.
|
||||
// display a truncated form, UI clients can ignore it.
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
@@ -726,19 +726,14 @@ message ListProfilesResponse {
|
||||
message Profile {
|
||||
string name = 1;
|
||||
bool is_active = 2;
|
||||
// id is the on-disk filename stem of the profile. Always set by the
|
||||
// server; older clients that ignore it continue to work via name.
|
||||
string id = 3;
|
||||
}
|
||||
|
||||
message GetActiveProfileRequest {}
|
||||
|
||||
message GetActiveProfileResponse {
|
||||
// profileName carries the display name for backwards compatibility
|
||||
// with UI clients. New callers should prefer id, which is unique.
|
||||
string profileName = 1;
|
||||
string username = 2;
|
||||
// id is the on-disk filename stem of the active profile.
|
||||
string id = 3;
|
||||
}
|
||||
|
||||
|
||||
@@ -1011,8 +1011,6 @@ func (s *Server) canRemoveProfile(id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateProfileOperation runs the common preconditions for add/remove/
|
||||
// logout flows. `id` is the resolved profile ID (never user input).
|
||||
func (s *Server) validateProfileOperation(id string, allowActiveProfile bool) error {
|
||||
if s.checkProfilesDisabled() {
|
||||
return gstatus.Errorf(codes.Unavailable, errProfilesDisabled)
|
||||
@@ -1031,8 +1029,6 @@ func (s *Server) validateProfileOperation(id string, allowActiveProfile bool) er
|
||||
return nil
|
||||
}
|
||||
|
||||
// logoutFromProfile logs out from a specific (already-resolved) profile
|
||||
// by loading its config and sending a logout request.
|
||||
func (s *Server) logoutFromProfile(ctx context.Context, profile *profilemanager.Profile) error {
|
||||
activeProf, err := s.profileManager.GetActiveProfileState()
|
||||
if err == nil && activeProf.ID == profile.ID && s.connectClient != nil {
|
||||
@@ -1639,7 +1635,7 @@ func (s *Server) ListProfiles(ctx context.Context, msg *proto.ListProfilesReques
|
||||
|
||||
// GetActiveProfile returns the active profile in the daemon. The
|
||||
// ProfileName field carries the display name for backwards compatibility
|
||||
// with UI clients; new callers should prefer Id.
|
||||
// with UI clients, new callers should prefer Id.
|
||||
func (s *Server) GetActiveProfile(ctx context.Context, msg *proto.GetActiveProfileRequest) (*proto.GetActiveProfileResponse, error) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
Reference in New Issue
Block a user