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:
Maycon Santos 2022-05-12 11:17:24 +02:00 committed by GitHub
parent 49cca57565
commit e5c52efb4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 925 additions and 427 deletions

View File

@ -17,7 +17,7 @@ var downCmd = &cobra.Command{
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
SetFlagsFromEnvVars() SetFlagsFromEnvVars()
err := util.InitLog(logLevel, logFile) err := util.InitLog(logLevel, "console")
if err != nil { if err != nil {
log.Errorf("failed initializing log %v", err) log.Errorf("failed initializing log %v", err)
return err return err

View File

@ -3,10 +3,13 @@ package cmd
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/skratchdot/open-golang/open"
"google.golang.org/grpc/codes"
gstatus "google.golang.org/grpc/status"
"time"
"github.com/netbirdio/netbird/util" "github.com/netbirdio/netbird/util"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/netbirdio/netbird/client/internal" "github.com/netbirdio/netbird/client/internal"
@ -19,10 +22,9 @@ var loginCmd = &cobra.Command{
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
SetFlagsFromEnvVars() SetFlagsFromEnvVars()
err := util.InitLog(logLevel, logFile) err := util.InitLog(logLevel, "console")
if err != nil { if err != nil {
log.Errorf("failed initializing log %v", err) return fmt.Errorf("failed initializing log %v", err)
return err
} }
ctx := internal.CtxInitState(context.Background()) ctx := internal.CtxInitState(context.Background())
@ -31,45 +33,162 @@ var loginCmd = &cobra.Command{
if logFile == "console" { if logFile == "console" {
config, err := internal.GetConfig(managementURL, adminURL, configPath, preSharedKey) config, err := internal.GetConfig(managementURL, adminURL, configPath, preSharedKey)
if err != nil { if err != nil {
log.Errorf("get config file: %v", err) return fmt.Errorf("get config file: %v", err)
return 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 == "" { err = foregroundLogin(ctx, cmd, config, setupKey)
log.Error("setup key can't be empty") if err != nil {
return fmt.Errorf("empty setup key") return fmt.Errorf("foreground login failed: %v", err)
}
cmd.Println("Logging successfully")
return nil
} }
conn, err := DialClientGRPCServer(ctx, daemonAddr) conn, err := DialClientGRPCServer(ctx, daemonAddr)
if err != nil { if err != nil {
log.Errorf("failed to connect to service CLI interface %v", err) return fmt.Errorf("failed to connect to daemon error: %v\n"+
return err "If the daemon is not running please run: "+
"\nnetbird service install \nnetbird service start\n", err)
} }
defer conn.Close() defer conn.Close()
request := proto.LoginRequest{ client := proto.NewDaemonServiceClient(conn)
loginRequest := proto.LoginRequest{
SetupKey: setupKey, SetupKey: setupKey,
PreSharedKey: preSharedKey, PreSharedKey: preSharedKey,
ManagementUrl: managementURL, ManagementUrl: managementURL,
} }
client := proto.NewDaemonServiceClient(conn)
var loginErr error
var loginResp *proto.LoginResponse
err = WithBackOff(func() error { err = WithBackOff(func() error {
if _, err := client.Login(ctx, &request); err != nil { var backOffErr error
log.Errorf("try login: %v", err) 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 { 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")
}
}

View File

@ -30,12 +30,12 @@ var (
managementURL string managementURL string
adminURL string adminURL string
setupKey string setupKey string
jwtToken string
preSharedKey string preSharedKey string
rootCmd = &cobra.Command{ rootCmd = &cobra.Command{
Use: "wiretrustee", Use: "wiretrustee",
Short: "", Short: "",
Long: "", Long: "",
SilenceUsage: true,
} }
) )

View File

@ -47,7 +47,7 @@ func (p *program) Start(svc service.Service) error {
defer listen.Close() defer listen.Close()
if split[0] == "unix" { if split[0] == "unix" {
err = os.Chmod(split[1], 0o666) err = os.Chmod(split[1], 0666)
if err != nil { if err != nil {
log.Errorf("failed setting daemon permissions: %v", split[1]) log.Errorf("failed setting daemon permissions: %v", split[1])
return return
@ -56,7 +56,7 @@ func (p *program) Start(svc service.Service) error {
serverInstance := server.New(p.ctx, managementURL, adminURL, configPath, logFile) serverInstance := server.New(p.ctx, managementURL, adminURL, configPath, logFile)
if err := serverInstance.Start(); err != nil { 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) proto.RegisterDaemonServiceServer(p.serv, serverInstance)

View File

@ -24,6 +24,11 @@ var installCmd = &cobra.Command{
logLevel, logLevel,
} }
if managementURL != "" {
svcConfig.Arguments = append(svcConfig.Arguments, "--management-url")
svcConfig.Arguments = append(svcConfig.Arguments, managementURL)
}
if runtime.GOOS == "linux" { if runtime.GOOS == "linux" {
// Respected only by systemd systems // Respected only by systemd systems
svcConfig.Dependencies = []string{"After=network.target syslog.target"} svcConfig.Dependencies = []string{"After=network.target syslog.target"}

View File

@ -2,9 +2,9 @@ package cmd
import ( import (
"context" "context"
"fmt"
"github.com/netbirdio/netbird/util" "github.com/netbirdio/netbird/util"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
@ -20,26 +20,32 @@ var statusCmd = &cobra.Command{
err := util.InitLog(logLevel, "console") err := util.InitLog(logLevel, "console")
if err != nil { if err != nil {
log.Errorf("failed initializing log %v", err) return fmt.Errorf("failed initializing log %v", err)
return err
} }
ctx := internal.CtxInitState(context.Background()) ctx := internal.CtxInitState(context.Background())
conn, err := DialClientGRPCServer(ctx, daemonAddr) conn, err := DialClientGRPCServer(ctx, daemonAddr)
if err != nil { if err != nil {
log.Errorf("failed to connect to service CLI interface %v", err) return fmt.Errorf("failed to connect to daemon error: %v\n"+
return err "If the daemon is not running please run: "+
"\nnetbird service install \nnetbird service start\n", err)
} }
defer conn.Close() defer conn.Close()
resp, err := proto.NewDaemonServiceClient(conn).Status(cmd.Context(), &proto.StatusRequest{}) resp, err := proto.NewDaemonServiceClient(conn).Status(cmd.Context(), &proto.StatusRequest{})
if err != nil { if err != nil {
log.Errorf("status failed: %v", status.Convert(err).Message()) return fmt.Errorf("status failed: %v", status.Convert(err).Message())
return nil }
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 return nil
}, },
} }

View File

@ -2,13 +2,13 @@ package cmd
import ( import (
"context" "context"
"fmt"
"github.com/netbirdio/netbird/util"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/netbirdio/netbird/client/internal" "github.com/netbirdio/netbird/client/internal"
"github.com/netbirdio/netbird/client/proto" "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{ var upCmd = &cobra.Command{
@ -17,10 +17,9 @@ var upCmd = &cobra.Command{
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
SetFlagsFromEnvVars() SetFlagsFromEnvVars()
err := util.InitLog(logLevel, logFile) err := util.InitLog(logLevel, "console")
if err != nil { if err != nil {
log.Errorf("failed initializing log %v", err) return fmt.Errorf("failed initializing log %v", err)
return err
} }
ctx := internal.CtxInitState(cmd.Context()) ctx := internal.CtxInitState(cmd.Context())
@ -29,15 +28,12 @@ var upCmd = &cobra.Command{
if logFile == "console" { if logFile == "console" {
config, err := internal.GetConfig(managementURL, adminURL, configPath, preSharedKey) config, err := internal.GetConfig(managementURL, adminURL, configPath, preSharedKey)
if err != nil { if err != nil {
log.Errorf("get config file: %v", err) return fmt.Errorf("get config file: %v", err)
return err
} }
err = WithBackOff(func() error {
return internal.Login(ctx, config, setupKey, jwtToken) err = foregroundLogin(ctx, cmd, config, setupKey)
})
if err != nil { if err != nil {
log.Errorf("backoff cycle failed: %v", err) return fmt.Errorf("foreground login failed: %v", err)
return err
} }
var cancel context.CancelFunc var cancel context.CancelFunc
@ -48,43 +44,67 @@ var upCmd = &cobra.Command{
conn, err := DialClientGRPCServer(ctx, daemonAddr) conn, err := DialClientGRPCServer(ctx, daemonAddr)
if err != nil { if err != nil {
log.Errorf("failed to connect to service CLI interface %v", err) return fmt.Errorf("failed to connect to daemon error: %v\n"+
return err "If the daemon is not running please run: "+
"\nnetbird service install \nnetbird service start\n", err)
} }
defer conn.Close() defer conn.Close()
daemonClient := proto.NewDaemonServiceClient(conn) client := proto.NewDaemonServiceClient(conn)
loginRequest := proto.LoginRequest{ status, err := client.Status(ctx, &proto.StatusRequest{})
SetupKey: setupKey,
PreSharedKey: preSharedKey,
ManagementUrl: managementURL,
}
err = WithBackOff(func() error {
_, err := daemonClient.Login(ctx, &loginRequest)
return err
})
if err != nil { if err != nil {
log.Errorf("backoff cycle failed: %v", err) return fmt.Errorf("unable to get daemon status: %v", err)
return err
} }
status, err := daemonClient.Status(ctx, &proto.StatusRequest{}) if status.Status == string(internal.StatusNeedsLogin) || status.Status == string(internal.StatusLoginFailed) {
if err != nil { loginRequest := proto.LoginRequest{
log.Errorf("get status: %v", err) SetupKey: setupKey,
return err PreSharedKey: preSharedKey,
} ManagementUrl: managementURL,
}
if status.Status != string(internal.StatusIdle) { var loginErr error
log.Warnf("already connected")
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 return nil
} }
if _, err := daemonClient.Up(ctx, &proto.UpRequest{}); err != nil { if _, err := client.Up(ctx, &proto.UpRequest{}); err != nil {
log.Errorf("call service up method: %v", err) return fmt.Errorf("call service up method: %v", err)
return err
} }
cmd.Println("Connected")
return nil return nil
}, },
} }

View File

@ -1,7 +1,11 @@
package internal package internal
import ( import (
"context"
"fmt" "fmt"
mgm "github.com/netbirdio/netbird/management/client"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"net/url" "net/url"
"os" "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 // 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) { func ReadConfig(managementURL, adminURL, configPath string, preSharedKey *string) (*Config, error) {
config := &Config{} 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 { if _, err := util.ReadJson(configPath, config); err != nil {
return nil, err return nil, err
} }
@ -151,3 +159,77 @@ func generateKey() string {
} }
return key.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
}

View File

@ -29,7 +29,12 @@ func RunClient(ctx context.Context, config *Config) error {
} }
state := CtxGetState(ctx) state := CtxGetState(ctx)
defer state.Set(StatusIdle) defer func() {
s, err := state.Status()
if err != nil || s != StatusNeedsLogin {
state.Set(StatusIdle)
}
}()
wrapErr := state.Wrap wrapErr := state.Wrap
operation := func() error { 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) mgmClient, loginResp, err := connectToManagement(ctx, config.ManagementURL.Host, myPrivateKey, mgmTlsEnabled)
if err != nil { if err != nil {
log.Warn(err) log.Warn(err)
if s, ok := status.FromError(err); ok && s.Code() == codes.PermissionDenied {
state.Set(StatusNeedsLogin)
return nil
}
return wrapErr(err) return wrapErr(err)
} }

View File

@ -2,7 +2,6 @@ package internal
import ( import (
"context" "context"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/netbirdio/netbird/client/system" "github.com/netbirdio/netbird/client/system"
mgm "github.com/netbirdio/netbird/management/client" 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) { func registerPeer(serverPublicKey wgtypes.Key, client *mgm.GrpcClient, setupKey string, jwtToken string) (*mgmProto.LoginResponse, error) {
validSetupKey, err := uuid.Parse(setupKey) validSetupKey, err := uuid.Parse(setupKey)
if err != nil && jwtToken == "" { 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") log.Debugf("sending peer registration request to Management Service")
info := system.GetInfo() info := system.GetInfo()
loginResp, err := client.Register(serverPublicKey, validSetupKey.String(), jwtToken, info) loginResp, err := client.Register(serverPublicKey, validSetupKey.String(), jwtToken, info)
if err != nil { if err != nil {
log.Errorf("failed registering peer %v", err) log.Errorf("failed registering peer %v,%s", err, validSetupKey.String())
return nil, err return nil, err
} }

View File

@ -1,4 +1,4 @@
package oauth package internal
import ( import (
"context" "context"
@ -11,19 +11,50 @@ import (
"time" "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 ( const (
auth0GrantType = "urn:ietf:params:oauth:grant-type:device_code" HostedGrantType = "urn:ietf:params:oauth:grant-type:device_code"
auth0RefreshGrant = "refresh_token" HostedRefreshGrant = "refresh_token"
) )
// Auth0 client // Hosted client
type Auth0 struct { type Hosted struct {
// Auth0 API Audience for validation // Hosted API Audience for validation
Audience string Audience string
// Auth0 Native application client id // Hosted Native application client id
ClientID string ClientID string
// Auth0 domain // Hosted domain
Domain string Domain string
HTTPClient HTTPClient HTTPClient HTTPClient
@ -43,7 +74,7 @@ type TokenRequestPayload struct {
RefreshToken string `json:"refresh_token,omitempty"` 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 { type TokenRequestResponse struct {
Error string `json:"error"` Error string `json:"error"`
ErrorDescription string `json:"error_description"` ErrorDescription string `json:"error_description"`
@ -55,8 +86,8 @@ type Claims struct {
Audience string `json:"aud"` Audience string `json:"aud"`
} }
// NewAuth0DeviceFlow returns an Auth0 OAuth client // NewHostedDeviceFlow returns an Hosted OAuth client
func NewAuth0DeviceFlow(audience string, clientID string, domain string) *Auth0 { func NewHostedDeviceFlow(audience string, clientID string, domain string) *Hosted {
httpTransport := http.DefaultTransport.(*http.Transport).Clone() httpTransport := http.DefaultTransport.(*http.Transport).Clone()
httpTransport.MaxIdleConns = 5 httpTransport.MaxIdleConns = 5
@ -65,7 +96,7 @@ func NewAuth0DeviceFlow(audience string, clientID string, domain string) *Auth0
Transport: httpTransport, Transport: httpTransport,
} }
return &Auth0{ return &Hosted{
Audience: audience, Audience: audience,
ClientID: clientID, ClientID: clientID,
Domain: domain, 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 // RequestDeviceCode requests a device code login flow information from Hosted
func (a *Auth0) RequestDeviceCode(ctx context.Context) (DeviceAuthInfo, error) { func (h *Hosted) RequestDeviceCode(ctx context.Context) (DeviceAuthInfo, error) {
url := "https://" + a.Domain + "/oauth/device/code" url := "https://" + h.Domain + "/oauth/device/code"
codePayload := RequestDeviceCodePayload{ codePayload := RequestDeviceCodePayload{
Audience: a.Audience, Audience: h.Audience,
ClientID: a.ClientID, ClientID: h.ClientID,
} }
p, err := json.Marshal(codePayload) p, err := json.Marshal(codePayload)
if err != nil { if err != nil {
@ -92,7 +123,7 @@ func (a *Auth0) RequestDeviceCode(ctx context.Context) (DeviceAuthInfo, error) {
req.Header.Add("content-type", "application/json") req.Header.Add("content-type", "application/json")
res, err := a.HTTPClient.Do(req) res, err := h.HTTPClient.Do(req)
if err != nil { if err != nil {
return DeviceAuthInfo{}, fmt.Errorf("doing request failed with error: %v", err) 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 // 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 // it retrieves the access token from Hosted's endpoint and validates it before returning
func (a *Auth0) WaitToken(ctx context.Context, info DeviceAuthInfo) (TokenInfo, error) { func (h *Hosted) WaitToken(ctx context.Context, info DeviceAuthInfo) (TokenInfo, error) {
ticker := time.NewTicker(time.Duration(info.Interval) * time.Second) ticker := time.NewTicker(time.Duration(info.Interval) * time.Second)
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return TokenInfo{}, ctx.Err() return TokenInfo{}, ctx.Err()
case <-ticker.C: case <-ticker.C:
url := "https://" + a.Domain + "/oauth/token" url := "https://" + h.Domain + "/oauth/token"
tokenReqPayload := TokenRequestPayload{ tokenReqPayload := TokenRequestPayload{
GrantType: auth0GrantType, GrantType: HostedGrantType,
DeviceCode: info.DeviceCode, 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 { if err != nil {
return TokenInfo{}, fmt.Errorf("wait for token: %v", err) 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) return TokenInfo{}, fmt.Errorf(tokenResponse.ErrorDescription)
} }
err = isValidAccessToken(tokenResponse.AccessToken, a.Audience) err = isValidAccessToken(tokenResponse.AccessToken, h.Audience)
if err != nil { if err != nil {
return TokenInfo{}, fmt.Errorf("validate access token failed with error: %v", err) 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 // RotateAccessToken requests a new token using an existing refresh token
func (a *Auth0) RotateAccessToken(ctx context.Context, refreshToken string) (TokenInfo, error) { func (h *Hosted) RotateAccessToken(ctx context.Context, refreshToken string) (TokenInfo, error) {
url := "https://" + a.Domain + "/oauth/token" url := "https://" + h.Domain + "/oauth/token"
tokenReqPayload := TokenRequestPayload{ tokenReqPayload := TokenRequestPayload{
GrantType: auth0RefreshGrant, GrantType: HostedRefreshGrant,
ClientID: a.ClientID, ClientID: h.ClientID,
RefreshToken: refreshToken, RefreshToken: refreshToken,
} }
body, statusCode, err := requestToken(a.HTTPClient, url, tokenReqPayload) body, statusCode, err := requestToken(h.HTTPClient, url, tokenReqPayload)
if err != nil { if err != nil {
return TokenInfo{}, fmt.Errorf("rotate access token: %v", err) 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) 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 { if err != nil {
return TokenInfo{}, fmt.Errorf("validate access token failed with error: %v", err) return TokenInfo{}, fmt.Errorf("validate access token failed with error: %v", err)
} }

View File

@ -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)
}

View File

@ -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
}

View File

@ -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")
}

View File

@ -1,4 +1,4 @@
package oauth package internal
import ( import (
"context" "context"
@ -43,7 +43,7 @@ func (c *mockHTTPClient) Do(req *http.Request) (*http.Response, error) {
}, c.err }, c.err
} }
func TestAuth0_RequestDeviceCode(t *testing.T) { func TestHosted_RequestDeviceCode(t *testing.T) {
type test struct { type test struct {
name string name string
inputResBody string inputResBody string
@ -107,14 +107,14 @@ func TestAuth0_RequestDeviceCode(t *testing.T) {
err: testCase.inputReqError, err: testCase.inputReqError,
} }
auth0 := Auth0{ hosted := Hosted{
Audience: testCase.expectPayload.Audience, Audience: testCase.expectPayload.Audience,
ClientID: testCase.expectPayload.ClientID, ClientID: testCase.expectPayload.ClientID,
Domain: "test.auth0.com", Domain: "test.hosted.com",
HTTPClient: &httpClient, HTTPClient: &httpClient,
} }
authInfo, err := auth0.RequestDeviceCode(context.TODO()) authInfo, err := hosted.RequestDeviceCode(context.TODO())
testCase.testingErrFunc(t, err, testCase.expectedErrorMSG) testCase.testingErrFunc(t, err, testCase.expectedErrorMSG)
payload, _ := json.Marshal(testCase.expectPayload) 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 { type test struct {
name string name string
inputResBody string inputResBody string
@ -153,7 +153,7 @@ func TestAuth0_WaitToken(t *testing.T) {
} }
tokenReqPayload := TokenRequestPayload{ tokenReqPayload := TokenRequestPayload{
GrantType: auth0GrantType, GrantType: HostedGrantType,
DeviceCode: defaultInfo.DeviceCode, DeviceCode: defaultInfo.DeviceCode,
ClientID: "test", ClientID: "test",
} }
@ -267,16 +267,16 @@ func TestAuth0_WaitToken(t *testing.T) {
countResBody: testCase.inputCountResBody, countResBody: testCase.inputCountResBody,
} }
auth0 := Auth0{ hosted := Hosted{
Audience: testCase.inputAudience, Audience: testCase.inputAudience,
ClientID: testCase.expectPayload.ClientID, ClientID: testCase.expectPayload.ClientID,
Domain: "test.auth0.com", Domain: "test.hosted.com",
HTTPClient: &httpClient, HTTPClient: &httpClient,
} }
ctx, cancel := context.WithTimeout(context.TODO(), testCase.inputTimeout) ctx, cancel := context.WithTimeout(context.TODO(), testCase.inputTimeout)
defer cancel() defer cancel()
tokenInfo, err := auth0.WaitToken(ctx, testCase.inputInfo) tokenInfo, err := hosted.WaitToken(ctx, testCase.inputInfo)
testCase.testingErrFunc(t, err, testCase.expectedErrorMSG) testCase.testingErrFunc(t, err, testCase.expectedErrorMSG)
var payload []byte 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 { type test struct {
name string name string
inputResBody string inputResBody string
@ -318,7 +318,7 @@ func TestAuth0_RotateAccessToken(t *testing.T) {
} }
tokenReqPayload := TokenRequestPayload{ tokenReqPayload := TokenRequestPayload{
GrantType: auth0RefreshGrant, GrantType: HostedRefreshGrant,
ClientID: "test", ClientID: "test",
RefreshToken: "refresh_test", RefreshToken: "refresh_test",
} }
@ -391,14 +391,14 @@ func TestAuth0_RotateAccessToken(t *testing.T) {
MaxReqs: testCase.inputMaxReqs, MaxReqs: testCase.inputMaxReqs,
} }
auth0 := Auth0{ hosted := Hosted{
Audience: testCase.inputAudience, Audience: testCase.inputAudience,
ClientID: testCase.expectPayload.ClientID, ClientID: testCase.expectPayload.ClientID,
Domain: "test.auth0.com", Domain: "test.hosted.com",
HTTPClient: &httpClient, 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) testCase.testingErrFunc(t, err, testCase.expectedErrorMSG)
var payload []byte var payload []byte

View File

@ -10,8 +10,10 @@ type StatusType string
const ( const (
StatusIdle StatusType = "Idle" StatusIdle StatusType = "Idle"
StatusConnecting StatusType = "Connecting" StatusConnecting StatusType = "Connecting"
StatusConnected StatusType = "Connected" StatusConnected StatusType = "Connected"
StatusNeedsLogin StatusType = "NeedsLogin"
StatusLoginFailed StatusType = "LoginFailed"
) )
// CtxInitState setup context state into the context tree. // CtxInitState setup context state into the context tree.

View File

@ -34,8 +34,6 @@ type LoginRequest struct {
ManagementUrl string `protobuf:"bytes,3,opt,name=managementUrl,proto3" json:"managementUrl,omitempty"` ManagementUrl string `protobuf:"bytes,3,opt,name=managementUrl,proto3" json:"managementUrl,omitempty"`
// adminUrl to manage keys. // adminUrl to manage keys.
AdminURL string `protobuf:"bytes,4,opt,name=adminURL,proto3" json:"adminURL,omitempty"` 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() { func (x *LoginRequest) Reset() {
@ -98,17 +96,15 @@ func (x *LoginRequest) GetAdminURL() string {
return "" return ""
} }
func (x *LoginRequest) GetJwtToken() string {
if x != nil {
return x.JwtToken
}
return ""
}
type LoginResponse struct { type LoginResponse struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields 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() { func (x *LoginResponse) Reset() {
@ -143,6 +139,119 @@ func (*LoginResponse) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{1} 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 { type UpRequest struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -152,7 +261,7 @@ type UpRequest struct {
func (x *UpRequest) Reset() { func (x *UpRequest) Reset() {
*x = UpRequest{} *x = UpRequest{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[2] mi := &file_daemon_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -165,7 +274,7 @@ func (x *UpRequest) String() string {
func (*UpRequest) ProtoMessage() {} func (*UpRequest) ProtoMessage() {}
func (x *UpRequest) ProtoReflect() protoreflect.Message { func (x *UpRequest) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[2] mi := &file_daemon_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -178,7 +287,7 @@ func (x *UpRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use UpRequest.ProtoReflect.Descriptor instead. // Deprecated: Use UpRequest.ProtoReflect.Descriptor instead.
func (*UpRequest) Descriptor() ([]byte, []int) { func (*UpRequest) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{2} return file_daemon_proto_rawDescGZIP(), []int{4}
} }
type UpResponse struct { type UpResponse struct {
@ -190,7 +299,7 @@ type UpResponse struct {
func (x *UpResponse) Reset() { func (x *UpResponse) Reset() {
*x = UpResponse{} *x = UpResponse{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[3] mi := &file_daemon_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -203,7 +312,7 @@ func (x *UpResponse) String() string {
func (*UpResponse) ProtoMessage() {} func (*UpResponse) ProtoMessage() {}
func (x *UpResponse) ProtoReflect() protoreflect.Message { func (x *UpResponse) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[3] mi := &file_daemon_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -216,7 +325,7 @@ func (x *UpResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use UpResponse.ProtoReflect.Descriptor instead. // Deprecated: Use UpResponse.ProtoReflect.Descriptor instead.
func (*UpResponse) Descriptor() ([]byte, []int) { func (*UpResponse) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{3} return file_daemon_proto_rawDescGZIP(), []int{5}
} }
type StatusRequest struct { type StatusRequest struct {
@ -228,7 +337,7 @@ type StatusRequest struct {
func (x *StatusRequest) Reset() { func (x *StatusRequest) Reset() {
*x = StatusRequest{} *x = StatusRequest{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[4] mi := &file_daemon_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -241,7 +350,7 @@ func (x *StatusRequest) String() string {
func (*StatusRequest) ProtoMessage() {} func (*StatusRequest) ProtoMessage() {}
func (x *StatusRequest) ProtoReflect() protoreflect.Message { func (x *StatusRequest) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[4] mi := &file_daemon_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -254,7 +363,7 @@ func (x *StatusRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use StatusRequest.ProtoReflect.Descriptor instead. // Deprecated: Use StatusRequest.ProtoReflect.Descriptor instead.
func (*StatusRequest) Descriptor() ([]byte, []int) { func (*StatusRequest) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{4} return file_daemon_proto_rawDescGZIP(), []int{6}
} }
type StatusResponse struct { type StatusResponse struct {
@ -269,7 +378,7 @@ type StatusResponse struct {
func (x *StatusResponse) Reset() { func (x *StatusResponse) Reset() {
*x = StatusResponse{} *x = StatusResponse{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[5] mi := &file_daemon_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -282,7 +391,7 @@ func (x *StatusResponse) String() string {
func (*StatusResponse) ProtoMessage() {} func (*StatusResponse) ProtoMessage() {}
func (x *StatusResponse) ProtoReflect() protoreflect.Message { func (x *StatusResponse) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[5] mi := &file_daemon_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -295,7 +404,7 @@ func (x *StatusResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead. // Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead.
func (*StatusResponse) Descriptor() ([]byte, []int) { func (*StatusResponse) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{5} return file_daemon_proto_rawDescGZIP(), []int{7}
} }
func (x *StatusResponse) GetStatus() string { func (x *StatusResponse) GetStatus() string {
@ -314,7 +423,7 @@ type DownRequest struct {
func (x *DownRequest) Reset() { func (x *DownRequest) Reset() {
*x = DownRequest{} *x = DownRequest{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[6] mi := &file_daemon_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -327,7 +436,7 @@ func (x *DownRequest) String() string {
func (*DownRequest) ProtoMessage() {} func (*DownRequest) ProtoMessage() {}
func (x *DownRequest) ProtoReflect() protoreflect.Message { func (x *DownRequest) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[6] mi := &file_daemon_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -340,7 +449,7 @@ func (x *DownRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use DownRequest.ProtoReflect.Descriptor instead. // Deprecated: Use DownRequest.ProtoReflect.Descriptor instead.
func (*DownRequest) Descriptor() ([]byte, []int) { func (*DownRequest) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{6} return file_daemon_proto_rawDescGZIP(), []int{8}
} }
type DownResponse struct { type DownResponse struct {
@ -352,7 +461,7 @@ type DownResponse struct {
func (x *DownResponse) Reset() { func (x *DownResponse) Reset() {
*x = DownResponse{} *x = DownResponse{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[7] mi := &file_daemon_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -365,7 +474,7 @@ func (x *DownResponse) String() string {
func (*DownResponse) ProtoMessage() {} func (*DownResponse) ProtoMessage() {}
func (x *DownResponse) ProtoReflect() protoreflect.Message { func (x *DownResponse) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[7] mi := &file_daemon_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -378,7 +487,7 @@ func (x *DownResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use DownResponse.ProtoReflect.Descriptor instead. // Deprecated: Use DownResponse.ProtoReflect.Descriptor instead.
func (*DownResponse) Descriptor() ([]byte, []int) { func (*DownResponse) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{7} return file_daemon_proto_rawDescGZIP(), []int{9}
} }
type GetConfigRequest struct { type GetConfigRequest struct {
@ -390,7 +499,7 @@ type GetConfigRequest struct {
func (x *GetConfigRequest) Reset() { func (x *GetConfigRequest) Reset() {
*x = GetConfigRequest{} *x = GetConfigRequest{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[8] mi := &file_daemon_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -403,7 +512,7 @@ func (x *GetConfigRequest) String() string {
func (*GetConfigRequest) ProtoMessage() {} func (*GetConfigRequest) ProtoMessage() {}
func (x *GetConfigRequest) ProtoReflect() protoreflect.Message { func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[8] mi := &file_daemon_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -416,7 +525,7 @@ func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetConfigRequest.ProtoReflect.Descriptor instead. // Deprecated: Use GetConfigRequest.ProtoReflect.Descriptor instead.
func (*GetConfigRequest) Descriptor() ([]byte, []int) { func (*GetConfigRequest) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{8} return file_daemon_proto_rawDescGZIP(), []int{10}
} }
type GetConfigResponse struct { type GetConfigResponse struct {
@ -439,7 +548,7 @@ type GetConfigResponse struct {
func (x *GetConfigResponse) Reset() { func (x *GetConfigResponse) Reset() {
*x = GetConfigResponse{} *x = GetConfigResponse{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[9] mi := &file_daemon_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -452,7 +561,7 @@ func (x *GetConfigResponse) String() string {
func (*GetConfigResponse) ProtoMessage() {} func (*GetConfigResponse) ProtoMessage() {}
func (x *GetConfigResponse) ProtoReflect() protoreflect.Message { func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[9] mi := &file_daemon_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -465,7 +574,7 @@ func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetConfigResponse.ProtoReflect.Descriptor instead. // Deprecated: Use GetConfigResponse.ProtoReflect.Descriptor instead.
func (*GetConfigResponse) Descriptor() ([]byte, []int) { func (*GetConfigResponse) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{9} return file_daemon_proto_rawDescGZIP(), []int{11}
} }
func (x *GetConfigResponse) GetManagementUrl() string { 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x09, 0x52, 0x08, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x52, 0x4c, 0x22, 0xb5, 0x01, 0x0a, 0x0d,
0x77, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6a, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a,
0x77, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x0f, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x0d, 0x6e, 0x65, 0x65, 0x64, 0x73, 0x53, 0x53, 0x4f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x01,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0b, 0x0a, 0x09, 0x55, 0x70, 0x52, 0x65, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6e, 0x65, 0x65, 0x64, 0x73, 0x53, 0x53, 0x4f, 0x4c, 0x6f,
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x0c, 0x0a, 0x0a, 0x55, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18,
0x6e, 0x73, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12,
0x75, 0x65, 0x73, 0x74, 0x22, 0x28, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x28, 0x0a, 0x0f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x49, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x0d, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x52, 0x49, 0x12, 0x38, 0x0a, 0x17, 0x76, 0x65, 0x72,
0x0a, 0x0b, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x0e, 0x0a, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x52, 0x49, 0x43, 0x6f, 0x6d, 0x70,
0x0c, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x0a, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x76, 0x65, 0x72, 0x69,
0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x52, 0x49, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
0x74, 0x22, 0xb3, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x74, 0x65, 0x22, 0x31, 0x0a, 0x13, 0x57, 0x61, 0x69, 0x74, 0x53, 0x53, 0x4f, 0x4c, 0x6f,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73,
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73,
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x1e, 0x0a, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x57, 0x61, 0x69, 0x74, 0x53, 0x53,
0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x4f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0b,
0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x0a, 0x09, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x0c, 0x0a, 0x0a, 0x55,
0x07, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61,
0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x53, 0x68, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x28, 0x0a, 0x0e, 0x53, 0x74,
0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06,
0x72, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74,
0x64, 0x6d, 0x69, 0x6e, 0x55, 0x52, 0x4c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x61, 0x74, 0x75, 0x73, 0x22, 0x0d, 0x0a, 0x0b, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75,
0x64, 0x6d, 0x69, 0x6e, 0x55, 0x52, 0x4c, 0x32, 0xaa, 0x02, 0x0a, 0x0d, 0x44, 0x61, 0x65, 0x6d, 0x65, 0x73, 0x74, 0x22, 0x0e, 0x0a, 0x0c, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x69, 0x6e, 0x12, 0x14, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb3, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a,
0x6e, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x72, 0x6c, 0x18, 0x01,
0x00, 0x12, 0x2d, 0x0a, 0x02, 0x55, 0x70, 0x12, 0x11, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
0x2e, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x61, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, 0x6c,
0x6d, 0x6f, 0x6e, 0x2e, 0x55, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46,
0x12, 0x39, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x15, 0x2e, 0x64, 0x61, 0x65, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x03,
0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x0a,
0x74, 0x1a, 0x16, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x0c, 0x70, 0x72, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x04, 0x44, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65,
0x6f, 0x77, 0x6e, 0x12, 0x13, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x6f, 0x77, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x52, 0x4c, 0x18, 0x05, 0x20,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x52, 0x4c, 0x32, 0xf7, 0x02,
0x6e, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x0a, 0x0d, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
0x12, 0x42, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x2e, 0x36, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x14, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f,
0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x6e, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73,
0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0c, 0x57, 0x61, 0x69, 0x74, 0x53,
0x73, 0x65, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x53, 0x4f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1b, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 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 ( var (
@ -576,35 +703,39 @@ func file_daemon_proto_rawDescGZIP() []byte {
return file_daemon_proto_rawDescData 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{}{ var file_daemon_proto_goTypes = []interface{}{
(*LoginRequest)(nil), // 0: daemon.LoginRequest (*LoginRequest)(nil), // 0: daemon.LoginRequest
(*LoginResponse)(nil), // 1: daemon.LoginResponse (*LoginResponse)(nil), // 1: daemon.LoginResponse
(*UpRequest)(nil), // 2: daemon.UpRequest (*WaitSSOLoginRequest)(nil), // 2: daemon.WaitSSOLoginRequest
(*UpResponse)(nil), // 3: daemon.UpResponse (*WaitSSOLoginResponse)(nil), // 3: daemon.WaitSSOLoginResponse
(*StatusRequest)(nil), // 4: daemon.StatusRequest (*UpRequest)(nil), // 4: daemon.UpRequest
(*StatusResponse)(nil), // 5: daemon.StatusResponse (*UpResponse)(nil), // 5: daemon.UpResponse
(*DownRequest)(nil), // 6: daemon.DownRequest (*StatusRequest)(nil), // 6: daemon.StatusRequest
(*DownResponse)(nil), // 7: daemon.DownResponse (*StatusResponse)(nil), // 7: daemon.StatusResponse
(*GetConfigRequest)(nil), // 8: daemon.GetConfigRequest (*DownRequest)(nil), // 8: daemon.DownRequest
(*GetConfigResponse)(nil), // 9: daemon.GetConfigResponse (*DownResponse)(nil), // 9: daemon.DownResponse
(*GetConfigRequest)(nil), // 10: daemon.GetConfigRequest
(*GetConfigResponse)(nil), // 11: daemon.GetConfigResponse
} }
var file_daemon_proto_depIdxs = []int32{ var file_daemon_proto_depIdxs = []int32{
0, // 0: daemon.DaemonService.Login:input_type -> daemon.LoginRequest 0, // 0: daemon.DaemonService.Login:input_type -> daemon.LoginRequest
2, // 1: daemon.DaemonService.Up:input_type -> daemon.UpRequest 2, // 1: daemon.DaemonService.WaitSSOLogin:input_type -> daemon.WaitSSOLoginRequest
4, // 2: daemon.DaemonService.Status:input_type -> daemon.StatusRequest 4, // 2: daemon.DaemonService.Up:input_type -> daemon.UpRequest
6, // 3: daemon.DaemonService.Down:input_type -> daemon.DownRequest 6, // 3: daemon.DaemonService.Status:input_type -> daemon.StatusRequest
8, // 4: daemon.DaemonService.GetConfig:input_type -> daemon.GetConfigRequest 8, // 4: daemon.DaemonService.Down:input_type -> daemon.DownRequest
1, // 5: daemon.DaemonService.Login:output_type -> daemon.LoginResponse 10, // 5: daemon.DaemonService.GetConfig:input_type -> daemon.GetConfigRequest
3, // 6: daemon.DaemonService.Up:output_type -> daemon.UpResponse 1, // 6: daemon.DaemonService.Login:output_type -> daemon.LoginResponse
5, // 7: daemon.DaemonService.Status:output_type -> daemon.StatusResponse 3, // 7: daemon.DaemonService.WaitSSOLogin:output_type -> daemon.WaitSSOLoginResponse
7, // 8: daemon.DaemonService.Down:output_type -> daemon.DownResponse 5, // 8: daemon.DaemonService.Up:output_type -> daemon.UpResponse
9, // 9: daemon.DaemonService.GetConfig:output_type -> daemon.GetConfigResponse 7, // 9: daemon.DaemonService.Status:output_type -> daemon.StatusResponse
5, // [5:10] is the sub-list for method output_type 9, // 10: daemon.DaemonService.Down:output_type -> daemon.DownResponse
0, // [0:5] is the sub-list for method input_type 11, // 11: daemon.DaemonService.GetConfig:output_type -> daemon.GetConfigResponse
0, // [0:0] is the sub-list for extension type_name 6, // [6:12] is the sub-list for method output_type
0, // [0:0] is the sub-list for extension extendee 0, // [0:6] is the sub-list for method input_type
0, // [0:0] is the sub-list for field type_name 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() } 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{} { file_daemon_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpRequest); i { switch v := v.(*WaitSSOLoginRequest); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -650,7 +781,7 @@ func file_daemon_proto_init() {
} }
} }
file_daemon_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { file_daemon_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpResponse); i { switch v := v.(*WaitSSOLoginResponse); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -662,7 +793,7 @@ func file_daemon_proto_init() {
} }
} }
file_daemon_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { file_daemon_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*StatusRequest); i { switch v := v.(*UpRequest); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -674,7 +805,7 @@ func file_daemon_proto_init() {
} }
} }
file_daemon_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { file_daemon_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*StatusResponse); i { switch v := v.(*UpResponse); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -686,7 +817,7 @@ func file_daemon_proto_init() {
} }
} }
file_daemon_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { file_daemon_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DownRequest); i { switch v := v.(*StatusRequest); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -698,7 +829,7 @@ func file_daemon_proto_init() {
} }
} }
file_daemon_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { file_daemon_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DownResponse); i { switch v := v.(*StatusResponse); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -710,7 +841,7 @@ func file_daemon_proto_init() {
} }
} }
file_daemon_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { file_daemon_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetConfigRequest); i { switch v := v.(*DownRequest); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -722,6 +853,30 @@ func file_daemon_proto_init() {
} }
} }
file_daemon_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { 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 { switch v := v.(*GetConfigResponse); i {
case 0: case 0:
return &v.state return &v.state
@ -740,7 +895,7 @@ func file_daemon_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_daemon_proto_rawDesc, RawDescriptor: file_daemon_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 10, NumMessages: 12,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },

View File

@ -10,6 +10,10 @@ service DaemonService {
// Login uses setup key to prepare configuration for the daemon. // Login uses setup key to prepare configuration for the daemon.
rpc Login(LoginRequest) returns (LoginResponse) {} 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. // Up starts engine work in the daemon.
rpc Up(UpRequest) returns (UpResponse) {} rpc Up(UpRequest) returns (UpResponse) {}
@ -36,11 +40,20 @@ message LoginRequest {
// adminUrl to manage keys. // adminUrl to manage keys.
string adminURL = 4; 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 {} message UpRequest {}

View File

@ -20,6 +20,9 @@ const _ = grpc.SupportPackageIsVersion7
type DaemonServiceClient interface { type DaemonServiceClient interface {
// Login uses setup key to prepare configuration for the daemon. // Login uses setup key to prepare configuration for the daemon.
Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) 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 starts engine work in the daemon.
Up(ctx context.Context, in *UpRequest, opts ...grpc.CallOption) (*UpResponse, error) Up(ctx context.Context, in *UpRequest, opts ...grpc.CallOption) (*UpResponse, error)
// Status of the service. // Status of the service.
@ -47,6 +50,15 @@ func (c *daemonServiceClient) Login(ctx context.Context, in *LoginRequest, opts
return out, nil 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) { func (c *daemonServiceClient) Up(ctx context.Context, in *UpRequest, opts ...grpc.CallOption) (*UpResponse, error) {
out := new(UpResponse) out := new(UpResponse)
err := c.cc.Invoke(ctx, "/daemon.DaemonService/Up", in, out, opts...) 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 { type DaemonServiceServer interface {
// Login uses setup key to prepare configuration for the daemon. // Login uses setup key to prepare configuration for the daemon.
Login(context.Context, *LoginRequest) (*LoginResponse, error) 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 starts engine work in the daemon.
Up(context.Context, *UpRequest) (*UpResponse, error) Up(context.Context, *UpRequest) (*UpResponse, error)
// Status of the service. // Status of the service.
@ -107,6 +122,9 @@ type UnimplementedDaemonServiceServer struct {
func (UnimplementedDaemonServiceServer) Login(context.Context, *LoginRequest) (*LoginResponse, error) { func (UnimplementedDaemonServiceServer) Login(context.Context, *LoginRequest) (*LoginResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Login not implemented") 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) { func (UnimplementedDaemonServiceServer) Up(context.Context, *UpRequest) (*UpResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Up not implemented") 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) 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) { func _DaemonService_Up_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpRequest) in := new(UpRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
@ -233,6 +269,10 @@ var DaemonService_ServiceDesc = grpc.ServiceDesc{
MethodName: "Login", MethodName: "Login",
Handler: _DaemonService_Login_Handler, Handler: _DaemonService_Login_Handler,
}, },
{
MethodName: "WaitSSOLogin",
Handler: _DaemonService_WaitSSOLogin_Handler,
},
{ {
MethodName: "Up", MethodName: "Up",
Handler: _DaemonService_Up_Handler, Handler: _DaemonService_Up_Handler,

View File

@ -3,7 +3,10 @@ package server
import ( import (
"context" "context"
"fmt" "fmt"
"google.golang.org/grpc/codes"
gstatus "google.golang.org/grpc/status"
"sync" "sync"
"time"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -21,6 +24,9 @@ type Server struct {
configPath string configPath string
logFile string logFile string
oauthClient internal.OAuthClient
deviceAuthInfo internal.DeviceAuthInfo
mutex sync.Mutex mutex sync.Mutex
config *internal.Config config *internal.Config
proto.UnimplementedDaemonServiceServer proto.UnimplementedDaemonServiceServer
@ -42,7 +48,7 @@ func (s *Server) Start() error {
// if current state contains any error, return it // 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 // 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() status, err := state.Status()
if err != nil { if err != nil {
return err return err
@ -55,12 +61,24 @@ func (s *Server) Start() error {
ctx, cancel := context.WithCancel(s.rootCtx) ctx, cancel := context.WithCancel(s.rootCtx)
s.actCancel = cancel 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) config, err := internal.ReadConfig(s.managementURL, s.adminURL, s.configPath, nil)
if err != nil { if errorStatus, ok := gstatus.FromError(err); ok && errorStatus.Code() == codes.NotFound {
log.Warnf("no config file, skip connection stage: %v", err) 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 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 s.config = config
go func() { go func() {
@ -83,7 +101,12 @@ func (s *Server) Login(_ context.Context, msg *proto.LoginRequest) (*proto.Login
s.mutex.Unlock() s.mutex.Unlock()
state := internal.CtxGetState(ctx) 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) state.Set(internal.StatusConnecting)
@ -108,16 +131,124 @@ func (s *Server) Login(_ context.Context, msg *proto.LoginRequest) (*proto.Login
s.config = config s.config = config
s.mutex.Unlock() s.mutex.Unlock()
// login operation uses backoff scheme to connect to management API if msg.SetupKey == "" {
// we don't wait for result and return response immediately. providerConfig, err := internal.GetDeviceAuthorizationFlowInfo(ctx, config)
if err := internal.Login(ctx, s.config, msg.SetupKey, msg.JwtToken); err != nil { if err != nil {
log.Errorf("failed login: %v", err) 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 nil, err
} }
return &proto.LoginResponse{}, nil 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. // Up starts engine work in the daemon.
func (s *Server) Up(_ context.Context, msg *proto.UpRequest) (*proto.UpResponse, error) { func (s *Server) Up(_ context.Context, msg *proto.UpRequest) (*proto.UpResponse, error) {
s.mutex.Lock() 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) 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 { if s.actCancel != nil {
s.actCancel() s.actCancel()
} }
@ -157,7 +288,7 @@ func (s *Server) Up(_ context.Context, msg *proto.UpRequest) (*proto.UpResponse,
return &proto.UpResponse{}, nil 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) { func (s *Server) Down(ctx context.Context, msg *proto.DownRequest) (*proto.DownResponse, error) {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
@ -187,10 +318,7 @@ func (s *Server) Status(
} }
// GetConfig of the daemon. // GetConfig of the daemon.
func (s *Server) GetConfig( func (s *Server) GetConfig(ctx context.Context, msg *proto.GetConfigRequest) (*proto.GetConfigResponse, error) {
ctx context.Context,
msg *proto.GetConfigRequest,
) (*proto.GetConfigResponse, error) {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
@ -211,6 +339,7 @@ func (s *Server) GetConfig(
if preSharedKey != "" { if preSharedKey != "" {
preSharedKey = "**********" preSharedKey = "**********"
} }
} }
return &proto.GetConfigResponse{ return &proto.GetConfigResponse{

View File

@ -210,6 +210,7 @@ func (s *serviceClient) getSettingsForm() *widget.Form {
log.Errorf("login to management URL: %v", err) log.Errorf("login to management URL: %v", err)
return return
} }
} }
s.wSettings.Close() 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 { func (s *serviceClient) menuUpClick() error {
conn, err := s.getSrvClient(defaultFailTimeout) conn, err := s.getSrvClient(defaultFailTimeout)
if err != nil { if err != nil {
@ -232,6 +268,14 @@ func (s *serviceClient) menuUpClick() error {
return err 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) { if status.Status != string(internal.StatusIdle) {
log.Warnf("already connected") log.Warnf("already connected")
return nil return nil

10
go.mod
View File

@ -29,21 +29,16 @@ require (
require ( require (
fyne.io/fyne/v2 v2.1.4 fyne.io/fyne/v2 v2.1.4
github.com/99designs/keyring v1.2.1
github.com/getlantern/systray v1.2.1 github.com/getlantern/systray v1.2.1
github.com/magiconair/properties v1.8.5 github.com/magiconair/properties v1.8.5
github.com/rs/xid v1.3.0 github.com/rs/xid v1.3.0
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/wiretrustee/wiretrustee v0.5.1
) )
require ( require (
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/BurntSushi/toml v0.4.1 // 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/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/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 // 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/gl v0.0.0-20210813123233-e4099ee2221f // indirect
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be // 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/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/godbus/dbus/v5 v5.0.4 // indirect
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff // indirect github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff // indirect
github.com/google/go-cmp v0.5.6 // 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/inconshreveable/mousetrap v1.0.0 // indirect
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 // indirect github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 // indirect
github.com/mdlayher/genetlink v1.1.0 // indirect github.com/mdlayher/genetlink v1.1.0 // indirect
github.com/mdlayher/netlink v1.4.2 // indirect github.com/mdlayher/netlink v1.4.2 // indirect
github.com/mdlayher/socket v0.0.0-20211102153432-57e3fa563ecb // 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/nxadm/tail v1.4.8 // indirect
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
github.com/pion/dtls/v2 v2.1.2 // 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/image v0.0.0-20200430140353-33d19683fad8 // indirect
golang.org/x/mod v0.5.1 // indirect golang.org/x/mod v0.5.1 // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // 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/text v0.3.8-0.20211105212822-18b340fc7af2 // indirect
golang.org/x/tools v0.1.8 // indirect golang.org/x/tools v0.1.8 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // 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/go118/netip v0.0.0-20211111135330-a4a02eeacf9d // indirect
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // 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/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect

19
go.sum
View File

@ -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= 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 h1:bt1+28++kAzRzPB0GM2EuSV4cnl8rXNX4cjfd8G06Rc=
fyne.io/fyne/v2 v2.1.4/go.mod h1:p+E/Dh+wPW8JwR2DVcsZ9iXgR9ZKde80+Y+40Is54AQ= 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.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= 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/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.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/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.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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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.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.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 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 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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/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 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 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= 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 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 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/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/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/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 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 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.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 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/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/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= 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/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.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.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.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 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/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 h1:CU1/+CEeCPvYXgfAyqTJXSQSf6hW3wsWM6Dfz6HkHEQ=
github.com/wiretrustee/ice/v2 v2.1.21-0.20220218121004-dc81faead4bb/go.mod h1:XT1Nrb4OxbVFPffbQMbq4PaeEkpRLVzdphh3fjrw7DY= 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.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/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= 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-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-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-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-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-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/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 h1:ppl5mZgokTT8uPkmYOyEUmPTr3ypaKkg5eFOGrAmxxE=
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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-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/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.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -89,8 +89,6 @@ type ProviderConfig struct {
// validateURL validates input http url // validateURL validates input http url
func validateURL(httpURL string) bool { func validateURL(httpURL string) bool {
_, err := url.ParseRequestURI(httpURL) _, err := url.ParseRequestURI(httpURL)
if err != nil {
return false return err == nil
}
return true
} }

View File

@ -203,6 +203,9 @@ func (s *Server) registerPeer(peerKey wgtypes.Key, req *proto.LoginRequest) (*Pe
}, },
}) })
if err != nil { 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") return nil, status.Errorf(codes.NotFound, "provided setup key doesn't exists")
} }

View File

@ -262,7 +262,7 @@ func (am *DefaultAccountManager) AddPeer(setupKey string, userID string, peer *P
} }
if !sk.IsValid() { 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 { } else if len(userID) != 0 {