From 5af078092e6859ea37a0f673a9ed81d143388d7d Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Thu, 4 Jan 2024 21:53:38 +0100 Subject: [PATCH] Add api-key based login --- agent/actions/actions.go | 21 ++++-- agent/actions/config.go | 34 ++++++++++ agent/actions/login.go | 4 +- agent/bitwarden/auth.go | 139 ++++++++++++++++++++++++++++++++------- agent/config/config.go | 80 ++++++++++++++++++++++ agent/unixsocketagent.go | 3 +- cmd/config.go | 68 +++++++++++++++++++ go.mod | 15 +---- go.sum | 22 +------ ipc/messages/config.go | 26 ++++++++ 10 files changed, 349 insertions(+), 63 deletions(-) diff --git a/agent/actions/actions.go b/agent/actions/actions.go index 7fa2ab8..5209778 100644 --- a/agent/actions/actions.go +++ b/agent/actions/actions.go @@ -51,7 +51,11 @@ func sync(ctx context.Context, vault *vault.Vault, cfg *config.Config) bool { token, err := cfg.GetToken() if err == nil { if token.AccessToken != "" { - bitwarden.RefreshToken(ctx, cfg) + refreshed := bitwarden.RefreshToken(ctx, cfg) + if !refreshed { + return false + } + userSymmetricKey, err := cfg.GetUserSymmetricKey() if err != nil { return false @@ -83,10 +87,17 @@ func ensureIsNotLocked(action Action) Action { ctx1 := context.Background() success := sync(ctx1, vault, cfg) if err != nil || !success { - return messages.IPCMessageFromPayload(messages.ActionResponse{ - Success: false, - Message: err.Error(), - }) + if err != nil { + return messages.IPCMessageFromPayload(messages.ActionResponse{ + Success: false, + Message: err.Error(), + }) + } else { + return messages.IPCMessageFromPayload(messages.ActionResponse{ + Success: false, + Message: "Could not sync vault", + }) + } } systemauth.CreatePinSession(*ctx) diff --git a/agent/actions/config.go b/agent/actions/config.go index 673af52..9f06fad 100644 --- a/agent/actions/config.go +++ b/agent/actions/config.go @@ -55,6 +55,38 @@ func handleSetNotifications(request messages.IPCMessage, cfg *config.Config, vau }) } +func handleSetClientID(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response messages.IPCMessage, err error) { + clientID := messages.ParsePayload(request).(messages.SetClientIDRequest).Value + cfg.SetClientID(clientID) + err = cfg.WriteConfig() + if err != nil { + return messages.IPCMessageFromPayload(messages.ActionResponse{ + Success: false, + Message: err.Error(), + }) + } + + return messages.IPCMessageFromPayload(messages.ActionResponse{ + Success: true, + }) +} + +func handleSetClientSecret(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response messages.IPCMessage, err error) { + clientSecret := messages.ParsePayload(request).(messages.SetClientSecretRequest).Value + cfg.SetClientSecret(clientSecret) + err = cfg.WriteConfig() + if err != nil { + return messages.IPCMessageFromPayload(messages.ActionResponse{ + Success: false, + Message: err.Error(), + }) + } + + return messages.IPCMessageFromPayload(messages.ActionResponse{ + Success: true, + }) +} + func handleGetRuntimeConfig(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response messages.IPCMessage, err error) { return messages.IPCMessageFromPayload(messages.GetRuntimeConfigResponse{ UseMemguard: cfg.ConfigFile.RuntimeConfig.UseMemguard, @@ -68,4 +100,6 @@ func init() { AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.SetApiURLRequest{}), handleSetApiURL) AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.SetNotificationsURLRequest{}), handleSetNotifications) AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.GetRuntimeConfigRequest{}), handleGetRuntimeConfig) + AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.SetClientIDRequest{}), handleSetClientID) + AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.SetClientSecretRequest{}), handleSetClientSecret) } diff --git a/agent/actions/login.go b/agent/actions/login.go index dbe50de..b13fcf3 100644 --- a/agent/actions/login.go +++ b/agent/actions/login.go @@ -32,7 +32,9 @@ func handleLogin(msg messages.IPCMessage, cfg *config.Config, vault *vault.Vault var masterKey crypto.MasterKey var masterpasswordHash string - if req.Passwordless { + if secret, err := cfg.GetClientSecret(); err == nil && secret != "" { + token, masterKey, masterpasswordHash, err = bitwarden.LoginWithApiKey(ctx, req.Email, cfg, vault) + } else if req.Passwordless { token, masterKey, masterpasswordHash, err = bitwarden.LoginWithDevice(ctx, req.Email, cfg, vault) } else { token, masterKey, masterpasswordHash, err = bitwarden.LoginWithMasterpassword(ctx, req.Email, cfg, vault) diff --git a/agent/bitwarden/auth.go b/agent/bitwarden/auth.go index c683131..42fa643 100644 --- a/agent/bitwarden/auth.go +++ b/agent/bitwarden/auth.go @@ -38,11 +38,15 @@ type preLoginResponse struct { } type LoginResponseToken struct { - AccessToken string `json:"access_token"` - ExpiresIn int `json:"expires_in"` - TokenType string `json:"token_type"` - RefreshToken string `json:"refresh_token"` - Key string `json:"key"` + AccessToken string `json:"access_token"` + ExpiresIn int `json:"expires_in"` + TokenType string `json:"token_type"` + RefreshToken string `json:"refresh_token"` + Key string `json:"key"` + Kdf int `json:"Kdf"` + KdfIterations int `json:"KdfIterations"` + KdfMemory int `json:"KdfMemory"` + KdfParallelism int `json:"KdfParallelism"` } const ( @@ -64,6 +68,52 @@ func deviceType() string { } } +func LoginWithApiKey(ctx context.Context, email string, cfg *config.Config, vault *vault.Vault) (LoginResponseToken, crypto.MasterKey, string, error) { + clientID, err := cfg.GetClientID() + if err != nil { + notify.Notify("Goldwarden", fmt.Sprintf("Could not get client ID: %v", err), "", func() {}) + return LoginResponseToken{}, crypto.MasterKey{}, "", fmt.Errorf("could not get client ID: %v", err) + } + clientSecret, err := cfg.GetClientSecret() + if err != nil { + notify.Notify("Goldwarden", fmt.Sprintf("Could not get client secret: %v", err), "", func() {}) + return LoginResponseToken{}, crypto.MasterKey{}, "", fmt.Errorf("could not get client secret: %v", err) + } + + values := urlValues( + "client_id", clientID, + "client_secret", clientSecret, + "scope", loginApiKeyScope, + "grant_type", "client_credentials", + "deviceType", deviceType(), + "deviceName", deviceName, + "deviceIdentifier", cfg.ConfigFile.DeviceUUID, + ) + + var loginResponseToken LoginResponseToken + err = authenticatedHTTPPost(ctx, cfg.ConfigFile.IdentityUrl+"/connect/token", &loginResponseToken, values) + if err != nil { + notify.Notify("Goldwarden", fmt.Sprintf("Could not login via API key: %v", err), "", func() {}) + return LoginResponseToken{}, crypto.MasterKey{}, "", fmt.Errorf("could not login via API key: %v", err) + } + + password, err := pinentry.GetPassword("Bitwarden Password", "Enter your Bitwarden password") + if err != nil { + notify.Notify("Goldwarden", fmt.Sprintf("Could not get password: %v", err), "", func() {}) + return LoginResponseToken{}, crypto.MasterKey{}, "", err + } + + masterKey, err := crypto.DeriveMasterKey([]byte(strings.Clone(password)), email, crypto.KDFConfig{Type: crypto.KDFType(loginResponseToken.Kdf), Iterations: uint32(loginResponseToken.KdfIterations), Memory: uint32(loginResponseToken.KdfMemory), Parallelism: uint32(loginResponseToken.KdfParallelism)}) + if err != nil { + notify.Notify("Goldwarden", fmt.Sprintf("Could not derive master key: %v", err), "", func() {}) + return LoginResponseToken{}, crypto.MasterKey{}, "", err + } + hashedPassword := b64enc.EncodeToString(pbkdf2.Key(masterKey.GetBytes(), []byte(password), 1, 32, sha256.New)) + + authLog.Info("Logged in") + return loginResponseToken, masterKey, hashedPassword, nil +} + func LoginWithMasterpassword(ctx context.Context, email string, cfg *config.Config, vault *vault.Vault) (LoginResponseToken, crypto.MasterKey, string, error) { var preLogin preLoginResponse if err := authenticatedHTTPPost(ctx, cfg.ConfigFile.ApiUrl+"/accounts/prelogin", &preLogin, preLoginRequest{ @@ -200,25 +250,70 @@ func RefreshToken(ctx context.Context, cfg *config.Config) bool { fmt.Println("Could not get refresh token: ", err) return false } + if token.RefreshToken == "" { + authLog.Info("Refreshing using API Key") + clientID, err := cfg.GetClientID() + if err != nil { + authLog.Error("Could not get client ID: %s", err.Error()) + return false + } + clientSecret, err := cfg.GetClientSecret() + if err != nil { + authLog.Error("Could not get client secret: %s", err.Error()) + return false + } - var loginResponseToken LoginResponseToken - err = authenticatedHTTPPost(ctx, cfg.ConfigFile.IdentityUrl+"/connect/token", &loginResponseToken, urlValues( - "grant_type", "refresh_token", - "refresh_token", token.RefreshToken, - "client_id", "connector", - )) - if err != nil { - authLog.Error("Could not refresh token: %s", err.Error()) - notify.Notify("Goldwarden", fmt.Sprintf("Could not refresh token: %v", err), "", func() {}) - return false + if clientID != "" && clientSecret != "" { + values := urlValues( + "client_id", clientID, + "client_secret", clientSecret, + "scope", loginApiKeyScope, + "grant_type", "client_credentials", + "deviceType", deviceType(), + "deviceName", deviceName, + "deviceIdentifier", cfg.ConfigFile.DeviceUUID, + ) + + var loginResponseToken LoginResponseToken + err = authenticatedHTTPPost(ctx, cfg.ConfigFile.IdentityUrl+"/connect/token", &loginResponseToken, values) + if err != nil { + authLog.Error("Could not refresh token: %s", err.Error()) + notify.Notify("Goldwarden", fmt.Sprintf("Could not refresh token: %v", err), "", func() {}) + return false + } + + cfg.SetToken(config.LoginToken{ + AccessToken: loginResponseToken.AccessToken, + RefreshToken: "", + Key: loginResponseToken.Key, + TokenType: loginResponseToken.TokenType, + ExpiresIn: loginResponseToken.ExpiresIn, + }) + } else { + authLog.Info("No api credentials set") + } + } else { + authLog.Info("Refreshing using refresh token") + + var loginResponseToken LoginResponseToken + err = authenticatedHTTPPost(ctx, cfg.ConfigFile.IdentityUrl+"/connect/token", &loginResponseToken, urlValues( + "grant_type", "refresh_token", + "refresh_token", token.RefreshToken, + "client_id", "connector", + )) + if err != nil { + authLog.Error("Could not refresh token: %s", err.Error()) + notify.Notify("Goldwarden", fmt.Sprintf("Could not refresh token: %v", err), "", func() {}) + return false + } + cfg.SetToken(config.LoginToken{ + AccessToken: loginResponseToken.AccessToken, + RefreshToken: loginResponseToken.RefreshToken, + Key: loginResponseToken.Key, + TokenType: loginResponseToken.TokenType, + ExpiresIn: loginResponseToken.ExpiresIn, + }) } - cfg.SetToken(config.LoginToken{ - AccessToken: loginResponseToken.AccessToken, - RefreshToken: loginResponseToken.RefreshToken, - Key: loginResponseToken.Key, - TokenType: loginResponseToken.TokenType, - ExpiresIn: loginResponseToken.ExpiresIn, - }) authLog.Info("Token refreshed") diff --git a/agent/config/config.go b/agent/config/config.go index 6b1eb00..9b0ed4c 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -54,6 +54,8 @@ type ConfigFile struct { IdentityUrl string ApiUrl string NotificationsUrl string + EncryptedClientID string + EncryptedClientSecret string DeviceUUID string ConfigKeyHash string EncryptedToken string @@ -88,6 +90,8 @@ func DefaultConfig(useMemguard bool) Config { IdentityUrl: "https://vault.bitwarden.com/identity", ApiUrl: "https://vault.bitwarden.com/api", NotificationsUrl: "https://notifications.bitwarden.com", + EncryptedClientID: "", + EncryptedClientSecret: "", DeviceUUID: deviceUUID.String(), ConfigKeyHash: "", EncryptedToken: "", @@ -241,6 +245,82 @@ func (c *Config) SetToken(token LoginToken) error { return nil } +func (c *Config) GetClientID() (string, error) { + if c.IsLocked() { + return "", errors.New("config is locked") + } + + if c.ConfigFile.EncryptedClientID == "" { + return "", nil + } + + decrypted, err := c.decryptString(c.ConfigFile.EncryptedClientID) + if err != nil { + return "", err + } + return decrypted, nil +} + +func (c *Config) SetClientID(clientID string) error { + if c.IsLocked() { + return errors.New("config is locked") + } + + if clientID == "" { + c.ConfigFile.EncryptedClientID = "" + c.WriteConfig() + return nil + } + + encryptedClientID, err := c.encryptString(clientID) + if err != nil { + return err + } + // c.mu.Lock() + c.ConfigFile.EncryptedClientID = encryptedClientID + // c.mu.Unlock() + c.WriteConfig() + return nil +} + +func (c *Config) GetClientSecret() (string, error) { + if c.IsLocked() { + return "", errors.New("config is locked") + } + + if c.ConfigFile.EncryptedClientSecret == "" { + return "", nil + } + + decrypted, err := c.decryptString(c.ConfigFile.EncryptedClientSecret) + if err != nil { + return "", err + } + return decrypted, nil +} + +func (c *Config) SetClientSecret(clientSecret string) error { + if c.IsLocked() { + return errors.New("config is locked") + } + + if clientSecret == "" { + c.ConfigFile.EncryptedClientSecret = "" + c.WriteConfig() + return nil + } + + encryptedClientSecret, err := c.encryptString(clientSecret) + if err != nil { + return err + } + // c.mu.Lock() + c.ConfigFile.EncryptedClientSecret = encryptedClientSecret + // c.mu.Unlock() + c.WriteConfig() + return nil +} + func (c *Config) GetUserSymmetricKey() ([]byte, error) { if c.IsLocked() { return []byte{}, errors.New("config is locked") diff --git a/agent/unixsocketagent.go b/agent/unixsocketagent.go index 8bc375d..74b59ea 100644 --- a/agent/unixsocketagent.go +++ b/agent/unixsocketagent.go @@ -23,7 +23,7 @@ import ( const ( FullSyncInterval = 60 * time.Minute - TokenRefreshInterval = 30 * time.Minute + TokenRefreshInterval = 10 * time.Minute ) var log = logging.GetLogger("Goldwarden", "Agent") @@ -248,6 +248,7 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error { for { time.Sleep(FullSyncInterval) if !cfg.IsLocked() { + bitwarden.RefreshToken(ctx, &cfg) token, err := cfg.GetToken() if err != nil { log.Warn("Could not get token: %s", err.Error()) diff --git a/cmd/config.go b/cmd/config.go index c4652a5..db25b28 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -106,6 +106,72 @@ var setNotificationsURLCmd = &cobra.Command{ }, } +var setApiClientIDCmd = &cobra.Command{ + Use: "set-api-client-id", + Short: "Set the api client id", + Long: `Set the api client id.`, + Run: func(cmd *cobra.Command, args []string) { + if len(args) == 0 { + return + } + + id := args[0] + request := messages.SetClientIDRequest{} + request.Value = id + + result, err := commandClient.SendToAgent(request) + if err != nil { + handleSendToAgentError(err) + return + } + + switch result.(type) { + case messages.ActionResponse: + if result.(messages.ActionResponse).Success { + println("Done") + } else { + println("Setting api client id failed: " + result.(messages.ActionResponse).Message) + } + default: + println("Wrong IPC response type") + } + + }, +} + +var setApiSecretCmd = &cobra.Command{ + Use: "set-api-client-secret", + Short: "Set the api secret", + Long: `Set the api secret.`, + Run: func(cmd *cobra.Command, args []string) { + if len(args) == 0 { + return + } + + secret := args[0] + request := messages.SetClientSecretRequest{} + request.Value = secret + + result, err := commandClient.SendToAgent(request) + if err != nil { + handleSendToAgentError(err) + return + } + + switch result.(type) { + case messages.ActionResponse: + if result.(messages.ActionResponse).Success { + println("Done") + } else { + println("Setting api secret failed: " + result.(messages.ActionResponse).Message) + } + default: + println("Wrong IPC response type") + } + + }, +} + var getRuntimeConfigCmd = &cobra.Command{ Use: "get-runtime-config", Short: "Get the runtime config", @@ -144,4 +210,6 @@ func init() { configCmd.AddCommand(setIdentityURLCmd) configCmd.AddCommand(setNotificationsURLCmd) configCmd.AddCommand(getRuntimeConfigCmd) + configCmd.AddCommand(setApiClientIDCmd) + configCmd.AddCommand(setApiSecretCmd) } diff --git a/go.mod b/go.mod index e371bdf..fe33433 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/awnumar/memguard v0.22.4 github.com/google/uuid v1.5.0 github.com/gorilla/websocket v1.5.1 + github.com/icza/gox v0.0.0-20230924165045-adcb03233bb5 github.com/lox/go-touchid v0.0.0-20170712105233-619cc8e578d0 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/mitchellh/go-ps v1.0.0 @@ -23,22 +24,8 @@ require ( require ( github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect - github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-text/typesetting v0.0.0-20230602202114-9797aefac433 // indirect - github.com/icza/gox v0.0.0-20230924165045-adcb03233bb5 // indirect - github.com/k0kubun/pp v2.4.0+incompatible // indirect - github.com/k0kubun/pp/v3 v3.2.0 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect - github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/shoenig/go-m1cpu v0.1.6 // indirect - github.com/tklauser/go-sysconf v0.3.13 // indirect - github.com/tklauser/numcpus v0.7.0 // indirect - github.com/yusufpapurcu/wmi v1.2.3 // indirect - golang.org/x/exp/shiny v0.0.0-20231219180239-dc181d75b848 // indirect - golang.org/x/image v0.14.0 // indirect golang.org/x/net v0.19.0 // indirect golang.org/x/sys v0.15.0 // indirect - golang.org/x/text v0.14.0 // indirect ) require ( diff --git a/go.sum b/go.sum index cfc5260..0c3a764 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,3 @@ -eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d h1:ARo7NCVvN2NdhLlJE9xAbKweuI9L6UgfTbYb0YwPacY= -gioui.org v0.1.0 h1:fEDY5A4+epOdzjCBYSUC4BzvjWqsjfqf5D6mskbthOs= -gioui.org v0.1.0/go.mod h1:a3hz8FyrPMkt899D9YrxMGtyRzpPrJpz1Lzbssn81vI= -gioui.org/cpu v0.0.0-20210808092351-bfe733dd3334/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ= -gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2 h1:AGDDxsJE1RpcXTAxPG2B4jrwVUJGFDjINIPi1jtO6pc= -gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ= -gioui.org/shader v1.0.6 h1:cvZmU+eODFR2545X+/8XucgZdTtEjR3QWW6W65b0q5Y= -gioui.org/shader v1.0.6/go.mod h1:mWdiME581d/kV7/iEhLmUgUK5iZ09XR5XpduXzbePVM= github.com/LlamaNite/llamalog v0.2.1 h1:k9XugHmyQqJhCrogca808Jl2rrEKIWMtWyLKX+xX9Mg= github.com/LlamaNite/llamalog v0.2.1/go.mod h1:zopgmWk8utZPfZCPa/uvQkv99Lan3pRrw/9inbIYZeo= github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= @@ -22,11 +14,8 @@ github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8 github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 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/go-text/typesetting v0.0.0-20230602202114-9797aefac433 h1:Pdyvqsfi1QYgFfZa4R8otBOtgO+CGyBDMEG8cM3jwvE= -github.com/go-text/typesetting v0.0.0-20230602202114-9797aefac433/go.mod h1:KmrpWuSMFcO2yjmyhGpnBGQHSKAoEgMTSSzvLDzCuEA= -github.com/go-text/typesetting-utils v0.0.0-20230412163830-89e4bcfa3ecc h1:9Kf84pnrmmjdRzZIkomfjowmGUhHs20jkrWYw/I6CYc= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -71,8 +60,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/tink-crypto/tink-go/v2 v2.1.0 h1:QXFBguwMwTIaU17EgZpEJWsUSc60b1BAGTzBIoMdmok= github.com/tink-crypto/tink-go/v2 v2.1.0/go.mod h1:y1TnYFt1i2eZVfx4OGc+C+EMp4CoKWAw2VSEuoicHHI= github.com/twpayne/go-pinentry v0.3.0 h1:Rr+fEOZXmeItOb4thjeVaBWJKB9Xa/eojolycyF/26c= @@ -85,10 +73,6 @@ golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 h1:+iq7lrkxmFNBM7xx+Rae2W6uyPfhPeDWD+n+JgppptE= golang.org/x/exp v0.0.0-20231219180239-dc181d75b848/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= -golang.org/x/exp/shiny v0.0.0-20231219180239-dc181d75b848 h1:LnDWUUS+bxOesHc+QBvFFmS4v0ZH+Vtg0EncMANwN9Q= -golang.org/x/exp/shiny v0.0.0-20231219180239-dc181d75b848/go.mod h1:UH99kUObWAZkDnWqppdQe5ZhPYESUw8I0zVV1uWBR+0= -golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= -golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -100,8 +84,6 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/ipc/messages/config.go b/ipc/messages/config.go index 41ed12a..107d818 100644 --- a/ipc/messages/config.go +++ b/ipc/messages/config.go @@ -14,6 +14,14 @@ type SetNotificationsURLRequest struct { Value string } +type SetClientIDRequest struct { + Value string +} + +type SetClientSecretRequest struct { + Value string +} + type GetRuntimeConfigRequest struct{} type GetRuntimeConfigResponse struct { @@ -67,4 +75,22 @@ func init() { } return req, nil }, GetRuntimeConfigResponse{}) + + registerPayloadParser(func(payload []byte) (interface{}, error) { + var req SetClientIDRequest + err := json.Unmarshal(payload, &req) + if err != nil { + panic("Unmarshal: " + err.Error()) + } + return req, nil + }, SetClientIDRequest{}) + + registerPayloadParser(func(payload []byte) (interface{}, error) { + var req SetClientSecretRequest + err := json.Unmarshal(payload, &req) + if err != nil { + panic("Unmarshal: " + err.Error()) + } + return req, nil + }, SetClientSecretRequest{}) }