feat(BRIDGE-238): Added host information to sentry events; new sentry event for keychain issues

This commit is contained in:
Atanas Janeshliev
2024-10-25 16:40:46 +02:00
parent 810be2d423
commit 4d2b328589
7 changed files with 71 additions and 28 deletions

View File

@ -285,7 +285,7 @@ func run(c *cli.Context) error {
skipKeychainTest := checkSkipKeychainTest(c, settings) skipKeychainTest := checkSkipKeychainTest(c, settings)
return WithKeychainList(crashHandler, skipKeychainTest, func(keychains *keychain.List) error { return WithKeychainList(crashHandler, skipKeychainTest, func(keychains *keychain.List) error {
// Unlock the encrypted vault. // Unlock the encrypted vault.
return WithVault(locations, keychains, crashHandler, func(v *vault.Vault, insecure, corrupt bool) error { return WithVault(reporter, locations, keychains, crashHandler, func(v *vault.Vault, insecure, corrupt bool) error {
if !v.Migrated() { if !v.Migrated() {
// Migrate old settings into the vault. // Migrate old settings into the vault.
if err := migrateOldSettings(v); err != nil { if err := migrateOldSettings(v); err != nil {

View File

@ -25,17 +25,18 @@ import (
"github.com/ProtonMail/proton-bridge/v3/internal/certs" "github.com/ProtonMail/proton-bridge/v3/internal/certs"
"github.com/ProtonMail/proton-bridge/v3/internal/constants" "github.com/ProtonMail/proton-bridge/v3/internal/constants"
"github.com/ProtonMail/proton-bridge/v3/internal/locations" "github.com/ProtonMail/proton-bridge/v3/internal/locations"
"github.com/ProtonMail/proton-bridge/v3/internal/sentry"
"github.com/ProtonMail/proton-bridge/v3/internal/vault" "github.com/ProtonMail/proton-bridge/v3/internal/vault"
"github.com/ProtonMail/proton-bridge/v3/pkg/keychain" "github.com/ProtonMail/proton-bridge/v3/pkg/keychain"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
func WithVault(locations *locations.Locations, keychains *keychain.List, panicHandler async.PanicHandler, fn func(*vault.Vault, bool, bool) error) error { func WithVault(reporter *sentry.Reporter, locations *locations.Locations, keychains *keychain.List, panicHandler async.PanicHandler, fn func(*vault.Vault, bool, bool) error) error {
logrus.Debug("Creating vault") logrus.Debug("Creating vault")
defer logrus.Debug("Vault stopped") defer logrus.Debug("Vault stopped")
// Create the encVault. // Create the encVault.
encVault, insecure, corrupt, err := newVault(locations, keychains, panicHandler) encVault, insecure, corrupt, err := newVault(reporter, locations, keychains, panicHandler)
if err != nil { if err != nil {
return fmt.Errorf("could not create vault: %w", err) return fmt.Errorf("could not create vault: %w", err)
} }
@ -57,7 +58,7 @@ func WithVault(locations *locations.Locations, keychains *keychain.List, panicHa
return fn(encVault, insecure, corrupt != nil) return fn(encVault, insecure, corrupt != nil)
} }
func newVault(locations *locations.Locations, keychains *keychain.List, panicHandler async.PanicHandler) (*vault.Vault, bool, error, error) { func newVault(reporter *sentry.Reporter, locations *locations.Locations, keychains *keychain.List, panicHandler async.PanicHandler) (*vault.Vault, bool, error, error) {
vaultDir, err := locations.ProvideSettingsPath() vaultDir, err := locations.ProvideSettingsPath()
if err != nil { if err != nil {
return nil, false, nil, fmt.Errorf("could not get vault dir: %w", err) return nil, false, nil, fmt.Errorf("could not get vault dir: %w", err)
@ -71,6 +72,16 @@ func newVault(locations *locations.Locations, keychains *keychain.List, panicHan
) )
if key, err := loadVaultKey(vaultDir, keychains); err != nil { if key, err := loadVaultKey(vaultDir, keychains); err != nil {
if reporter != nil {
if rerr := reporter.ReportMessageWithContext("Could not load/create vault key", map[string]any{
"keychainDefaultHelper": keychains.GetDefaultHelper(),
"keychainUsableHelpersLength": len(keychains.GetHelpers()),
"error": err.Error(),
}); rerr != nil {
logrus.WithError(err).Info("Failed to report keychain issue to Sentry")
}
}
logrus.WithError(err).Error("Could not load/create vault key") logrus.WithError(err).Error("Could not load/create vault key")
insecure = true insecure = true

View File

@ -21,18 +21,13 @@
package sentry package sentry
import ( import (
"github.com/elastic/go-sysinfo" "github.com/elastic/go-sysinfo/types"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
const translatedProcDarwin = "sysctl.proc_translated" const translatedProcDarwin = "sysctl.proc_translated"
func getHostArch() string { func getHostArch(host types.Host) string {
host, err := sysinfo.Host()
if err != nil {
return "not-detected"
}
// It is not possible to retrieve real hardware architecture once using // It is not possible to retrieve real hardware architecture once using
// rosetta. But it is possible to detect the process translation if // rosetta. But it is possible to detect the process translation if
// rosetta is used. // rosetta is used.

View File

@ -20,12 +20,10 @@
package sentry package sentry
import "github.com/elastic/go-sysinfo" import (
"github.com/elastic/go-sysinfo/types"
)
func getHostArch() string { func getHostArch(host types.Host) string {
host, err := sysinfo.Host()
if err != nil {
return "not-detected"
}
return host.Info().Architecture return host.Info().Architecture
} }

View File

@ -30,10 +30,13 @@ import (
"github.com/ProtonMail/proton-bridge/v3/internal/constants" "github.com/ProtonMail/proton-bridge/v3/internal/constants"
"github.com/ProtonMail/proton-bridge/v3/pkg/algo" "github.com/ProtonMail/proton-bridge/v3/pkg/algo"
"github.com/ProtonMail/proton-bridge/v3/pkg/restarter" "github.com/ProtonMail/proton-bridge/v3/pkg/restarter"
"github.com/elastic/go-sysinfo"
"github.com/getsentry/sentry-go" "github.com/getsentry/sentry-go"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
const hostNotDetectedField = "not-detected"
var skippedFunctions = []string{} //nolint:gochecknoglobals var skippedFunctions = []string{} //nolint:gochecknoglobals
func init() { //nolint:gochecknoinits func init() { //nolint:gochecknoinits
@ -70,17 +73,50 @@ func init() { //nolint:gochecknoinits
) )
} }
type hostInfoData struct {
hostArch string
hostName string
hostVersion string
hostBuild string
}
func newHostInfoData() hostInfoData {
return hostInfoData{
hostArch: hostNotDetectedField,
hostName: hostNotDetectedField,
hostVersion: hostNotDetectedField,
hostBuild: hostNotDetectedField,
}
}
type Reporter struct { type Reporter struct {
appName string appName string
appVersion string appVersion string
identifier Identifier identifier Identifier
hostArch string hostInfo hostInfoData
} }
type Identifier interface { type Identifier interface {
GetUserAgent() string GetUserAgent() string
} }
func getHostInfo() hostInfoData {
data := newHostInfoData()
host, err := sysinfo.Host()
if err != nil {
return data
}
data.hostArch = getHostArch(host)
osInfo := host.Info().OS
data.hostName = osInfo.Name
data.hostVersion = osInfo.Version
data.hostBuild = osInfo.Build
return data
}
func GetProtectedHostname() string { func GetProtectedHostname() string {
hostname, err := os.Hostname() hostname, err := os.Hostname()
if err != nil { if err != nil {
@ -100,7 +136,7 @@ func NewReporter(appName string, identifier Identifier) *Reporter {
appName: appName, appName: appName,
appVersion: constants.Revision, appVersion: constants.Revision,
identifier: identifier, identifier: identifier,
hostArch: getHostArch(), hostInfo: getHostInfo(),
} }
} }
@ -152,11 +188,14 @@ func (r *Reporter) scopedReport(context map[string]interface{}, doReport func())
} }
tags := map[string]string{ tags := map[string]string{
"OS": runtime.GOOS, "OS": runtime.GOOS,
"Client": r.appName, "Client": r.appName,
"Version": r.appVersion, "Version": r.appVersion,
"UserAgent": r.identifier.GetUserAgent(), "UserAgent": r.identifier.GetUserAgent(),
"HostArch": r.hostArch, "HostArch": r.hostInfo.hostArch,
"HostName": r.hostInfo.hostName,
"HostVersion": r.hostInfo.hostVersion,
"HostBuild": r.hostInfo.hostBuild,
} }
sentry.WithScope(func(scope *sentry.Scope) { sentry.WithScope(func(scope *sentry.Scope) {

View File

@ -62,7 +62,7 @@ func main() {
func getRollout(_ *cli.Context) error { func getRollout(_ *cli.Context) error {
return app.WithLocations(func(locations *locations.Locations) error { return app.WithLocations(func(locations *locations.Locations) error {
return app.WithKeychainList(async.NoopPanicHandler{}, false, func(keychains *keychain.List) error { return app.WithKeychainList(async.NoopPanicHandler{}, false, func(keychains *keychain.List) error {
return app.WithVault(locations, keychains, async.NoopPanicHandler{}, func(vault *vault.Vault, _, _ bool) error { return app.WithVault(nil, locations, keychains, async.NoopPanicHandler{}, func(vault *vault.Vault, _, _ bool) error {
fmt.Println(vault.GetUpdateRollout()) fmt.Println(vault.GetUpdateRollout())
return nil return nil
}) })
@ -73,7 +73,7 @@ func getRollout(_ *cli.Context) error {
func setRollout(c *cli.Context) error { func setRollout(c *cli.Context) error {
return app.WithLocations(func(locations *locations.Locations) error { return app.WithLocations(func(locations *locations.Locations) error {
return app.WithKeychainList(async.NoopPanicHandler{}, false, func(keychains *keychain.List) error { return app.WithKeychainList(async.NoopPanicHandler{}, false, func(keychains *keychain.List) error {
return app.WithVault(locations, keychains, async.NoopPanicHandler{}, func(vault *vault.Vault, _, _ bool) error { return app.WithVault(nil, locations, keychains, async.NoopPanicHandler{}, func(vault *vault.Vault, _, _ bool) error {
clamped := max(0.0, min(1.0, c.Float64("value"))) clamped := max(0.0, min(1.0, c.Float64("value")))
if err := vault.SetUpdateRollout(clamped); err != nil { if err := vault.SetUpdateRollout(clamped); err != nil {
return err return err

View File

@ -52,7 +52,7 @@ func main() {
func readAction(c *cli.Context) error { func readAction(c *cli.Context) error {
return app.WithLocations(func(locations *locations.Locations) error { return app.WithLocations(func(locations *locations.Locations) error {
return app.WithKeychainList(async.NoopPanicHandler{}, false, func(keychains *keychain.List) error { return app.WithKeychainList(async.NoopPanicHandler{}, false, func(keychains *keychain.List) error {
return app.WithVault(locations, keychains, async.NoopPanicHandler{}, func(vault *vault.Vault, insecure, corrupt bool) error { return app.WithVault(nil, locations, keychains, async.NoopPanicHandler{}, func(vault *vault.Vault, insecure, corrupt bool) error {
if _, err := os.Stdout.Write(vault.ExportJSON()); err != nil { if _, err := os.Stdout.Write(vault.ExportJSON()); err != nil {
return fmt.Errorf("failed to write vault: %w", err) return fmt.Errorf("failed to write vault: %w", err)
} }
@ -66,7 +66,7 @@ func readAction(c *cli.Context) error {
func writeAction(c *cli.Context) error { func writeAction(c *cli.Context) error {
return app.WithLocations(func(locations *locations.Locations) error { return app.WithLocations(func(locations *locations.Locations) error {
return app.WithKeychainList(async.NoopPanicHandler{}, false, func(keychains *keychain.List) error { return app.WithKeychainList(async.NoopPanicHandler{}, false, func(keychains *keychain.List) error {
return app.WithVault(locations, keychains, async.NoopPanicHandler{}, func(vault *vault.Vault, insecure, corrupt bool) error { return app.WithVault(nil, locations, keychains, async.NoopPanicHandler{}, func(vault *vault.Vault, insecure, corrupt bool) error {
b, err := io.ReadAll(os.Stdin) b, err := io.ReadAll(os.Stdin)
if err != nil { if err != nil {
return fmt.Errorf("failed to read vault: %w", err) return fmt.Errorf("failed to read vault: %w", err)