mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-07 08:44:07 +01:00
Client Login via device authorization flow (#309)
UI and CLI Clients are now able to use SSO login by default we will check if the management has configured or supports SSO providers daemon will handle fetching and waiting for an access token Oauth package was moved to internal to avoid one extra package at this stage Secrets were removed from OAuth CLI clients have less and better output 2 new status were introduced, NeedsLogin and FailedLogin for better messaging With NeedsLogin we no longer have endless login attempts
This commit is contained in:
parent
49cca57565
commit
e5c52efb4c
@ -17,7 +17,7 @@ var downCmd = &cobra.Command{
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
SetFlagsFromEnvVars()
|
||||
|
||||
err := util.InitLog(logLevel, logFile)
|
||||
err := util.InitLog(logLevel, "console")
|
||||
if err != nil {
|
||||
log.Errorf("failed initializing log %v", err)
|
||||
return err
|
||||
|
@ -3,10 +3,13 @@ package cmd
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/skratchdot/open-golang/open"
|
||||
"google.golang.org/grpc/codes"
|
||||
gstatus "google.golang.org/grpc/status"
|
||||
"time"
|
||||
|
||||
"github.com/netbirdio/netbird/util"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/netbirdio/netbird/client/internal"
|
||||
@ -19,10 +22,9 @@ var loginCmd = &cobra.Command{
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
SetFlagsFromEnvVars()
|
||||
|
||||
err := util.InitLog(logLevel, logFile)
|
||||
err := util.InitLog(logLevel, "console")
|
||||
if err != nil {
|
||||
log.Errorf("failed initializing log %v", err)
|
||||
return err
|
||||
return fmt.Errorf("failed initializing log %v", err)
|
||||
}
|
||||
|
||||
ctx := internal.CtxInitState(context.Background())
|
||||
@ -31,45 +33,162 @@ var loginCmd = &cobra.Command{
|
||||
if logFile == "console" {
|
||||
config, err := internal.GetConfig(managementURL, adminURL, configPath, preSharedKey)
|
||||
if err != nil {
|
||||
log.Errorf("get config file: %v", err)
|
||||
return err
|
||||
return fmt.Errorf("get config file: %v", err)
|
||||
}
|
||||
err = WithBackOff(func() error {
|
||||
return internal.Login(ctx, config, setupKey, jwtToken)
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("backoff cycle failed: %v", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if setupKey == "" {
|
||||
log.Error("setup key can't be empty")
|
||||
return fmt.Errorf("empty setup key")
|
||||
err = foregroundLogin(ctx, cmd, config, setupKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("foreground login failed: %v", err)
|
||||
}
|
||||
cmd.Println("Logging successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
conn, err := DialClientGRPCServer(ctx, daemonAddr)
|
||||
if err != nil {
|
||||
log.Errorf("failed to connect to service CLI interface %v", err)
|
||||
return err
|
||||
return fmt.Errorf("failed to connect to daemon error: %v\n"+
|
||||
"If the daemon is not running please run: "+
|
||||
"\nnetbird service install \nnetbird service start\n", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
request := proto.LoginRequest{
|
||||
client := proto.NewDaemonServiceClient(conn)
|
||||
|
||||
loginRequest := proto.LoginRequest{
|
||||
SetupKey: setupKey,
|
||||
PreSharedKey: preSharedKey,
|
||||
ManagementUrl: managementURL,
|
||||
}
|
||||
client := proto.NewDaemonServiceClient(conn)
|
||||
|
||||
var loginErr error
|
||||
|
||||
var loginResp *proto.LoginResponse
|
||||
|
||||
err = WithBackOff(func() error {
|
||||
if _, err := client.Login(ctx, &request); err != nil {
|
||||
log.Errorf("try login: %v", err)
|
||||
var backOffErr error
|
||||
loginResp, backOffErr = client.Login(ctx, &loginRequest)
|
||||
if s, ok := gstatus.FromError(backOffErr); ok && (s.Code() == codes.InvalidArgument ||
|
||||
s.Code() == codes.PermissionDenied ||
|
||||
s.Code() == codes.NotFound ||
|
||||
s.Code() == codes.Unimplemented) {
|
||||
loginErr = backOffErr
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
return backOffErr
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("backoff cycle failed: %v", err)
|
||||
return fmt.Errorf("login backoff cycle failed: %v", err)
|
||||
}
|
||||
return err
|
||||
|
||||
if loginErr != nil {
|
||||
return fmt.Errorf("login failed: %v", loginErr)
|
||||
}
|
||||
|
||||
if loginResp.NeedsSSOLogin {
|
||||
openURL(cmd, loginResp.VerificationURI, loginResp.VerificationURIComplete, loginResp.UserCode)
|
||||
|
||||
_, err = client.WaitSSOLogin(ctx, &proto.WaitSSOLoginRequest{UserCode: loginResp.UserCode})
|
||||
if err != nil {
|
||||
return fmt.Errorf("waiting sso login failed with: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
cmd.Println("Logging successfully")
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func foregroundLogin(ctx context.Context, cmd *cobra.Command, config *internal.Config, setupKey string) error {
|
||||
needsLogin := false
|
||||
|
||||
err := WithBackOff(func() error {
|
||||
err := internal.Login(ctx, config, "", "")
|
||||
if s, ok := gstatus.FromError(err); ok && (s.Code() == codes.InvalidArgument || s.Code() == codes.PermissionDenied) {
|
||||
needsLogin = true
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("backoff cycle failed: %v", err)
|
||||
}
|
||||
|
||||
jwtToken := ""
|
||||
if setupKey == "" && needsLogin {
|
||||
tokenInfo, err := foregroundGetTokenInfo(ctx, cmd, config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("interactive sso login failed: %v", err)
|
||||
}
|
||||
jwtToken = tokenInfo.AccessToken
|
||||
}
|
||||
|
||||
err = WithBackOff(func() error {
|
||||
err := internal.Login(ctx, config, setupKey, jwtToken)
|
||||
if s, ok := gstatus.FromError(err); ok && (s.Code() == codes.InvalidArgument || s.Code() == codes.PermissionDenied) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("backoff cycle failed: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func foregroundGetTokenInfo(ctx context.Context, cmd *cobra.Command, config *internal.Config) (*internal.TokenInfo, error) {
|
||||
providerConfig, err := internal.GetDeviceAuthorizationFlowInfo(ctx, config)
|
||||
if err != nil {
|
||||
s, ok := gstatus.FromError(err)
|
||||
if ok && s.Code() == codes.NotFound {
|
||||
return nil, fmt.Errorf("no SSO provider returned from management. " +
|
||||
"If you are using hosting Netbird see documentation at " +
|
||||
"https://github.com/netbirdio/netbird/tree/main/management for details")
|
||||
} else if ok && s.Code() == codes.Unimplemented {
|
||||
mgmtURL := managementURL
|
||||
if mgmtURL == "" {
|
||||
mgmtURL = internal.ManagementURLDefault().String()
|
||||
}
|
||||
return nil, fmt.Errorf("the management server, %s, does not support SSO providers, "+
|
||||
"please update your servver or use Setup Keys to login", mgmtURL)
|
||||
} else {
|
||||
return nil, fmt.Errorf("getting device authorization flow info failed with error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
hostedClient := internal.NewHostedDeviceFlow(
|
||||
providerConfig.ProviderConfig.Audience,
|
||||
providerConfig.ProviderConfig.ClientID,
|
||||
providerConfig.ProviderConfig.Domain,
|
||||
)
|
||||
|
||||
flowInfo, err := hostedClient.RequestDeviceCode(context.TODO())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting a request device code failed: %v", err)
|
||||
}
|
||||
|
||||
openURL(cmd, flowInfo.VerificationURI, flowInfo.VerificationURIComplete, flowInfo.UserCode)
|
||||
|
||||
waitTimeout := time.Duration(flowInfo.ExpiresIn)
|
||||
waitCTX, c := context.WithTimeout(context.TODO(), waitTimeout*time.Second)
|
||||
defer c()
|
||||
|
||||
tokenInfo, err := hostedClient.WaitToken(waitCTX, flowInfo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("waiting for browser login failed: %v", err)
|
||||
}
|
||||
|
||||
return &tokenInfo, nil
|
||||
}
|
||||
|
||||
func openURL(cmd *cobra.Command, verificationURI, verificationURIComplete, userCode string) {
|
||||
err := open.Run(verificationURIComplete)
|
||||
if err != nil {
|
||||
cmd.Println("Unable to open the default browser.")
|
||||
cmd.Println("If this is not an interactive shell, you may want to use the setup key, see https://www.netbird.io/docs/overview/setup-keys")
|
||||
cmd.Printf("Otherwise, you can continue the login flow by accessing the url below:\n\t%s\n", verificationURI)
|
||||
cmd.Printf("Use the access code: %s\n", userCode)
|
||||
cmd.Println("Or press CTRL + C or COMMAND + C")
|
||||
}
|
||||
}
|
||||
|
@ -30,12 +30,12 @@ var (
|
||||
managementURL string
|
||||
adminURL string
|
||||
setupKey string
|
||||
jwtToken string
|
||||
preSharedKey string
|
||||
rootCmd = &cobra.Command{
|
||||
Use: "wiretrustee",
|
||||
Short: "",
|
||||
Long: "",
|
||||
Use: "wiretrustee",
|
||||
Short: "",
|
||||
Long: "",
|
||||
SilenceUsage: true,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -47,7 +47,7 @@ func (p *program) Start(svc service.Service) error {
|
||||
defer listen.Close()
|
||||
|
||||
if split[0] == "unix" {
|
||||
err = os.Chmod(split[1], 0o666)
|
||||
err = os.Chmod(split[1], 0666)
|
||||
if err != nil {
|
||||
log.Errorf("failed setting daemon permissions: %v", split[1])
|
||||
return
|
||||
@ -56,7 +56,7 @@ func (p *program) Start(svc service.Service) error {
|
||||
|
||||
serverInstance := server.New(p.ctx, managementURL, adminURL, configPath, logFile)
|
||||
if err := serverInstance.Start(); err != nil {
|
||||
log.Fatalf("failed start daemon: %v", err)
|
||||
log.Fatalf("failed to start daemon: %v", err)
|
||||
}
|
||||
proto.RegisterDaemonServiceServer(p.serv, serverInstance)
|
||||
|
||||
|
@ -24,6 +24,11 @@ var installCmd = &cobra.Command{
|
||||
logLevel,
|
||||
}
|
||||
|
||||
if managementURL != "" {
|
||||
svcConfig.Arguments = append(svcConfig.Arguments, "--management-url")
|
||||
svcConfig.Arguments = append(svcConfig.Arguments, managementURL)
|
||||
}
|
||||
|
||||
if runtime.GOOS == "linux" {
|
||||
// Respected only by systemd systems
|
||||
svcConfig.Dependencies = []string{"After=network.target syslog.target"}
|
||||
|
@ -2,9 +2,9 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/netbirdio/netbird/util"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
@ -20,26 +20,32 @@ var statusCmd = &cobra.Command{
|
||||
|
||||
err := util.InitLog(logLevel, "console")
|
||||
if err != nil {
|
||||
log.Errorf("failed initializing log %v", err)
|
||||
return err
|
||||
return fmt.Errorf("failed initializing log %v", err)
|
||||
}
|
||||
|
||||
ctx := internal.CtxInitState(context.Background())
|
||||
|
||||
conn, err := DialClientGRPCServer(ctx, daemonAddr)
|
||||
if err != nil {
|
||||
log.Errorf("failed to connect to service CLI interface %v", err)
|
||||
return err
|
||||
return fmt.Errorf("failed to connect to daemon error: %v\n"+
|
||||
"If the daemon is not running please run: "+
|
||||
"\nnetbird service install \nnetbird service start\n", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
resp, err := proto.NewDaemonServiceClient(conn).Status(cmd.Context(), &proto.StatusRequest{})
|
||||
if err != nil {
|
||||
log.Errorf("status failed: %v", status.Convert(err).Message())
|
||||
return nil
|
||||
return fmt.Errorf("status failed: %v", status.Convert(err).Message())
|
||||
}
|
||||
|
||||
if resp.GetStatus() == string(internal.StatusNeedsLogin) || resp.GetStatus() == string(internal.StatusLoginFailed) {
|
||||
// todo: update login doc url
|
||||
cmd.Printf("run the command \"netbird up\" to login. If no SSO provider has been set " +
|
||||
"in your management server" +
|
||||
"you can use a setup-key, " +
|
||||
"see more at https://www.netbird.io/docs/overview/setup-keys for more info")
|
||||
}
|
||||
|
||||
log.Infof("status: %v", resp.Status)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
100
client/cmd/up.go
100
client/cmd/up.go
@ -2,13 +2,13 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/netbirdio/netbird/util"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"fmt"
|
||||
"github.com/netbirdio/netbird/client/internal"
|
||||
"github.com/netbirdio/netbird/client/proto"
|
||||
"github.com/netbirdio/netbird/util"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/codes"
|
||||
gstatus "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var upCmd = &cobra.Command{
|
||||
@ -17,10 +17,9 @@ var upCmd = &cobra.Command{
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
SetFlagsFromEnvVars()
|
||||
|
||||
err := util.InitLog(logLevel, logFile)
|
||||
err := util.InitLog(logLevel, "console")
|
||||
if err != nil {
|
||||
log.Errorf("failed initializing log %v", err)
|
||||
return err
|
||||
return fmt.Errorf("failed initializing log %v", err)
|
||||
}
|
||||
|
||||
ctx := internal.CtxInitState(cmd.Context())
|
||||
@ -29,15 +28,12 @@ var upCmd = &cobra.Command{
|
||||
if logFile == "console" {
|
||||
config, err := internal.GetConfig(managementURL, adminURL, configPath, preSharedKey)
|
||||
if err != nil {
|
||||
log.Errorf("get config file: %v", err)
|
||||
return err
|
||||
return fmt.Errorf("get config file: %v", err)
|
||||
}
|
||||
err = WithBackOff(func() error {
|
||||
return internal.Login(ctx, config, setupKey, jwtToken)
|
||||
})
|
||||
|
||||
err = foregroundLogin(ctx, cmd, config, setupKey)
|
||||
if err != nil {
|
||||
log.Errorf("backoff cycle failed: %v", err)
|
||||
return err
|
||||
return fmt.Errorf("foreground login failed: %v", err)
|
||||
}
|
||||
|
||||
var cancel context.CancelFunc
|
||||
@ -48,43 +44,67 @@ var upCmd = &cobra.Command{
|
||||
|
||||
conn, err := DialClientGRPCServer(ctx, daemonAddr)
|
||||
if err != nil {
|
||||
log.Errorf("failed to connect to service CLI interface %v", err)
|
||||
return err
|
||||
return fmt.Errorf("failed to connect to daemon error: %v\n"+
|
||||
"If the daemon is not running please run: "+
|
||||
"\nnetbird service install \nnetbird service start\n", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
daemonClient := proto.NewDaemonServiceClient(conn)
|
||||
client := proto.NewDaemonServiceClient(conn)
|
||||
|
||||
loginRequest := proto.LoginRequest{
|
||||
SetupKey: setupKey,
|
||||
PreSharedKey: preSharedKey,
|
||||
ManagementUrl: managementURL,
|
||||
}
|
||||
err = WithBackOff(func() error {
|
||||
_, err := daemonClient.Login(ctx, &loginRequest)
|
||||
return err
|
||||
})
|
||||
status, err := client.Status(ctx, &proto.StatusRequest{})
|
||||
if err != nil {
|
||||
log.Errorf("backoff cycle failed: %v", err)
|
||||
return err
|
||||
return fmt.Errorf("unable to get daemon status: %v", err)
|
||||
}
|
||||
|
||||
status, err := daemonClient.Status(ctx, &proto.StatusRequest{})
|
||||
if err != nil {
|
||||
log.Errorf("get status: %v", err)
|
||||
return err
|
||||
}
|
||||
if status.Status == string(internal.StatusNeedsLogin) || status.Status == string(internal.StatusLoginFailed) {
|
||||
loginRequest := proto.LoginRequest{
|
||||
SetupKey: setupKey,
|
||||
PreSharedKey: preSharedKey,
|
||||
ManagementUrl: managementURL,
|
||||
}
|
||||
|
||||
if status.Status != string(internal.StatusIdle) {
|
||||
log.Warnf("already connected")
|
||||
var loginErr error
|
||||
|
||||
var loginResp *proto.LoginResponse
|
||||
|
||||
err = WithBackOff(func() error {
|
||||
var backOffErr error
|
||||
loginResp, backOffErr = client.Login(ctx, &loginRequest)
|
||||
if s, ok := gstatus.FromError(backOffErr); ok && (s.Code() == codes.InvalidArgument ||
|
||||
s.Code() == codes.PermissionDenied ||
|
||||
s.Code() == codes.NotFound ||
|
||||
s.Code() == codes.Unimplemented) {
|
||||
loginErr = backOffErr
|
||||
return nil
|
||||
}
|
||||
return backOffErr
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("login backoff cycle failed: %v", err)
|
||||
}
|
||||
|
||||
if loginErr != nil {
|
||||
return fmt.Errorf("login failed: %v", loginErr)
|
||||
}
|
||||
|
||||
if loginResp.NeedsSSOLogin {
|
||||
openURL(cmd, loginResp.VerificationURI, loginResp.VerificationURIComplete, loginResp.UserCode)
|
||||
|
||||
_, err = client.WaitSSOLogin(ctx, &proto.WaitSSOLoginRequest{UserCode: loginResp.UserCode})
|
||||
if err != nil {
|
||||
return fmt.Errorf("waiting sso login failed with: %v", err)
|
||||
}
|
||||
}
|
||||
} else if status.Status != string(internal.StatusIdle) {
|
||||
cmd.Println("Already connected")
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err := daemonClient.Up(ctx, &proto.UpRequest{}); err != nil {
|
||||
log.Errorf("call service up method: %v", err)
|
||||
return err
|
||||
if _, err := client.Up(ctx, &proto.UpRequest{}); err != nil {
|
||||
return fmt.Errorf("call service up method: %v", err)
|
||||
}
|
||||
|
||||
cmd.Println("Connected")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
mgm "github.com/netbirdio/netbird/management/client"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
@ -83,6 +87,10 @@ func parseURL(serviceName, managementURL string) (*url.URL, error) {
|
||||
// ReadConfig reads existing config. In case provided managementURL is not empty overrides the read property
|
||||
func ReadConfig(managementURL, adminURL, configPath string, preSharedKey *string) (*Config, error) {
|
||||
config := &Config{}
|
||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||
return nil, status.Errorf(codes.NotFound, "config file doesn't exist")
|
||||
}
|
||||
|
||||
if _, err := util.ReadJson(configPath, config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -151,3 +159,77 @@ 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
|
||||
Domain string
|
||||
// Audience An Audience for to authorization validation
|
||||
Audience 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 management Service %s", config.ManagementURL.String())
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
err = mgmClient.Close()
|
||||
if err != nil {
|
||||
log.Errorf("failed closing Management Service client: %v", err)
|
||||
return DeviceAuthorizationFlow{}, err
|
||||
}
|
||||
|
||||
return DeviceAuthorizationFlow{
|
||||
Provider: protoDeviceAuthorizationFlow.Provider.String(),
|
||||
|
||||
ProviderConfig: ProviderConfig{
|
||||
Audience: protoDeviceAuthorizationFlow.ProviderConfig.Audience,
|
||||
ClientID: protoDeviceAuthorizationFlow.ProviderConfig.ClientID,
|
||||
ClientSecret: protoDeviceAuthorizationFlow.ProviderConfig.ClientSecret,
|
||||
Domain: protoDeviceAuthorizationFlow.ProviderConfig.Domain,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
@ -29,7 +29,12 @@ func RunClient(ctx context.Context, config *Config) error {
|
||||
}
|
||||
|
||||
state := CtxGetState(ctx)
|
||||
defer state.Set(StatusIdle)
|
||||
defer func() {
|
||||
s, err := state.Status()
|
||||
if err != nil || s != StatusNeedsLogin {
|
||||
state.Set(StatusIdle)
|
||||
}
|
||||
}()
|
||||
|
||||
wrapErr := state.Wrap
|
||||
operation := func() error {
|
||||
@ -57,6 +62,10 @@ func RunClient(ctx context.Context, config *Config) error {
|
||||
mgmClient, loginResp, err := connectToManagement(ctx, config.ManagementURL.Host, myPrivateKey, mgmTlsEnabled)
|
||||
if err != nil {
|
||||
log.Warn(err)
|
||||
if s, ok := status.FromError(err); ok && s.Code() == codes.PermissionDenied {
|
||||
state.Set(StatusNeedsLogin)
|
||||
return nil
|
||||
}
|
||||
return wrapErr(err)
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/netbirdio/netbird/client/system"
|
||||
mgm "github.com/netbirdio/netbird/management/client"
|
||||
@ -77,14 +76,14 @@ func loginPeer(serverPublicKey wgtypes.Key, client *mgm.GrpcClient, setupKey str
|
||||
func registerPeer(serverPublicKey wgtypes.Key, client *mgm.GrpcClient, setupKey string, jwtToken string) (*mgmProto.LoginResponse, error) {
|
||||
validSetupKey, err := uuid.Parse(setupKey)
|
||||
if err != nil && jwtToken == "" {
|
||||
return nil, err
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid setup-key or no sso information provided, err: %v", err)
|
||||
}
|
||||
|
||||
log.Debugf("sending peer registration request to Management Service")
|
||||
info := system.GetInfo()
|
||||
loginResp, err := client.Register(serverPublicKey, validSetupKey.String(), jwtToken, info)
|
||||
if err != nil {
|
||||
log.Errorf("failed registering peer %v", err)
|
||||
log.Errorf("failed registering peer %v,%s", err, validSetupKey.String())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package oauth
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -11,19 +11,50 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// auth0GrantType grant type for device flow on Auth0
|
||||
// OAuthClient is a OAuth client interface for various idp providers
|
||||
type OAuthClient interface {
|
||||
RequestDeviceCode(ctx context.Context) (DeviceAuthInfo, error)
|
||||
RotateAccessToken(ctx context.Context, refreshToken string) (TokenInfo, error)
|
||||
WaitToken(ctx context.Context, info DeviceAuthInfo) (TokenInfo, error)
|
||||
}
|
||||
|
||||
// HTTPClient http client interface for API calls
|
||||
type HTTPClient interface {
|
||||
Do(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// DeviceAuthInfo holds information for the OAuth device login flow
|
||||
type DeviceAuthInfo struct {
|
||||
DeviceCode string `json:"device_code"`
|
||||
UserCode string `json:"user_code"`
|
||||
VerificationURI string `json:"verification_uri"`
|
||||
VerificationURIComplete string `json:"verification_uri_complete"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
Interval int `json:"interval"`
|
||||
}
|
||||
|
||||
// TokenInfo holds information of issued access token
|
||||
type TokenInfo struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
IDToken string `json:"id_token"`
|
||||
TokenType string `json:"token_type"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
}
|
||||
|
||||
// HostedGrantType grant type for device flow on Hosted
|
||||
const (
|
||||
auth0GrantType = "urn:ietf:params:oauth:grant-type:device_code"
|
||||
auth0RefreshGrant = "refresh_token"
|
||||
HostedGrantType = "urn:ietf:params:oauth:grant-type:device_code"
|
||||
HostedRefreshGrant = "refresh_token"
|
||||
)
|
||||
|
||||
// Auth0 client
|
||||
type Auth0 struct {
|
||||
// Auth0 API Audience for validation
|
||||
// Hosted client
|
||||
type Hosted struct {
|
||||
// Hosted API Audience for validation
|
||||
Audience string
|
||||
// Auth0 Native application client id
|
||||
// Hosted Native application client id
|
||||
ClientID string
|
||||
// Auth0 domain
|
||||
// Hosted domain
|
||||
Domain string
|
||||
|
||||
HTTPClient HTTPClient
|
||||
@ -43,7 +74,7 @@ type TokenRequestPayload struct {
|
||||
RefreshToken string `json:"refresh_token,omitempty"`
|
||||
}
|
||||
|
||||
// TokenRequestResponse used for parsing Auth0 token's response
|
||||
// TokenRequestResponse used for parsing Hosted token's response
|
||||
type TokenRequestResponse struct {
|
||||
Error string `json:"error"`
|
||||
ErrorDescription string `json:"error_description"`
|
||||
@ -55,8 +86,8 @@ type Claims struct {
|
||||
Audience string `json:"aud"`
|
||||
}
|
||||
|
||||
// NewAuth0DeviceFlow returns an Auth0 OAuth client
|
||||
func NewAuth0DeviceFlow(audience string, clientID string, domain string) *Auth0 {
|
||||
// NewHostedDeviceFlow returns an Hosted OAuth client
|
||||
func NewHostedDeviceFlow(audience string, clientID string, domain string) *Hosted {
|
||||
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
|
||||
httpTransport.MaxIdleConns = 5
|
||||
|
||||
@ -65,7 +96,7 @@ func NewAuth0DeviceFlow(audience string, clientID string, domain string) *Auth0
|
||||
Transport: httpTransport,
|
||||
}
|
||||
|
||||
return &Auth0{
|
||||
return &Hosted{
|
||||
Audience: audience,
|
||||
ClientID: clientID,
|
||||
Domain: domain,
|
||||
@ -73,12 +104,12 @@ func NewAuth0DeviceFlow(audience string, clientID string, domain string) *Auth0
|
||||
}
|
||||
}
|
||||
|
||||
// RequestDeviceCode requests a device code login flow information from Auth0
|
||||
func (a *Auth0) RequestDeviceCode(ctx context.Context) (DeviceAuthInfo, error) {
|
||||
url := "https://" + a.Domain + "/oauth/device/code"
|
||||
// RequestDeviceCode requests a device code login flow information from Hosted
|
||||
func (h *Hosted) RequestDeviceCode(ctx context.Context) (DeviceAuthInfo, error) {
|
||||
url := "https://" + h.Domain + "/oauth/device/code"
|
||||
codePayload := RequestDeviceCodePayload{
|
||||
Audience: a.Audience,
|
||||
ClientID: a.ClientID,
|
||||
Audience: h.Audience,
|
||||
ClientID: h.ClientID,
|
||||
}
|
||||
p, err := json.Marshal(codePayload)
|
||||
if err != nil {
|
||||
@ -92,7 +123,7 @@ func (a *Auth0) RequestDeviceCode(ctx context.Context) (DeviceAuthInfo, error) {
|
||||
|
||||
req.Header.Add("content-type", "application/json")
|
||||
|
||||
res, err := a.HTTPClient.Do(req)
|
||||
res, err := h.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return DeviceAuthInfo{}, fmt.Errorf("doing request failed with error: %v", err)
|
||||
}
|
||||
@ -117,22 +148,22 @@ func (a *Auth0) RequestDeviceCode(ctx context.Context) (DeviceAuthInfo, error) {
|
||||
}
|
||||
|
||||
// WaitToken waits user's login and authorize the app. Once the user's authorize
|
||||
// it retrieves the access token from Auth0's endpoint and validates it before returning
|
||||
func (a *Auth0) WaitToken(ctx context.Context, info DeviceAuthInfo) (TokenInfo, error) {
|
||||
// it retrieves the access token from Hosted's endpoint and validates it before returning
|
||||
func (h *Hosted) WaitToken(ctx context.Context, info DeviceAuthInfo) (TokenInfo, error) {
|
||||
ticker := time.NewTicker(time.Duration(info.Interval) * time.Second)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return TokenInfo{}, ctx.Err()
|
||||
case <-ticker.C:
|
||||
url := "https://" + a.Domain + "/oauth/token"
|
||||
url := "https://" + h.Domain + "/oauth/token"
|
||||
tokenReqPayload := TokenRequestPayload{
|
||||
GrantType: auth0GrantType,
|
||||
GrantType: HostedGrantType,
|
||||
DeviceCode: info.DeviceCode,
|
||||
ClientID: a.ClientID,
|
||||
ClientID: h.ClientID,
|
||||
}
|
||||
|
||||
body, statusCode, err := requestToken(a.HTTPClient, url, tokenReqPayload)
|
||||
body, statusCode, err := requestToken(h.HTTPClient, url, tokenReqPayload)
|
||||
if err != nil {
|
||||
return TokenInfo{}, fmt.Errorf("wait for token: %v", err)
|
||||
}
|
||||
@ -154,7 +185,7 @@ func (a *Auth0) WaitToken(ctx context.Context, info DeviceAuthInfo) (TokenInfo,
|
||||
return TokenInfo{}, fmt.Errorf(tokenResponse.ErrorDescription)
|
||||
}
|
||||
|
||||
err = isValidAccessToken(tokenResponse.AccessToken, a.Audience)
|
||||
err = isValidAccessToken(tokenResponse.AccessToken, h.Audience)
|
||||
if err != nil {
|
||||
return TokenInfo{}, fmt.Errorf("validate access token failed with error: %v", err)
|
||||
}
|
||||
@ -172,15 +203,15 @@ func (a *Auth0) WaitToken(ctx context.Context, info DeviceAuthInfo) (TokenInfo,
|
||||
}
|
||||
|
||||
// RotateAccessToken requests a new token using an existing refresh token
|
||||
func (a *Auth0) RotateAccessToken(ctx context.Context, refreshToken string) (TokenInfo, error) {
|
||||
url := "https://" + a.Domain + "/oauth/token"
|
||||
func (h *Hosted) RotateAccessToken(ctx context.Context, refreshToken string) (TokenInfo, error) {
|
||||
url := "https://" + h.Domain + "/oauth/token"
|
||||
tokenReqPayload := TokenRequestPayload{
|
||||
GrantType: auth0RefreshGrant,
|
||||
ClientID: a.ClientID,
|
||||
GrantType: HostedRefreshGrant,
|
||||
ClientID: h.ClientID,
|
||||
RefreshToken: refreshToken,
|
||||
}
|
||||
|
||||
body, statusCode, err := requestToken(a.HTTPClient, url, tokenReqPayload)
|
||||
body, statusCode, err := requestToken(h.HTTPClient, url, tokenReqPayload)
|
||||
if err != nil {
|
||||
return TokenInfo{}, fmt.Errorf("rotate access token: %v", err)
|
||||
}
|
||||
@ -195,7 +226,7 @@ func (a *Auth0) RotateAccessToken(ctx context.Context, refreshToken string) (Tok
|
||||
return TokenInfo{}, fmt.Errorf("parsing token response failed with error: %v", err)
|
||||
}
|
||||
|
||||
err = isValidAccessToken(tokenResponse.AccessToken, a.Audience)
|
||||
err = isValidAccessToken(tokenResponse.AccessToken, h.Audience)
|
||||
if err != nil {
|
||||
return TokenInfo{}, fmt.Errorf("validate access token failed with error: %v", err)
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// HTTPClient http client interface for API calls
|
||||
type HTTPClient interface {
|
||||
Do(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// DeviceAuthInfo holds information for the OAuth device login flow
|
||||
type DeviceAuthInfo struct {
|
||||
DeviceCode string `json:"device_code"`
|
||||
UserCode string `json:"user_code"`
|
||||
VerificationURI string `json:"verification_uri"`
|
||||
VerificationURIComplete string `json:"verification_uri_complete"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
Interval int `json:"interval"`
|
||||
}
|
||||
|
||||
// TokenInfo holds information of issued access token
|
||||
type TokenInfo struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
IDToken string `json:"id_token"`
|
||||
TokenType string `json:"token_type"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
}
|
||||
|
||||
// Client is a OAuth client interface for various idp providers
|
||||
type Client interface {
|
||||
RequestDeviceCode(ctx context.Context) (DeviceAuthInfo, error)
|
||||
RotateAccessToken(ctx context.Context, refreshToken string) (TokenInfo, error)
|
||||
WaitToken(ctx context.Context, info DeviceAuthInfo) (TokenInfo, error)
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/99designs/keyring"
|
||||
)
|
||||
|
||||
// ServiceName default service name for saving the secret
|
||||
const ServiceName = "Wiretrustee"
|
||||
|
||||
func newSecretAPI() (keyring.Keyring, error) {
|
||||
return keyring.Open(keyring.Config{
|
||||
ServiceName: ServiceName,
|
||||
//KeychainName: ServiceName,
|
||||
})
|
||||
}
|
||||
|
||||
// SetSecret stores the secret in the system's available backend
|
||||
func SetSecret(key string, value string) error {
|
||||
storeAPI, err := newSecretAPI()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create secret API for setting a secret, error: %v", err)
|
||||
}
|
||||
|
||||
item := keyring.Item{
|
||||
Key: key,
|
||||
Data: []byte(value),
|
||||
}
|
||||
|
||||
err = storeAPI.Set(item)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to set the secret, error: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSecret retrieves a secret from the system's available backend
|
||||
func GetSecret(key string) (string, error) {
|
||||
storeAPI, err := newSecretAPI()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create secret API for getting a secret, error: %v", err)
|
||||
}
|
||||
|
||||
item, err := storeAPI.Get(key)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get secret, error: %v", err)
|
||||
}
|
||||
|
||||
return string(item.Data), nil
|
||||
}
|
||||
|
||||
// DeleteSecret deletes a secret from the system's available backend
|
||||
func DeleteSecret(key string) error {
|
||||
storeAPI, err := newSecretAPI()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create secret API for deleting a secret, error: %v", err)
|
||||
}
|
||||
|
||||
err = storeAPI.Remove(key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete secret, error: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSecret(t *testing.T) {
|
||||
// this test is not ready to run as part of our ci/cd
|
||||
// todo fix testing
|
||||
if os.Getenv("CI") == "true" {
|
||||
t.Skip("skipping testing in github actions")
|
||||
}
|
||||
|
||||
key := "testing"
|
||||
value := "1234"
|
||||
err := SetSecret(key, value)
|
||||
require.NoError(t, err, "should set secret")
|
||||
|
||||
v, err := GetSecret(key)
|
||||
require.NoError(t, err, "should retrieve secret")
|
||||
require.Equal(t, value, v, "values should match")
|
||||
|
||||
err = DeleteSecret(key)
|
||||
require.NoError(t, err, "should delete secret")
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package oauth
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -43,7 +43,7 @@ func (c *mockHTTPClient) Do(req *http.Request) (*http.Response, error) {
|
||||
}, c.err
|
||||
}
|
||||
|
||||
func TestAuth0_RequestDeviceCode(t *testing.T) {
|
||||
func TestHosted_RequestDeviceCode(t *testing.T) {
|
||||
type test struct {
|
||||
name string
|
||||
inputResBody string
|
||||
@ -107,14 +107,14 @@ func TestAuth0_RequestDeviceCode(t *testing.T) {
|
||||
err: testCase.inputReqError,
|
||||
}
|
||||
|
||||
auth0 := Auth0{
|
||||
hosted := Hosted{
|
||||
Audience: testCase.expectPayload.Audience,
|
||||
ClientID: testCase.expectPayload.ClientID,
|
||||
Domain: "test.auth0.com",
|
||||
Domain: "test.hosted.com",
|
||||
HTTPClient: &httpClient,
|
||||
}
|
||||
|
||||
authInfo, err := auth0.RequestDeviceCode(context.TODO())
|
||||
authInfo, err := hosted.RequestDeviceCode(context.TODO())
|
||||
testCase.testingErrFunc(t, err, testCase.expectedErrorMSG)
|
||||
|
||||
payload, _ := json.Marshal(testCase.expectPayload)
|
||||
@ -127,7 +127,7 @@ func TestAuth0_RequestDeviceCode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuth0_WaitToken(t *testing.T) {
|
||||
func TestHosted_WaitToken(t *testing.T) {
|
||||
type test struct {
|
||||
name string
|
||||
inputResBody string
|
||||
@ -153,7 +153,7 @@ func TestAuth0_WaitToken(t *testing.T) {
|
||||
}
|
||||
|
||||
tokenReqPayload := TokenRequestPayload{
|
||||
GrantType: auth0GrantType,
|
||||
GrantType: HostedGrantType,
|
||||
DeviceCode: defaultInfo.DeviceCode,
|
||||
ClientID: "test",
|
||||
}
|
||||
@ -267,16 +267,16 @@ func TestAuth0_WaitToken(t *testing.T) {
|
||||
countResBody: testCase.inputCountResBody,
|
||||
}
|
||||
|
||||
auth0 := Auth0{
|
||||
hosted := Hosted{
|
||||
Audience: testCase.inputAudience,
|
||||
ClientID: testCase.expectPayload.ClientID,
|
||||
Domain: "test.auth0.com",
|
||||
Domain: "test.hosted.com",
|
||||
HTTPClient: &httpClient,
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), testCase.inputTimeout)
|
||||
defer cancel()
|
||||
tokenInfo, err := auth0.WaitToken(ctx, testCase.inputInfo)
|
||||
tokenInfo, err := hosted.WaitToken(ctx, testCase.inputInfo)
|
||||
testCase.testingErrFunc(t, err, testCase.expectedErrorMSG)
|
||||
|
||||
var payload []byte
|
||||
@ -294,7 +294,7 @@ func TestAuth0_WaitToken(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuth0_RotateAccessToken(t *testing.T) {
|
||||
func TestHosted_RotateAccessToken(t *testing.T) {
|
||||
type test struct {
|
||||
name string
|
||||
inputResBody string
|
||||
@ -318,7 +318,7 @@ func TestAuth0_RotateAccessToken(t *testing.T) {
|
||||
}
|
||||
|
||||
tokenReqPayload := TokenRequestPayload{
|
||||
GrantType: auth0RefreshGrant,
|
||||
GrantType: HostedRefreshGrant,
|
||||
ClientID: "test",
|
||||
RefreshToken: "refresh_test",
|
||||
}
|
||||
@ -391,14 +391,14 @@ func TestAuth0_RotateAccessToken(t *testing.T) {
|
||||
MaxReqs: testCase.inputMaxReqs,
|
||||
}
|
||||
|
||||
auth0 := Auth0{
|
||||
hosted := Hosted{
|
||||
Audience: testCase.inputAudience,
|
||||
ClientID: testCase.expectPayload.ClientID,
|
||||
Domain: "test.auth0.com",
|
||||
Domain: "test.hosted.com",
|
||||
HTTPClient: &httpClient,
|
||||
}
|
||||
|
||||
tokenInfo, err := auth0.RotateAccessToken(context.TODO(), testCase.expectPayload.RefreshToken)
|
||||
tokenInfo, err := hosted.RotateAccessToken(context.TODO(), testCase.expectPayload.RefreshToken)
|
||||
testCase.testingErrFunc(t, err, testCase.expectedErrorMSG)
|
||||
|
||||
var payload []byte
|
@ -10,8 +10,10 @@ type StatusType string
|
||||
const (
|
||||
StatusIdle StatusType = "Idle"
|
||||
|
||||
StatusConnecting StatusType = "Connecting"
|
||||
StatusConnected StatusType = "Connected"
|
||||
StatusConnecting StatusType = "Connecting"
|
||||
StatusConnected StatusType = "Connected"
|
||||
StatusNeedsLogin StatusType = "NeedsLogin"
|
||||
StatusLoginFailed StatusType = "LoginFailed"
|
||||
)
|
||||
|
||||
// CtxInitState setup context state into the context tree.
|
||||
|
@ -34,8 +34,6 @@ type LoginRequest struct {
|
||||
ManagementUrl string `protobuf:"bytes,3,opt,name=managementUrl,proto3" json:"managementUrl,omitempty"`
|
||||
// adminUrl to manage keys.
|
||||
AdminURL string `protobuf:"bytes,4,opt,name=adminURL,proto3" json:"adminURL,omitempty"`
|
||||
// jwtToken sso token to authenticate.
|
||||
JwtToken string `protobuf:"bytes,5,opt,name=jwtToken,proto3" json:"jwtToken,omitempty"`
|
||||
}
|
||||
|
||||
func (x *LoginRequest) Reset() {
|
||||
@ -98,17 +96,15 @@ func (x *LoginRequest) GetAdminURL() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *LoginRequest) GetJwtToken() string {
|
||||
if x != nil {
|
||||
return x.JwtToken
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type LoginResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
NeedsSSOLogin bool `protobuf:"varint,1,opt,name=needsSSOLogin,proto3" json:"needsSSOLogin,omitempty"`
|
||||
UserCode string `protobuf:"bytes,2,opt,name=userCode,proto3" json:"userCode,omitempty"`
|
||||
VerificationURI string `protobuf:"bytes,3,opt,name=verificationURI,proto3" json:"verificationURI,omitempty"`
|
||||
VerificationURIComplete string `protobuf:"bytes,4,opt,name=verificationURIComplete,proto3" json:"verificationURIComplete,omitempty"`
|
||||
}
|
||||
|
||||
func (x *LoginResponse) Reset() {
|
||||
@ -143,6 +139,119 @@ func (*LoginResponse) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *LoginResponse) GetNeedsSSOLogin() bool {
|
||||
if x != nil {
|
||||
return x.NeedsSSOLogin
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *LoginResponse) GetUserCode() string {
|
||||
if x != nil {
|
||||
return x.UserCode
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *LoginResponse) GetVerificationURI() string {
|
||||
if x != nil {
|
||||
return x.VerificationURI
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *LoginResponse) GetVerificationURIComplete() string {
|
||||
if x != nil {
|
||||
return x.VerificationURIComplete
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type WaitSSOLoginRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
UserCode string `protobuf:"bytes,1,opt,name=userCode,proto3" json:"userCode,omitempty"`
|
||||
}
|
||||
|
||||
func (x *WaitSSOLoginRequest) Reset() {
|
||||
*x = WaitSSOLoginRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_daemon_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *WaitSSOLoginRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*WaitSSOLoginRequest) ProtoMessage() {}
|
||||
|
||||
func (x *WaitSSOLoginRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use WaitSSOLoginRequest.ProtoReflect.Descriptor instead.
|
||||
func (*WaitSSOLoginRequest) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *WaitSSOLoginRequest) GetUserCode() string {
|
||||
if x != nil {
|
||||
return x.UserCode
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type WaitSSOLoginResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *WaitSSOLoginResponse) Reset() {
|
||||
*x = WaitSSOLoginResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_daemon_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *WaitSSOLoginResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*WaitSSOLoginResponse) ProtoMessage() {}
|
||||
|
||||
func (x *WaitSSOLoginResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use WaitSSOLoginResponse.ProtoReflect.Descriptor instead.
|
||||
func (*WaitSSOLoginResponse) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
type UpRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -152,7 +261,7 @@ type UpRequest struct {
|
||||
func (x *UpRequest) Reset() {
|
||||
*x = UpRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_daemon_proto_msgTypes[2]
|
||||
mi := &file_daemon_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -165,7 +274,7 @@ func (x *UpRequest) String() string {
|
||||
func (*UpRequest) ProtoMessage() {}
|
||||
|
||||
func (x *UpRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[2]
|
||||
mi := &file_daemon_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -178,7 +287,7 @@ func (x *UpRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use UpRequest.ProtoReflect.Descriptor instead.
|
||||
func (*UpRequest) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{2}
|
||||
return file_daemon_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
type UpResponse struct {
|
||||
@ -190,7 +299,7 @@ type UpResponse struct {
|
||||
func (x *UpResponse) Reset() {
|
||||
*x = UpResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_daemon_proto_msgTypes[3]
|
||||
mi := &file_daemon_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -203,7 +312,7 @@ func (x *UpResponse) String() string {
|
||||
func (*UpResponse) ProtoMessage() {}
|
||||
|
||||
func (x *UpResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[3]
|
||||
mi := &file_daemon_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -216,7 +325,7 @@ func (x *UpResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use UpResponse.ProtoReflect.Descriptor instead.
|
||||
func (*UpResponse) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{3}
|
||||
return file_daemon_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
type StatusRequest struct {
|
||||
@ -228,7 +337,7 @@ type StatusRequest struct {
|
||||
func (x *StatusRequest) Reset() {
|
||||
*x = StatusRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_daemon_proto_msgTypes[4]
|
||||
mi := &file_daemon_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -241,7 +350,7 @@ func (x *StatusRequest) String() string {
|
||||
func (*StatusRequest) ProtoMessage() {}
|
||||
|
||||
func (x *StatusRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[4]
|
||||
mi := &file_daemon_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -254,7 +363,7 @@ func (x *StatusRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use StatusRequest.ProtoReflect.Descriptor instead.
|
||||
func (*StatusRequest) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{4}
|
||||
return file_daemon_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
type StatusResponse struct {
|
||||
@ -269,7 +378,7 @@ type StatusResponse struct {
|
||||
func (x *StatusResponse) Reset() {
|
||||
*x = StatusResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_daemon_proto_msgTypes[5]
|
||||
mi := &file_daemon_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -282,7 +391,7 @@ func (x *StatusResponse) String() string {
|
||||
func (*StatusResponse) ProtoMessage() {}
|
||||
|
||||
func (x *StatusResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[5]
|
||||
mi := &file_daemon_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -295,7 +404,7 @@ func (x *StatusResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead.
|
||||
func (*StatusResponse) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{5}
|
||||
return file_daemon_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *StatusResponse) GetStatus() string {
|
||||
@ -314,7 +423,7 @@ type DownRequest struct {
|
||||
func (x *DownRequest) Reset() {
|
||||
*x = DownRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_daemon_proto_msgTypes[6]
|
||||
mi := &file_daemon_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -327,7 +436,7 @@ func (x *DownRequest) String() string {
|
||||
func (*DownRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DownRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[6]
|
||||
mi := &file_daemon_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -340,7 +449,7 @@ func (x *DownRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use DownRequest.ProtoReflect.Descriptor instead.
|
||||
func (*DownRequest) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{6}
|
||||
return file_daemon_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
type DownResponse struct {
|
||||
@ -352,7 +461,7 @@ type DownResponse struct {
|
||||
func (x *DownResponse) Reset() {
|
||||
*x = DownResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_daemon_proto_msgTypes[7]
|
||||
mi := &file_daemon_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -365,7 +474,7 @@ func (x *DownResponse) String() string {
|
||||
func (*DownResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DownResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[7]
|
||||
mi := &file_daemon_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -378,7 +487,7 @@ func (x *DownResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use DownResponse.ProtoReflect.Descriptor instead.
|
||||
func (*DownResponse) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{7}
|
||||
return file_daemon_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
type GetConfigRequest struct {
|
||||
@ -390,7 +499,7 @@ type GetConfigRequest struct {
|
||||
func (x *GetConfigRequest) Reset() {
|
||||
*x = GetConfigRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_daemon_proto_msgTypes[8]
|
||||
mi := &file_daemon_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -403,7 +512,7 @@ func (x *GetConfigRequest) String() string {
|
||||
func (*GetConfigRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[8]
|
||||
mi := &file_daemon_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -416,7 +525,7 @@ func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GetConfigRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetConfigRequest) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{8}
|
||||
return file_daemon_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
type GetConfigResponse struct {
|
||||
@ -439,7 +548,7 @@ type GetConfigResponse struct {
|
||||
func (x *GetConfigResponse) Reset() {
|
||||
*x = GetConfigResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_daemon_proto_msgTypes[9]
|
||||
mi := &file_daemon_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -452,7 +561,7 @@ func (x *GetConfigResponse) String() string {
|
||||
func (*GetConfigResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[9]
|
||||
mi := &file_daemon_proto_msgTypes[11]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -465,7 +574,7 @@ func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GetConfigResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetConfigResponse) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{9}
|
||||
return file_daemon_proto_rawDescGZIP(), []int{11}
|
||||
}
|
||||
|
||||
func (x *GetConfigResponse) GetManagementUrl() string {
|
||||
@ -509,7 +618,7 @@ var file_daemon_proto_rawDesc = []byte{
|
||||
0x0a, 0x0c, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06,
|
||||
0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
|
||||
0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xac, 0x01, 0x0a, 0x0c, 0x4c, 0x6f, 0x67,
|
||||
0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x90, 0x01, 0x0a, 0x0c, 0x4c, 0x6f, 0x67,
|
||||
0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x74,
|
||||
0x75, 0x70, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x74,
|
||||
0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x53, 0x68, 0x61, 0x72,
|
||||
@ -518,50 +627,68 @@ var file_daemon_proto_rawDesc = []byte{
|
||||
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x72, 0x6c, 0x12,
|
||||
0x1a, 0x0a, 0x08, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x52, 0x4c, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x52, 0x4c, 0x12, 0x1a, 0x0a, 0x08, 0x6a,
|
||||
0x77, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6a,
|
||||
0x77, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x0f, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x69, 0x6e,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0b, 0x0a, 0x09, 0x55, 0x70, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x0c, 0x0a, 0x0a, 0x55, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x22, 0x28, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x0d,
|
||||
0x0a, 0x0b, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x0e, 0x0a,
|
||||
0x0c, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x0a,
|
||||
0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x22, 0xb3, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
||||
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
|
||||
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x1e, 0x0a,
|
||||
0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
|
||||
0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x53, 0x68,
|
||||
0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70,
|
||||
0x72, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x61,
|
||||
0x64, 0x6d, 0x69, 0x6e, 0x55, 0x52, 0x4c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61,
|
||||
0x64, 0x6d, 0x69, 0x6e, 0x55, 0x52, 0x4c, 0x32, 0xaa, 0x02, 0x0a, 0x0d, 0x44, 0x61, 0x65, 0x6d,
|
||||
0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x4c, 0x6f, 0x67,
|
||||
0x69, 0x6e, 0x12, 0x14, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x67, 0x69,
|
||||
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f,
|
||||
0x6e, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x12, 0x2d, 0x0a, 0x02, 0x55, 0x70, 0x12, 0x11, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e,
|
||||
0x2e, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x61, 0x65,
|
||||
0x6d, 0x6f, 0x6e, 0x2e, 0x55, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
|
||||
0x12, 0x39, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x15, 0x2e, 0x64, 0x61, 0x65,
|
||||
0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x16, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75,
|
||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x04, 0x44,
|
||||
0x6f, 0x77, 0x6e, 0x12, 0x13, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x6f, 0x77,
|
||||
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f,
|
||||
0x6e, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
|
||||
0x12, 0x42, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x2e,
|
||||
0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x09, 0x52, 0x08, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x52, 0x4c, 0x22, 0xb5, 0x01, 0x0a, 0x0d,
|
||||
0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a,
|
||||
0x0d, 0x6e, 0x65, 0x65, 0x64, 0x73, 0x53, 0x53, 0x4f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6e, 0x65, 0x65, 0x64, 0x73, 0x53, 0x53, 0x4f, 0x4c, 0x6f,
|
||||
0x67, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12,
|
||||
0x28, 0x0a, 0x0f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55,
|
||||
0x52, 0x49, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69,
|
||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x52, 0x49, 0x12, 0x38, 0x0a, 0x17, 0x76, 0x65, 0x72,
|
||||
0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x52, 0x49, 0x43, 0x6f, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x76, 0x65, 0x72, 0x69,
|
||||
0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x52, 0x49, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x74, 0x65, 0x22, 0x31, 0x0a, 0x13, 0x57, 0x61, 0x69, 0x74, 0x53, 0x53, 0x4f, 0x4c, 0x6f,
|
||||
0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73,
|
||||
0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73,
|
||||
0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x57, 0x61, 0x69, 0x74, 0x53, 0x53,
|
||||
0x4f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0b,
|
||||
0x0a, 0x09, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x0c, 0x0a, 0x0a, 0x55,
|
||||
0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x28, 0x0a, 0x0e, 0x53, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x22, 0x0d, 0x0a, 0x0b, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x22, 0x0e, 0x0a, 0x0c, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb3, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a,
|
||||
0x0d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x72, 0x6c, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x55, 0x72, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, 0x6c,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46,
|
||||
0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x0a,
|
||||
0x0c, 0x70, 0x72, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65,
|
||||
0x79, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x52, 0x4c, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x52, 0x4c, 0x32, 0xf7, 0x02,
|
||||
0x0a, 0x0d, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
|
||||
0x36, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x14, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f,
|
||||
0x6e, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15,
|
||||
0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0c, 0x57, 0x61, 0x69, 0x74, 0x53,
|
||||
0x53, 0x4f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1b, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e,
|
||||
0x2e, 0x57, 0x61, 0x69, 0x74, 0x53, 0x53, 0x4f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x57, 0x61,
|
||||
0x69, 0x74, 0x53, 0x53, 0x4f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x12, 0x2d, 0x0a, 0x02, 0x55, 0x70, 0x12, 0x11, 0x2e, 0x64, 0x61, 0x65,
|
||||
0x6d, 0x6f, 0x6e, 0x2e, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e,
|
||||
0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x55, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x15, 0x2e,
|
||||
0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x33,
|
||||
0x0a, 0x04, 0x44, 0x6f, 0x77, 0x6e, 0x12, 0x13, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e,
|
||||
0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x64, 0x61,
|
||||
0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x12, 0x18, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x64, 0x61, 0x65,
|
||||
0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -576,35 +703,39 @@ func file_daemon_proto_rawDescGZIP() []byte {
|
||||
return file_daemon_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_daemon_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
|
||||
var file_daemon_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
|
||||
var file_daemon_proto_goTypes = []interface{}{
|
||||
(*LoginRequest)(nil), // 0: daemon.LoginRequest
|
||||
(*LoginResponse)(nil), // 1: daemon.LoginResponse
|
||||
(*UpRequest)(nil), // 2: daemon.UpRequest
|
||||
(*UpResponse)(nil), // 3: daemon.UpResponse
|
||||
(*StatusRequest)(nil), // 4: daemon.StatusRequest
|
||||
(*StatusResponse)(nil), // 5: daemon.StatusResponse
|
||||
(*DownRequest)(nil), // 6: daemon.DownRequest
|
||||
(*DownResponse)(nil), // 7: daemon.DownResponse
|
||||
(*GetConfigRequest)(nil), // 8: daemon.GetConfigRequest
|
||||
(*GetConfigResponse)(nil), // 9: daemon.GetConfigResponse
|
||||
(*LoginRequest)(nil), // 0: daemon.LoginRequest
|
||||
(*LoginResponse)(nil), // 1: daemon.LoginResponse
|
||||
(*WaitSSOLoginRequest)(nil), // 2: daemon.WaitSSOLoginRequest
|
||||
(*WaitSSOLoginResponse)(nil), // 3: daemon.WaitSSOLoginResponse
|
||||
(*UpRequest)(nil), // 4: daemon.UpRequest
|
||||
(*UpResponse)(nil), // 5: daemon.UpResponse
|
||||
(*StatusRequest)(nil), // 6: daemon.StatusRequest
|
||||
(*StatusResponse)(nil), // 7: daemon.StatusResponse
|
||||
(*DownRequest)(nil), // 8: daemon.DownRequest
|
||||
(*DownResponse)(nil), // 9: daemon.DownResponse
|
||||
(*GetConfigRequest)(nil), // 10: daemon.GetConfigRequest
|
||||
(*GetConfigResponse)(nil), // 11: daemon.GetConfigResponse
|
||||
}
|
||||
var file_daemon_proto_depIdxs = []int32{
|
||||
0, // 0: daemon.DaemonService.Login:input_type -> daemon.LoginRequest
|
||||
2, // 1: daemon.DaemonService.Up:input_type -> daemon.UpRequest
|
||||
4, // 2: daemon.DaemonService.Status:input_type -> daemon.StatusRequest
|
||||
6, // 3: daemon.DaemonService.Down:input_type -> daemon.DownRequest
|
||||
8, // 4: daemon.DaemonService.GetConfig:input_type -> daemon.GetConfigRequest
|
||||
1, // 5: daemon.DaemonService.Login:output_type -> daemon.LoginResponse
|
||||
3, // 6: daemon.DaemonService.Up:output_type -> daemon.UpResponse
|
||||
5, // 7: daemon.DaemonService.Status:output_type -> daemon.StatusResponse
|
||||
7, // 8: daemon.DaemonService.Down:output_type -> daemon.DownResponse
|
||||
9, // 9: daemon.DaemonService.GetConfig:output_type -> daemon.GetConfigResponse
|
||||
5, // [5:10] is the sub-list for method output_type
|
||||
0, // [0:5] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
0, // 0: daemon.DaemonService.Login:input_type -> daemon.LoginRequest
|
||||
2, // 1: daemon.DaemonService.WaitSSOLogin:input_type -> daemon.WaitSSOLoginRequest
|
||||
4, // 2: daemon.DaemonService.Up:input_type -> daemon.UpRequest
|
||||
6, // 3: daemon.DaemonService.Status:input_type -> daemon.StatusRequest
|
||||
8, // 4: daemon.DaemonService.Down:input_type -> daemon.DownRequest
|
||||
10, // 5: daemon.DaemonService.GetConfig:input_type -> daemon.GetConfigRequest
|
||||
1, // 6: daemon.DaemonService.Login:output_type -> daemon.LoginResponse
|
||||
3, // 7: daemon.DaemonService.WaitSSOLogin:output_type -> daemon.WaitSSOLoginResponse
|
||||
5, // 8: daemon.DaemonService.Up:output_type -> daemon.UpResponse
|
||||
7, // 9: daemon.DaemonService.Status:output_type -> daemon.StatusResponse
|
||||
9, // 10: daemon.DaemonService.Down:output_type -> daemon.DownResponse
|
||||
11, // 11: daemon.DaemonService.GetConfig:output_type -> daemon.GetConfigResponse
|
||||
6, // [6:12] is the sub-list for method output_type
|
||||
0, // [0:6] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_daemon_proto_init() }
|
||||
@ -638,7 +769,7 @@ func file_daemon_proto_init() {
|
||||
}
|
||||
}
|
||||
file_daemon_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*UpRequest); i {
|
||||
switch v := v.(*WaitSSOLoginRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -650,7 +781,7 @@ func file_daemon_proto_init() {
|
||||
}
|
||||
}
|
||||
file_daemon_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*UpResponse); i {
|
||||
switch v := v.(*WaitSSOLoginResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -662,7 +793,7 @@ func file_daemon_proto_init() {
|
||||
}
|
||||
}
|
||||
file_daemon_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*StatusRequest); i {
|
||||
switch v := v.(*UpRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -674,7 +805,7 @@ func file_daemon_proto_init() {
|
||||
}
|
||||
}
|
||||
file_daemon_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*StatusResponse); i {
|
||||
switch v := v.(*UpResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -686,7 +817,7 @@ func file_daemon_proto_init() {
|
||||
}
|
||||
}
|
||||
file_daemon_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DownRequest); i {
|
||||
switch v := v.(*StatusRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -698,7 +829,7 @@ func file_daemon_proto_init() {
|
||||
}
|
||||
}
|
||||
file_daemon_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DownResponse); i {
|
||||
switch v := v.(*StatusResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -710,7 +841,7 @@ func file_daemon_proto_init() {
|
||||
}
|
||||
}
|
||||
file_daemon_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetConfigRequest); i {
|
||||
switch v := v.(*DownRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -722,6 +853,30 @@ func file_daemon_proto_init() {
|
||||
}
|
||||
}
|
||||
file_daemon_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DownResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_daemon_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetConfigRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_daemon_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetConfigResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@ -740,7 +895,7 @@ func file_daemon_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_daemon_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 10,
|
||||
NumMessages: 12,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
@ -10,6 +10,10 @@ service DaemonService {
|
||||
// Login uses setup key to prepare configuration for the daemon.
|
||||
rpc Login(LoginRequest) returns (LoginResponse) {}
|
||||
|
||||
// WaitSSOLogin uses the userCode to validate the TokenInfo and
|
||||
// waits for the user to continue with the login on a browser
|
||||
rpc WaitSSOLogin(WaitSSOLoginRequest) returns (WaitSSOLoginResponse) {}
|
||||
|
||||
// Up starts engine work in the daemon.
|
||||
rpc Up(UpRequest) returns (UpResponse) {}
|
||||
|
||||
@ -36,11 +40,20 @@ message LoginRequest {
|
||||
// adminUrl to manage keys.
|
||||
string adminURL = 4;
|
||||
|
||||
// jwtToken sso token to authenticate.
|
||||
string jwtToken = 5;
|
||||
}
|
||||
|
||||
message LoginResponse {}
|
||||
message LoginResponse {
|
||||
bool needsSSOLogin = 1;
|
||||
string userCode = 2;
|
||||
string verificationURI = 3;
|
||||
string verificationURIComplete = 4;
|
||||
}
|
||||
|
||||
message WaitSSOLoginRequest {
|
||||
string userCode = 1;
|
||||
}
|
||||
|
||||
message WaitSSOLoginResponse {}
|
||||
|
||||
message UpRequest {}
|
||||
|
||||
|
@ -20,6 +20,9 @@ const _ = grpc.SupportPackageIsVersion7
|
||||
type DaemonServiceClient interface {
|
||||
// Login uses setup key to prepare configuration for the daemon.
|
||||
Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error)
|
||||
// WaitSSOLogin uses the userCode to validate the TokenInfo and
|
||||
// waits for the user to continue with the login on a browser
|
||||
WaitSSOLogin(ctx context.Context, in *WaitSSOLoginRequest, opts ...grpc.CallOption) (*WaitSSOLoginResponse, error)
|
||||
// Up starts engine work in the daemon.
|
||||
Up(ctx context.Context, in *UpRequest, opts ...grpc.CallOption) (*UpResponse, error)
|
||||
// Status of the service.
|
||||
@ -47,6 +50,15 @@ func (c *daemonServiceClient) Login(ctx context.Context, in *LoginRequest, opts
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *daemonServiceClient) WaitSSOLogin(ctx context.Context, in *WaitSSOLoginRequest, opts ...grpc.CallOption) (*WaitSSOLoginResponse, error) {
|
||||
out := new(WaitSSOLoginResponse)
|
||||
err := c.cc.Invoke(ctx, "/daemon.DaemonService/WaitSSOLogin", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *daemonServiceClient) Up(ctx context.Context, in *UpRequest, opts ...grpc.CallOption) (*UpResponse, error) {
|
||||
out := new(UpResponse)
|
||||
err := c.cc.Invoke(ctx, "/daemon.DaemonService/Up", in, out, opts...)
|
||||
@ -89,6 +101,9 @@ func (c *daemonServiceClient) GetConfig(ctx context.Context, in *GetConfigReques
|
||||
type DaemonServiceServer interface {
|
||||
// Login uses setup key to prepare configuration for the daemon.
|
||||
Login(context.Context, *LoginRequest) (*LoginResponse, error)
|
||||
// WaitSSOLogin uses the userCode to validate the TokenInfo and
|
||||
// waits for the user to continue with the login on a browser
|
||||
WaitSSOLogin(context.Context, *WaitSSOLoginRequest) (*WaitSSOLoginResponse, error)
|
||||
// Up starts engine work in the daemon.
|
||||
Up(context.Context, *UpRequest) (*UpResponse, error)
|
||||
// Status of the service.
|
||||
@ -107,6 +122,9 @@ type UnimplementedDaemonServiceServer struct {
|
||||
func (UnimplementedDaemonServiceServer) Login(context.Context, *LoginRequest) (*LoginResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Login not implemented")
|
||||
}
|
||||
func (UnimplementedDaemonServiceServer) WaitSSOLogin(context.Context, *WaitSSOLoginRequest) (*WaitSSOLoginResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method WaitSSOLogin not implemented")
|
||||
}
|
||||
func (UnimplementedDaemonServiceServer) Up(context.Context, *UpRequest) (*UpResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Up not implemented")
|
||||
}
|
||||
@ -150,6 +168,24 @@ func _DaemonService_Login_Handler(srv interface{}, ctx context.Context, dec func
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _DaemonService_WaitSSOLogin_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(WaitSSOLoginRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(DaemonServiceServer).WaitSSOLogin(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/daemon.DaemonService/WaitSSOLogin",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DaemonServiceServer).WaitSSOLogin(ctx, req.(*WaitSSOLoginRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _DaemonService_Up_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UpRequest)
|
||||
if err := dec(in); err != nil {
|
||||
@ -233,6 +269,10 @@ var DaemonService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "Login",
|
||||
Handler: _DaemonService_Login_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "WaitSSOLogin",
|
||||
Handler: _DaemonService_WaitSSOLogin_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Up",
|
||||
Handler: _DaemonService_Up_Handler,
|
||||
|
@ -3,7 +3,10 @@ package server
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"google.golang.org/grpc/codes"
|
||||
gstatus "google.golang.org/grpc/status"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
@ -21,6 +24,9 @@ type Server struct {
|
||||
configPath string
|
||||
logFile string
|
||||
|
||||
oauthClient internal.OAuthClient
|
||||
deviceAuthInfo internal.DeviceAuthInfo
|
||||
|
||||
mutex sync.Mutex
|
||||
config *internal.Config
|
||||
proto.UnimplementedDaemonServiceServer
|
||||
@ -42,7 +48,7 @@ func (s *Server) Start() error {
|
||||
|
||||
// if current state contains any error, return it
|
||||
// in all other cases we can continue execution only if status is idle and up command was
|
||||
// not in the progress or already successfully estabilished connection.
|
||||
// not in the progress or already successfully established connection.
|
||||
status, err := state.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -55,12 +61,24 @@ func (s *Server) Start() error {
|
||||
ctx, cancel := context.WithCancel(s.rootCtx)
|
||||
s.actCancel = cancel
|
||||
|
||||
// if configuration exists, we just start connections.
|
||||
// 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.managementURL, s.adminURL, s.configPath, nil)
|
||||
if err != nil {
|
||||
log.Warnf("no config file, skip connection stage: %v", err)
|
||||
if errorStatus, ok := gstatus.FromError(err); ok && errorStatus.Code() == codes.NotFound {
|
||||
config, err = internal.GetConfig(s.managementURL, s.adminURL, s.configPath, "")
|
||||
if err != nil {
|
||||
log.Warnf("unable to create configuration file: %v", err)
|
||||
return err
|
||||
}
|
||||
state.Set(internal.StatusNeedsLogin)
|
||||
return nil
|
||||
} else if err != nil {
|
||||
log.Warnf("unable to create configuration file: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// if configuration exists, we just start connections.
|
||||
|
||||
s.config = config
|
||||
|
||||
go func() {
|
||||
@ -83,7 +101,12 @@ func (s *Server) Login(_ context.Context, msg *proto.LoginRequest) (*proto.Login
|
||||
s.mutex.Unlock()
|
||||
|
||||
state := internal.CtxGetState(ctx)
|
||||
defer state.Set(internal.StatusIdle)
|
||||
defer func() {
|
||||
s, err := state.Status()
|
||||
if err != nil || (s != internal.StatusNeedsLogin && s != internal.StatusLoginFailed) {
|
||||
state.Set(internal.StatusIdle)
|
||||
}
|
||||
}()
|
||||
|
||||
state.Set(internal.StatusConnecting)
|
||||
|
||||
@ -108,16 +131,124 @@ func (s *Server) Login(_ context.Context, msg *proto.LoginRequest) (*proto.Login
|
||||
s.config = config
|
||||
s.mutex.Unlock()
|
||||
|
||||
// login operation uses backoff scheme to connect to management API
|
||||
// we don't wait for result and return response immediately.
|
||||
if err := internal.Login(ctx, s.config, msg.SetupKey, msg.JwtToken); err != nil {
|
||||
log.Errorf("failed login: %v", err)
|
||||
if msg.SetupKey == "" {
|
||||
providerConfig, err := internal.GetDeviceAuthorizationFlowInfo(ctx, config)
|
||||
if err != nil {
|
||||
state.Set(internal.StatusLoginFailed)
|
||||
s, ok := gstatus.FromError(err)
|
||||
if ok && s.Code() == codes.NotFound {
|
||||
return nil, gstatus.Errorf(codes.NotFound, "no SSO provider returned from management. "+
|
||||
"If you are using hosting Netbird see documentation at "+
|
||||
"https://github.com/netbirdio/netbird/tree/main/management for details")
|
||||
} else if ok && s.Code() == codes.Unimplemented {
|
||||
return nil, gstatus.Errorf(codes.Unimplemented, "the management server, %s, does not support SSO providers, "+
|
||||
"please update your server or use Setup Keys to login", config.ManagementURL)
|
||||
} else {
|
||||
log.Errorf("getting device authorization flow info failed with error: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
hostedClient := internal.NewHostedDeviceFlow(
|
||||
providerConfig.ProviderConfig.Audience,
|
||||
providerConfig.ProviderConfig.ClientID,
|
||||
providerConfig.ProviderConfig.Domain,
|
||||
)
|
||||
|
||||
deviceAuthInfo, err := hostedClient.RequestDeviceCode(context.TODO())
|
||||
if err != nil {
|
||||
log.Errorf("getting a request device code failed: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.mutex.Lock()
|
||||
s.oauthClient = hostedClient
|
||||
s.deviceAuthInfo = deviceAuthInfo
|
||||
s.mutex.Unlock()
|
||||
|
||||
state.Set(internal.StatusNeedsLogin)
|
||||
|
||||
return &proto.LoginResponse{
|
||||
NeedsSSOLogin: true,
|
||||
VerificationURI: deviceAuthInfo.VerificationURI,
|
||||
VerificationURIComplete: deviceAuthInfo.VerificationURIComplete,
|
||||
UserCode: deviceAuthInfo.UserCode,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if err := internal.Login(ctx, s.config, msg.SetupKey, ""); err != nil {
|
||||
if s, ok := gstatus.FromError(err); ok && (s.Code() == codes.InvalidArgument || s.Code() == codes.PermissionDenied) {
|
||||
log.Warnf("failed login with known status: %v", err)
|
||||
state.Set(internal.StatusNeedsLogin)
|
||||
} else {
|
||||
log.Errorf("failed login: %v", err)
|
||||
state.Set(internal.StatusLoginFailed)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.LoginResponse{}, nil
|
||||
}
|
||||
|
||||
// WaitSSOLogin uses the userCode to validate the TokenInfo and
|
||||
// waits for the user to continue with the login on a browser
|
||||
func (s *Server) WaitSSOLogin(_ context.Context, msg *proto.WaitSSOLoginRequest) (*proto.WaitSSOLoginResponse, error) {
|
||||
s.mutex.Lock()
|
||||
if s.actCancel != nil {
|
||||
s.actCancel()
|
||||
}
|
||||
ctx, cancel := context.WithCancel(s.rootCtx)
|
||||
s.actCancel = cancel
|
||||
s.mutex.Unlock()
|
||||
|
||||
if s.oauthClient == nil {
|
||||
return nil, gstatus.Errorf(codes.Internal, "oauth client is not initialized")
|
||||
}
|
||||
|
||||
state := internal.CtxGetState(ctx)
|
||||
defer func() {
|
||||
s, err := state.Status()
|
||||
if err != nil || (s != internal.StatusNeedsLogin && s != internal.StatusLoginFailed) {
|
||||
state.Set(internal.StatusIdle)
|
||||
}
|
||||
}()
|
||||
|
||||
state.Set(internal.StatusConnecting)
|
||||
|
||||
s.mutex.Lock()
|
||||
deviceAuthInfo := s.deviceAuthInfo
|
||||
s.mutex.Unlock()
|
||||
|
||||
if deviceAuthInfo.UserCode != msg.UserCode {
|
||||
state.Set(internal.StatusLoginFailed)
|
||||
return nil, gstatus.Errorf(codes.InvalidArgument, "sso user code is invalid")
|
||||
}
|
||||
|
||||
waitTimeout := time.Duration(deviceAuthInfo.ExpiresIn)
|
||||
waitCTX, cancel := context.WithTimeout(ctx, waitTimeout*time.Second)
|
||||
defer cancel()
|
||||
|
||||
tokenInfo, err := s.oauthClient.WaitToken(waitCTX, deviceAuthInfo)
|
||||
if err != nil {
|
||||
state.Set(internal.StatusLoginFailed)
|
||||
log.Errorf("waiting for browser login failed: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := internal.Login(ctx, s.config, "", tokenInfo.AccessToken); err != nil {
|
||||
if s, ok := gstatus.FromError(err); ok && (s.Code() == codes.InvalidArgument || s.Code() == codes.PermissionDenied) {
|
||||
log.Warnf("failed login: %v", err)
|
||||
state.Set(internal.StatusNeedsLogin)
|
||||
} else {
|
||||
log.Errorf("failed login: %v", err)
|
||||
state.Set(internal.StatusLoginFailed)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.WaitSSOLoginResponse{}, nil
|
||||
}
|
||||
|
||||
// Up starts engine work in the daemon.
|
||||
func (s *Server) Up(_ context.Context, msg *proto.UpRequest) (*proto.UpResponse, error) {
|
||||
s.mutex.Lock()
|
||||
@ -136,7 +267,7 @@ func (s *Server) Up(_ context.Context, msg *proto.UpRequest) (*proto.UpResponse,
|
||||
return nil, fmt.Errorf("up already in progress: current status %s", status)
|
||||
}
|
||||
|
||||
// it should be nill here, but .
|
||||
// it should be nil here, but .
|
||||
if s.actCancel != nil {
|
||||
s.actCancel()
|
||||
}
|
||||
@ -157,7 +288,7 @@ func (s *Server) Up(_ context.Context, msg *proto.UpRequest) (*proto.UpResponse,
|
||||
return &proto.UpResponse{}, nil
|
||||
}
|
||||
|
||||
// Down dengine work in the daemon.
|
||||
// Down engine work in the daemon.
|
||||
func (s *Server) Down(ctx context.Context, msg *proto.DownRequest) (*proto.DownResponse, error) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
@ -187,10 +318,7 @@ func (s *Server) Status(
|
||||
}
|
||||
|
||||
// GetConfig of the daemon.
|
||||
func (s *Server) GetConfig(
|
||||
ctx context.Context,
|
||||
msg *proto.GetConfigRequest,
|
||||
) (*proto.GetConfigResponse, error) {
|
||||
func (s *Server) GetConfig(ctx context.Context, msg *proto.GetConfigRequest) (*proto.GetConfigResponse, error) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
@ -211,6 +339,7 @@ func (s *Server) GetConfig(
|
||||
if preSharedKey != "" {
|
||||
preSharedKey = "**********"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return &proto.GetConfigResponse{
|
||||
|
@ -210,6 +210,7 @@ func (s *serviceClient) getSettingsForm() *widget.Form {
|
||||
log.Errorf("login to management URL: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
s.wSettings.Close()
|
||||
},
|
||||
@ -219,6 +220,41 @@ func (s *serviceClient) getSettingsForm() *widget.Form {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *serviceClient) login() error {
|
||||
conn, err := s.getSrvClient(defaultFailTimeout)
|
||||
if err != nil {
|
||||
log.Errorf("get client: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
loginResp, err := conn.Login(s.ctx, &proto.LoginRequest{})
|
||||
if err != nil {
|
||||
log.Errorf("login to management URL with: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if loginResp.NeedsSSOLogin {
|
||||
err = open.Run(loginResp.VerificationURIComplete)
|
||||
if err != nil {
|
||||
log.Errorf("opening the verification uri in the browser failed: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = conn.WaitSSOLogin(s.ctx, &proto.WaitSSOLoginRequest{UserCode: loginResp.UserCode})
|
||||
if err != nil {
|
||||
log.Errorf("waiting sso login failed with: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := s.conn.Up(s.ctx, &proto.UpRequest{}); err != nil {
|
||||
log.Errorf("up service: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *serviceClient) menuUpClick() error {
|
||||
conn, err := s.getSrvClient(defaultFailTimeout)
|
||||
if err != nil {
|
||||
@ -232,6 +268,14 @@ func (s *serviceClient) menuUpClick() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if status.Status == string(internal.StatusNeedsLogin) || status.Status == string(internal.StatusLoginFailed) {
|
||||
err = s.login()
|
||||
if err != nil {
|
||||
log.Errorf("get service status: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if status.Status != string(internal.StatusIdle) {
|
||||
log.Warnf("already connected")
|
||||
return nil
|
||||
|
10
go.mod
10
go.mod
@ -29,21 +29,16 @@ require (
|
||||
|
||||
require (
|
||||
fyne.io/fyne/v2 v2.1.4
|
||||
github.com/99designs/keyring v1.2.1
|
||||
github.com/getlantern/systray v1.2.1
|
||||
github.com/magiconair/properties v1.8.5
|
||||
github.com/rs/xid v1.3.0
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/wiretrustee/wiretrustee v0.5.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
|
||||
github.com/BurntSushi/toml v0.4.1 // indirect
|
||||
github.com/danieljoos/wincred v1.1.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dvsekhvalnov/jose2go v1.5.0 // indirect
|
||||
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 // indirect
|
||||
@ -55,17 +50,14 @@ require (
|
||||
github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f // indirect
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be // indirect
|
||||
github.com/go-stack/stack v1.8.0 // indirect
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
|
||||
github.com/godbus/dbus/v5 v5.0.4 // indirect
|
||||
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 // indirect
|
||||
github.com/mdlayher/genetlink v1.1.0 // indirect
|
||||
github.com/mdlayher/netlink v1.4.2 // indirect
|
||||
github.com/mdlayher/socket v0.0.0-20211102153432-57e3fa563ecb // indirect
|
||||
github.com/mtibben/percent v0.2.1 // indirect
|
||||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
|
||||
github.com/pion/dtls/v2 v2.1.2 // indirect
|
||||
@ -84,13 +76,13 @@ require (
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect
|
||||
golang.org/x/mod v0.5.1 // indirect
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 // indirect
|
||||
golang.org/x/tools v0.1.8 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
golang.zx2c4.com/go118/netip v0.0.0-20211111135330-a4a02eeacf9d // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
|
19
go.sum
19
go.sum
@ -48,10 +48,6 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
fyne.io/fyne/v2 v2.1.4 h1:bt1+28++kAzRzPB0GM2EuSV4cnl8rXNX4cjfd8G06Rc=
|
||||
fyne.io/fyne/v2 v2.1.4/go.mod h1:p+E/Dh+wPW8JwR2DVcsZ9iXgR9ZKde80+Y+40Is54AQ=
|
||||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs=
|
||||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4=
|
||||
github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o=
|
||||
github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
|
||||
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
@ -103,13 +99,9 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0=
|
||||
github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM=
|
||||
github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
@ -165,8 +157,6 @@ github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEK
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0=
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
@ -253,8 +243,6 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU=
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0=
|
||||
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
|
||||
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@ -382,8 +370,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs=
|
||||
github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
@ -478,7 +464,6 @@ github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9 h1:m59mIOBO4kfcNCE
|
||||
github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
@ -497,8 +482,6 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7Zo
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/wiretrustee/ice/v2 v2.1.21-0.20220218121004-dc81faead4bb h1:CU1/+CEeCPvYXgfAyqTJXSQSf6hW3wsWM6Dfz6HkHEQ=
|
||||
github.com/wiretrustee/ice/v2 v2.1.21-0.20220218121004-dc81faead4bb/go.mod h1:XT1Nrb4OxbVFPffbQMbq4PaeEkpRLVzdphh3fjrw7DY=
|
||||
github.com/wiretrustee/wiretrustee v0.5.1 h1:mCuGOjsys5KgiLcRA38WYSwtyQ6YBPOZYquFz6EvTvk=
|
||||
github.com/wiretrustee/wiretrustee v0.5.1/go.mod h1:y6sXInx4Fur1pTfiZUNI+S73AEj1nvIiM1OJzCCK7z0=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@ -744,7 +727,6 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -761,7 +743,6 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a h1:ppl5mZgokTT8uPkmYOyEUmPTr3ypaKkg5eFOGrAmxxE=
|
||||
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -89,8 +89,6 @@ type ProviderConfig struct {
|
||||
// validateURL validates input http url
|
||||
func validateURL(httpURL string) bool {
|
||||
_, err := url.ParseRequestURI(httpURL)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
@ -203,6 +203,9 @@ func (s *Server) registerPeer(peerKey wgtypes.Key, req *proto.LoginRequest) (*Pe
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
if s, ok := status.FromError(err); ok && s.Code() == codes.FailedPrecondition {
|
||||
return nil, err
|
||||
}
|
||||
return nil, status.Errorf(codes.NotFound, "provided setup key doesn't exists")
|
||||
}
|
||||
|
||||
|
@ -262,7 +262,7 @@ func (am *DefaultAccountManager) AddPeer(setupKey string, userID string, peer *P
|
||||
}
|
||||
|
||||
if !sk.IsValid() {
|
||||
return nil, status.Errorf(codes.FailedPrecondition, "unable to register peer, setup key was expired or overused %s", upperKey)
|
||||
return nil, status.Errorf(codes.FailedPrecondition, "unable to register peer, its setup key is invalid (expired, overused or revoked)")
|
||||
}
|
||||
|
||||
} else if len(userID) != 0 {
|
||||
|
Loading…
Reference in New Issue
Block a user