diff --git a/client/cmd/login.go b/client/cmd/login.go index c1fe39d2f..13b4b335c 100644 --- a/client/cmd/login.go +++ b/client/cmd/login.go @@ -3,10 +3,11 @@ package cmd import ( "context" "fmt" + "time" + "github.com/skratchdot/open-golang/open" "google.golang.org/grpc/codes" gstatus "google.golang.org/grpc/status" - "time" "github.com/netbirdio/netbird/util" @@ -38,7 +39,7 @@ var loginCmd = &cobra.Command{ return err } - config, err := internal.GetConfig(internal.ConfigInput{ + config, err := internal.UpdateOrCreateConfig(internal.ConfigInput{ ManagementURL: managementURL, AdminURL: adminURL, ConfigPath: configPath, @@ -152,7 +153,7 @@ func foregroundLogin(ctx context.Context, cmd *cobra.Command, config *internal.C } func foregroundGetTokenInfo(ctx context.Context, cmd *cobra.Command, config *internal.Config) (*internal.TokenInfo, error) { - providerConfig, err := internal.GetDeviceAuthorizationFlowInfo(ctx, config) + providerConfig, err := internal.GetDeviceAuthorizationFlowInfo(ctx, config.PrivateKey, config.ManagementURL) if err != nil { s, ok := gstatus.FromError(err) if ok && s.Code() == codes.NotFound { diff --git a/client/cmd/ssh.go b/client/cmd/ssh.go index 9775fda24..d0f506ff8 100644 --- a/client/cmd/ssh.go +++ b/client/cmd/ssh.go @@ -4,15 +4,17 @@ import ( "context" "errors" "fmt" - "github.com/netbirdio/netbird/client/internal" - nbssh "github.com/netbirdio/netbird/client/ssh" - "github.com/netbirdio/netbird/util" - log "github.com/sirupsen/logrus" - "github.com/spf13/cobra" "os" "os/signal" "strings" "syscall" + + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + + "github.com/netbirdio/netbird/client/internal" + nbssh "github.com/netbirdio/netbird/client/ssh" + "github.com/netbirdio/netbird/util" ) var ( @@ -57,7 +59,7 @@ var sshCmd = &cobra.Command{ ctx := internal.CtxInitState(cmd.Context()) - config, err := internal.ReadConfig(internal.ConfigInput{ + config, err := internal.UpdateConfig(internal.ConfigInput{ ConfigPath: configPath, }) if err != nil { diff --git a/client/cmd/up.go b/client/cmd/up.go index 1f874c744..edf97b84f 100644 --- a/client/cmd/up.go +++ b/client/cmd/up.go @@ -3,17 +3,19 @@ package cmd import ( "context" "fmt" - "github.com/netbirdio/netbird/client/internal" - "github.com/netbirdio/netbird/client/proto" - nbStatus "github.com/netbirdio/netbird/client/status" - "github.com/netbirdio/netbird/util" + "net" + "net/netip" + "strings" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "google.golang.org/grpc/codes" gstatus "google.golang.org/grpc/status" - "net" - "net/netip" - "strings" + + "github.com/netbirdio/netbird/client/internal" + "github.com/netbirdio/netbird/client/proto" + nbStatus "github.com/netbirdio/netbird/client/status" + "github.com/netbirdio/netbird/util" ) const ( @@ -70,7 +72,7 @@ func runInForegroundMode(ctx context.Context, cmd *cobra.Command) error { return err } - config, err := internal.GetConfig(internal.ConfigInput{ + config, err := internal.UpdateOrCreateConfig(internal.ConfigInput{ ManagementURL: managementURL, AdminURL: adminURL, ConfigPath: configPath, diff --git a/client/internal/config.go b/client/internal/config.go index 92a008bb2..a3ff09979 100644 --- a/client/internal/config.go +++ b/client/internal/config.go @@ -1,19 +1,18 @@ package internal import ( - "context" "fmt" "net/url" "os" - "github.com/netbirdio/netbird/client/ssh" - "github.com/netbirdio/netbird/iface" - mgm "github.com/netbirdio/netbird/management/client" - "github.com/netbirdio/netbird/util" log "github.com/sirupsen/logrus" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + + "github.com/netbirdio/netbird/client/ssh" + "github.com/netbirdio/netbird/iface" + "github.com/netbirdio/netbird/util" ) const ( @@ -74,6 +73,28 @@ type Config struct { CustomDNSAddress string } +// UpdateConfig update existing configuration according to input configuration and return with the configuration +func UpdateConfig(input ConfigInput) (*Config, error) { + if !configFileIsExists(input.ConfigPath) { + return nil, status.Errorf(codes.NotFound, "config file doesn't exist") + } + + return update(input) +} + +// UpdateOrCreateConfig reads existing config or generates a new one +func UpdateOrCreateConfig(input ConfigInput) (*Config, error) { + if !configFileIsExists(input.ConfigPath) { + log.Infof("generating new config %s", input.ConfigPath) + return createNewConfig(input) + } + + if isPreSharedKeyHidden(input.PreSharedKey) { + input.PreSharedKey = nil + } + return update(input) +} + // createNewConfig creates a new config generating a new Wireguard key and saving to file func createNewConfig(input ConfigInput) (*Config, error) { wgKey := generateKey() @@ -92,14 +113,14 @@ func createNewConfig(input ConfigInput) (*Config, error) { CustomDNSAddress: string(input.CustomDNSAddress), } - defaultManagementURL, err := ParseURL("Management URL", DefaultManagementURL) + defaultManagementURL, err := parseURL("Management URL", DefaultManagementURL) if err != nil { return nil, err } config.ManagementURL = defaultManagementURL if input.ManagementURL != "" { - URL, err := ParseURL("Management URL", input.ManagementURL) + URL, err := parseURL("Management URL", input.ManagementURL) if err != nil { return nil, err } @@ -110,14 +131,14 @@ func createNewConfig(input ConfigInput) (*Config, error) { config.PreSharedKey = *input.PreSharedKey } - defaultAdminURL, err := ParseURL("Admin URL", DefaultAdminURL) + defaultAdminURL, err := parseURL("Admin URL", DefaultAdminURL) if err != nil { return nil, err } config.AdminURL = defaultAdminURL if input.AdminURL != "" { - newURL, err := ParseURL("Admin Panel URL", input.AdminURL) + newURL, err := parseURL("Admin Panel URL", input.AdminURL) if err != nil { return nil, err } @@ -134,40 +155,8 @@ func createNewConfig(input ConfigInput) (*Config, error) { return config, nil } -// ParseURL parses and validates a service URL -func ParseURL(serviceName, serviceURL string) (*url.URL, error) { - parsedMgmtURL, err := url.ParseRequestURI(serviceURL) - if err != nil { - log.Errorf("failed parsing %s URL %s: [%s]", serviceName, serviceURL, err.Error()) - return nil, err - } - - if parsedMgmtURL.Scheme != "https" && parsedMgmtURL.Scheme != "http" { - return nil, fmt.Errorf( - "invalid %s URL provided %s. Supported format [http|https]://[host]:[port]", - serviceName, serviceURL) - } - - if parsedMgmtURL.Port() == "" { - switch parsedMgmtURL.Scheme { - case "https": - parsedMgmtURL.Host = parsedMgmtURL.Host + ":443" - case "http": - parsedMgmtURL.Host = parsedMgmtURL.Host + ":80" - default: - log.Infof("unable to determine a default port for schema %s in URL %s", parsedMgmtURL.Scheme, serviceURL) - } - } - - return parsedMgmtURL, err -} - -// ReadConfig reads existing configuration and update settings according to input configuration -func ReadConfig(input ConfigInput) (*Config, error) { +func update(input ConfigInput) (*Config, error) { config := &Config{} - if _, err := os.Stat(input.ConfigPath); os.IsNotExist(err) { - return nil, status.Errorf(codes.NotFound, "config file doesn't exist") - } if _, err := util.ReadJson(input.ConfigPath, config); err != nil { return nil, err @@ -178,7 +167,7 @@ func ReadConfig(input ConfigInput) (*Config, error) { if input.ManagementURL != "" && config.ManagementURL.String() != input.ManagementURL { log.Infof("new Management URL provided, updated to %s (old value %s)", input.ManagementURL, config.ManagementURL) - newURL, err := ParseURL("Management URL", input.ManagementURL) + newURL, err := parseURL("Management URL", input.ManagementURL) if err != nil { return nil, err } @@ -189,7 +178,7 @@ func ReadConfig(input ConfigInput) (*Config, error) { if input.AdminURL != "" && (config.AdminURL == nil || config.AdminURL.String() != input.AdminURL) { log.Infof("new Admin Panel URL provided, updated to %s (old value %s)", input.AdminURL, config.AdminURL) - newURL, err := ParseURL("Admin Panel URL", input.AdminURL) + newURL, err := parseURL("Admin Panel URL", input.AdminURL) if err != nil { return nil, err } @@ -237,17 +226,32 @@ func ReadConfig(input ConfigInput) (*Config, error) { return config, nil } -// GetConfig reads existing config or generates a new one -func GetConfig(input ConfigInput) (*Config, error) { - if _, err := os.Stat(input.ConfigPath); os.IsNotExist(err) { - log.Infof("generating new config %s", input.ConfigPath) - return createNewConfig(input) +// parseURL parses and validates a service URL +func parseURL(serviceName, serviceURL string) (*url.URL, error) { + parsedMgmtURL, err := url.ParseRequestURI(serviceURL) + if err != nil { + log.Errorf("failed parsing %s URL %s: [%s]", serviceName, serviceURL, err.Error()) + return nil, err } - if isPreSharedKeyHidden(input.PreSharedKey) { - input.PreSharedKey = nil + if parsedMgmtURL.Scheme != "https" && parsedMgmtURL.Scheme != "http" { + return nil, fmt.Errorf( + "invalid %s URL provided %s. Supported format [http|https]://[host]:[port]", + serviceName, serviceURL) } - return ReadConfig(input) + + if parsedMgmtURL.Port() == "" { + switch parsedMgmtURL.Scheme { + case "https": + parsedMgmtURL.Host = parsedMgmtURL.Host + ":443" + case "http": + parsedMgmtURL.Host = parsedMgmtURL.Host + ":80" + default: + log.Infof("unable to determine a default port for schema %s in URL %s", parsedMgmtURL.Scheme, serviceURL) + } + } + + return parsedMgmtURL, err } // generateKey generates a new Wireguard private key @@ -259,111 +263,6 @@ func generateKey() string { return key.String() } -// DeviceAuthorizationFlow represents Device Authorization Flow information -type DeviceAuthorizationFlow struct { - Provider string - ProviderConfig ProviderConfig -} - -// ProviderConfig has all attributes needed to initiate a device authorization flow -type ProviderConfig struct { - // ClientID An IDP application client id - ClientID string - // ClientSecret An IDP application client secret - ClientSecret string - // Domain An IDP API domain - // Deprecated. Use OIDCConfigEndpoint instead - Domain string - // Audience An Audience for to authorization validation - Audience string - // TokenEndpoint is the endpoint of an IDP manager where clients can obtain access token - TokenEndpoint string - // DeviceAuthEndpoint is the endpoint of an IDP manager where clients can obtain device authorization code - DeviceAuthEndpoint string -} - -func GetDeviceAuthorizationFlowInfo(ctx context.Context, config *Config) (DeviceAuthorizationFlow, error) { - // validate our peer's Wireguard PRIVATE key - myPrivateKey, err := wgtypes.ParseKey(config.PrivateKey) - if err != nil { - log.Errorf("failed parsing Wireguard key %s: [%s]", config.PrivateKey, err.Error()) - return DeviceAuthorizationFlow{}, err - } - - var mgmTlsEnabled bool - if config.ManagementURL.Scheme == "https" { - mgmTlsEnabled = true - } - - log.Debugf("connecting to Management Service %s", config.ManagementURL.String()) - mgmClient, err := mgm.NewClient(ctx, config.ManagementURL.Host, myPrivateKey, mgmTlsEnabled) - if err != nil { - log.Errorf("failed connecting to Management Service %s %v", config.ManagementURL.String(), err) - return DeviceAuthorizationFlow{}, err - } - log.Debugf("connected to the Management service %s", config.ManagementURL.String()) - defer func() { - err = mgmClient.Close() - if err != nil { - log.Warnf("failed to close the Management service client %v", err) - } - }() - - serverKey, err := mgmClient.GetServerPublicKey() - if err != nil { - log.Errorf("failed while getting Management Service public key: %v", err) - return DeviceAuthorizationFlow{}, err - } - - protoDeviceAuthorizationFlow, err := mgmClient.GetDeviceAuthorizationFlow(*serverKey) - if err != nil { - if s, ok := status.FromError(err); ok && s.Code() == codes.NotFound { - log.Warnf("server couldn't find device flow, contact admin: %v", err) - return DeviceAuthorizationFlow{}, err - } else { - log.Errorf("failed to retrieve device flow: %v", err) - return DeviceAuthorizationFlow{}, err - } - } - - deviceAuthorizationFlow := DeviceAuthorizationFlow{ - Provider: protoDeviceAuthorizationFlow.Provider.String(), - - ProviderConfig: ProviderConfig{ - Audience: protoDeviceAuthorizationFlow.GetProviderConfig().GetAudience(), - ClientID: protoDeviceAuthorizationFlow.GetProviderConfig().GetClientID(), - ClientSecret: protoDeviceAuthorizationFlow.GetProviderConfig().GetClientSecret(), - Domain: protoDeviceAuthorizationFlow.GetProviderConfig().Domain, - TokenEndpoint: protoDeviceAuthorizationFlow.GetProviderConfig().GetTokenEndpoint(), - DeviceAuthEndpoint: protoDeviceAuthorizationFlow.GetProviderConfig().GetDeviceAuthEndpoint(), - }, - } - - err = isProviderConfigValid(deviceAuthorizationFlow.ProviderConfig) - if err != nil { - return DeviceAuthorizationFlow{}, err - } - - return deviceAuthorizationFlow, nil -} - -func isProviderConfigValid(config ProviderConfig) error { - errorMSGFormat := "invalid provider configuration received from management: %s value is empty. Contact your NetBird administrator" - if config.Audience == "" { - return fmt.Errorf(errorMSGFormat, "Audience") - } - if config.ClientID == "" { - return fmt.Errorf(errorMSGFormat, "Client ID") - } - if config.TokenEndpoint == "" { - return fmt.Errorf(errorMSGFormat, "Token Endpoint") - } - if config.DeviceAuthEndpoint == "" { - return fmt.Errorf(errorMSGFormat, "Device Auth Endpoint") - } - return nil -} - // don't overwrite pre-shared key if we receive asterisks from UI func isPreSharedKeyHidden(preSharedKey *string) bool { if preSharedKey != nil && *preSharedKey == "**********" { @@ -371,3 +270,8 @@ func isPreSharedKeyHidden(preSharedKey *string) bool { } return false } + +func configFileIsExists(path string) bool { + _, err := os.Stat(path) + return !os.IsNotExist(err) +} diff --git a/client/internal/config_test.go b/client/internal/config_test.go index 5c2be50a0..d4c207aed 100644 --- a/client/internal/config_test.go +++ b/client/internal/config_test.go @@ -12,7 +12,7 @@ import ( func TestGetConfig(t *testing.T) { // case 1: new default config has to be generated - config, err := GetConfig(ConfigInput{ + config, err := UpdateOrCreateConfig(ConfigInput{ ConfigPath: filepath.Join(t.TempDir(), "config.json"), }) @@ -32,7 +32,7 @@ func TestGetConfig(t *testing.T) { preSharedKey := "preSharedKey" // case 2: new config has to be generated - config, err = GetConfig(ConfigInput{ + config, err = UpdateOrCreateConfig(ConfigInput{ ManagementURL: managementURL, AdminURL: adminURL, ConfigPath: path, @@ -50,7 +50,7 @@ func TestGetConfig(t *testing.T) { } // case 3: existing config -> fetch it - config, err = GetConfig(ConfigInput{ + config, err = UpdateOrCreateConfig(ConfigInput{ ManagementURL: managementURL, AdminURL: adminURL, ConfigPath: path, @@ -65,7 +65,7 @@ func TestGetConfig(t *testing.T) { // case 4: existing config, but new managementURL has been provided -> update config newManagementURL := "https://test.newManagement.url:33071" - config, err = GetConfig(ConfigInput{ + config, err = UpdateOrCreateConfig(ConfigInput{ ManagementURL: newManagementURL, AdminURL: adminURL, ConfigPath: path, @@ -101,13 +101,13 @@ func TestHiddenPreSharedKey(t *testing.T) { // generate default cfg cfgFile := filepath.Join(t.TempDir(), "config.json") - _, _ = GetConfig(ConfigInput{ + _, _ = UpdateOrCreateConfig(ConfigInput{ ConfigPath: cfgFile, }) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cfg, err := GetConfig(ConfigInput{ + cfg, err := UpdateOrCreateConfig(ConfigInput{ ConfigPath: cfgFile, PreSharedKey: tt.preSharedKey, }) diff --git a/client/internal/connect.go b/client/internal/connect.go index bbc430d3f..5bd3c9f62 100644 --- a/client/internal/connect.go +++ b/client/internal/connect.go @@ -6,21 +6,19 @@ import ( "strings" "time" + "github.com/cenkalti/backoff/v4" + log "github.com/sirupsen/logrus" + "golang.zx2c4.com/wireguard/wgctrl/wgtypes" + "google.golang.org/grpc/codes" + gstatus "google.golang.org/grpc/status" + "github.com/netbirdio/netbird/client/ssh" nbStatus "github.com/netbirdio/netbird/client/status" - "github.com/netbirdio/netbird/client/system" - "github.com/netbirdio/netbird/iface" mgm "github.com/netbirdio/netbird/management/client" mgmProto "github.com/netbirdio/netbird/management/proto" signal "github.com/netbirdio/netbird/signal/client" - log "github.com/sirupsen/logrus" - - "github.com/cenkalti/backoff/v4" - "golang.zx2c4.com/wireguard/wgctrl/wgtypes" - "google.golang.org/grpc/codes" - gstatus "google.golang.org/grpc/status" ) // RunClient with main logic. @@ -251,7 +249,7 @@ func loginToManagement(ctx context.Context, client mgm.Client, pubSSHKey []byte) // The check is performed only for the NetBird's managed version. func UpdateOldManagementPort(ctx context.Context, config *Config, configPath string) (*Config, error) { - defaultManagementURL, err := ParseURL("Management URL", DefaultManagementURL) + defaultManagementURL, err := parseURL("Management URL", DefaultManagementURL) if err != nil { return nil, err } @@ -273,7 +271,7 @@ func UpdateOldManagementPort(ctx context.Context, config *Config, configPath str if mgmTlsEnabled && config.ManagementURL.Port() == fmt.Sprintf("%d", ManagementLegacyPort) { - newURL, err := ParseURL("Management URL", fmt.Sprintf("%s://%s:%d", + newURL, err := parseURL("Management URL", fmt.Sprintf("%s://%s:%d", config.ManagementURL.Scheme, config.ManagementURL.Hostname(), 443)) if err != nil { return nil, err @@ -307,7 +305,7 @@ func UpdateOldManagementPort(ctx context.Context, config *Config, configPath str } // everything is alright => update the config - newConfig, err := ReadConfig(ConfigInput{ + newConfig, err := UpdateConfig(ConfigInput{ ManagementURL: newURL.String(), ConfigPath: configPath, }) diff --git a/client/internal/device_auth.go b/client/internal/device_auth.go new file mode 100644 index 000000000..2fab17188 --- /dev/null +++ b/client/internal/device_auth.go @@ -0,0 +1,119 @@ +package internal + +import ( + "context" + "fmt" + "net/url" + + log "github.com/sirupsen/logrus" + "golang.zx2c4.com/wireguard/wgctrl/wgtypes" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + mgm "github.com/netbirdio/netbird/management/client" +) + +// DeviceAuthorizationFlow represents Device Authorization Flow information +type DeviceAuthorizationFlow struct { + Provider string + ProviderConfig ProviderConfig +} + +// ProviderConfig has all attributes needed to initiate a device authorization flow +type ProviderConfig struct { + // ClientID An IDP application client id + ClientID string + // ClientSecret An IDP application client secret + ClientSecret string + // Domain An IDP API domain + // Deprecated. Use OIDCConfigEndpoint instead + Domain string + // Audience An Audience for to authorization validation + Audience string + // TokenEndpoint is the endpoint of an IDP manager where clients can obtain access token + TokenEndpoint string + // DeviceAuthEndpoint is the endpoint of an IDP manager where clients can obtain device authorization code + DeviceAuthEndpoint string +} + +// GetDeviceAuthorizationFlowInfo initialize a DeviceAuthorizationFlow instance and return with it +func GetDeviceAuthorizationFlowInfo(ctx context.Context, privateKey string, mgmURL *url.URL) (DeviceAuthorizationFlow, error) { + // validate our peer's Wireguard PRIVATE key + myPrivateKey, err := wgtypes.ParseKey(privateKey) + if err != nil { + log.Errorf("failed parsing Wireguard key %s: [%s]", privateKey, err.Error()) + return DeviceAuthorizationFlow{}, err + } + + var mgmTLSEnabled bool + if mgmURL.Scheme == "https" { + mgmTLSEnabled = true + } + + log.Debugf("connecting to Management Service %s", mgmURL.String()) + mgmClient, err := mgm.NewClient(ctx, mgmURL.Host, myPrivateKey, mgmTLSEnabled) + if err != nil { + log.Errorf("failed connecting to Management Service %s %v", mgmURL.String(), err) + return DeviceAuthorizationFlow{}, err + } + log.Debugf("connected to the Management service %s", mgmURL.String()) + defer func() { + err = mgmClient.Close() + if err != nil { + log.Warnf("failed to close the Management service client %v", err) + } + }() + + serverKey, err := mgmClient.GetServerPublicKey() + if err != nil { + log.Errorf("failed while getting Management Service public key: %v", err) + return DeviceAuthorizationFlow{}, err + } + + protoDeviceAuthorizationFlow, err := mgmClient.GetDeviceAuthorizationFlow(*serverKey) + if err != nil { + if s, ok := status.FromError(err); ok && s.Code() == codes.NotFound { + log.Warnf("server couldn't find device flow, contact admin: %v", err) + return DeviceAuthorizationFlow{}, err + } + log.Errorf("failed to retrieve device flow: %v", err) + return DeviceAuthorizationFlow{}, err + } + + deviceAuthorizationFlow := DeviceAuthorizationFlow{ + Provider: protoDeviceAuthorizationFlow.Provider.String(), + + ProviderConfig: ProviderConfig{ + Audience: protoDeviceAuthorizationFlow.GetProviderConfig().GetAudience(), + ClientID: protoDeviceAuthorizationFlow.GetProviderConfig().GetClientID(), + ClientSecret: protoDeviceAuthorizationFlow.GetProviderConfig().GetClientSecret(), + Domain: protoDeviceAuthorizationFlow.GetProviderConfig().Domain, + TokenEndpoint: protoDeviceAuthorizationFlow.GetProviderConfig().GetTokenEndpoint(), + DeviceAuthEndpoint: protoDeviceAuthorizationFlow.GetProviderConfig().GetDeviceAuthEndpoint(), + }, + } + + err = isProviderConfigValid(deviceAuthorizationFlow.ProviderConfig) + if err != nil { + return DeviceAuthorizationFlow{}, err + } + + return deviceAuthorizationFlow, nil +} + +func isProviderConfigValid(config ProviderConfig) error { + errorMSGFormat := "invalid provider configuration received from management: %s value is empty. Contact your NetBird administrator" + if config.Audience == "" { + return fmt.Errorf(errorMSGFormat, "Audience") + } + if config.ClientID == "" { + return fmt.Errorf(errorMSGFormat, "Client ID") + } + if config.TokenEndpoint == "" { + return fmt.Errorf(errorMSGFormat, "Token Endpoint") + } + if config.DeviceAuthEndpoint == "" { + return fmt.Errorf(errorMSGFormat, "Device Auth Endpoint") + } + return nil +} diff --git a/client/server/server.go b/client/server/server.go index 4b2efeb78..0297f7e6b 100644 --- a/client/server/server.go +++ b/client/server/server.go @@ -3,20 +3,19 @@ package server import ( "context" "fmt" - nbStatus "github.com/netbirdio/netbird/client/status" - "github.com/netbirdio/netbird/client/system" - "google.golang.org/protobuf/types/known/timestamppb" "sync" "time" + log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" - - log "github.com/sirupsen/logrus" + "google.golang.org/protobuf/types/known/timestamppb" "github.com/netbirdio/netbird/client/internal" "github.com/netbirdio/netbird/client/proto" + nbStatus "github.com/netbirdio/netbird/client/status" + "github.com/netbirdio/netbird/client/system" ) // Server for service control. @@ -77,9 +76,9 @@ func (s *Server) Start() error { // if configuration exists, we just start connections. if is new config we skip and set status NeedsLogin // on failure we return error to retry - config, err := internal.ReadConfig(s.latestConfigInput) + config, err := internal.UpdateConfig(s.latestConfigInput) if errorStatus, ok := gstatus.FromError(err); ok && errorStatus.Code() == codes.NotFound { - config, err = internal.GetConfig(s.latestConfigInput) + config, err = internal.UpdateOrCreateConfig(s.latestConfigInput) if err != nil { log.Warnf("unable to create configuration file: %v", err) return err @@ -182,7 +181,7 @@ func (s *Server) Login(callerCtx context.Context, msg *proto.LoginRequest) (*pro inputConfig.PreSharedKey = &msg.PreSharedKey - config, err := internal.GetConfig(inputConfig) + config, err := internal.UpdateOrCreateConfig(inputConfig) if err != nil { return nil, err } @@ -205,7 +204,7 @@ func (s *Server) Login(callerCtx context.Context, msg *proto.LoginRequest) (*pro state.Set(internal.StatusConnecting) if msg.SetupKey == "" { - providerConfig, err := internal.GetDeviceAuthorizationFlowInfo(ctx, config) + providerConfig, err := internal.GetDeviceAuthorizationFlowInfo(ctx, config.PrivateKey, config.ManagementURL) if err != nil { state.Set(internal.StatusLoginFailed) s, ok := gstatus.FromError(err)