Other(refactor): Move Settings out of frontend

This commit is contained in:
James Houlahan
2022-08-22 12:32:55 +02:00
committed by Jakub
parent 310c6a1ccf
commit 0c7453684b
17 changed files with 178 additions and 129 deletions

View File

@ -156,7 +156,6 @@ func main(b *base.Base, c *cli.Context) error { //nolint:funlen
frontendMode, frontendMode,
!c.Bool(base.FlagNoWindow), !c.Bool(base.FlagNoWindow),
b.CrashHandler, b.CrashHandler,
b.Settings,
b.Listener, b.Listener,
b.Updater, b.Updater,
bridge, bridge,

View File

@ -0,0 +1,44 @@
// Copyright (c) 2022 Proton AG
//
// This file is part of Proton Mail Bridge.
//
// Proton Mail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Proton Mail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
package bridge
import "github.com/ProtonMail/proton-bridge/v2/internal/config/settings"
func (b *Bridge) Get(key settings.Key) string {
return b.settings.Get(key)
}
func (b *Bridge) Set(key settings.Key, value string) {
b.settings.Set(key, value)
}
func (b *Bridge) GetBool(key settings.Key) bool {
return b.settings.GetBool(key)
}
func (b *Bridge) SetBool(key settings.Key, value bool) {
b.settings.SetBool(key, value)
}
func (b *Bridge) GetInt(key settings.Key) int {
return b.settings.GetInt(key)
}
func (b *Bridge) SetInt(key settings.Key, value int) {
b.settings.SetInt(key, value)
}

View File

@ -20,6 +20,7 @@ package bridge
import ( import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/ProtonMail/proton-bridge/v2/internal/config/settings"
"github.com/ProtonMail/proton-bridge/v2/internal/updater" "github.com/ProtonMail/proton-bridge/v2/internal/updater"
) )
@ -40,11 +41,14 @@ type CacheProvider interface {
} }
type SettingsProvider interface { type SettingsProvider interface {
Get(key string) string Get(key settings.Key) string
Set(key string, value string) Set(key settings.Key, value string)
GetBool(key string) bool
SetBool(key string, val bool) GetBool(key settings.Key) bool
GetInt(key string) int SetBool(key settings.Key, val bool)
GetInt(key settings.Key) int
SetInt(key settings.Key, val int)
} }
type Updater interface { type Updater interface {

View File

@ -30,9 +30,9 @@ import (
) )
type keyValueStore struct { type keyValueStore struct {
cache map[string]string vals map[Key]string
path string path string
lock *sync.RWMutex lock *sync.RWMutex
} }
// newKeyValueStore returns loaded preferences. // newKeyValueStore returns loaded preferences.
@ -48,14 +48,14 @@ func newKeyValueStore(path string) *keyValueStore {
} }
func (p *keyValueStore) load() error { func (p *keyValueStore) load() error {
if p.cache != nil { if p.vals != nil {
return nil return nil
} }
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() defer p.lock.Unlock()
p.cache = map[string]string{} p.vals = make(map[Key]string)
f, err := os.Open(p.path) f, err := os.Open(p.path)
if err != nil { if err != nil {
@ -63,18 +63,18 @@ func (p *keyValueStore) load() error {
} }
defer f.Close() //nolint:errcheck,gosec defer f.Close() //nolint:errcheck,gosec
return json.NewDecoder(f).Decode(&p.cache) return json.NewDecoder(f).Decode(&p.vals)
} }
func (p *keyValueStore) save() error { func (p *keyValueStore) save() error {
if p.cache == nil { if p.vals == nil {
return errors.New("cannot save preferences: cache is nil") return errors.New("cannot save preferences: cache is nil")
} }
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() defer p.lock.Unlock()
b, err := json.MarshalIndent(p.cache, "", "\t") b, err := json.MarshalIndent(p.vals, "", "\t")
if err != nil { if err != nil {
return err return err
} }
@ -82,24 +82,24 @@ func (p *keyValueStore) save() error {
return ioutil.WriteFile(p.path, b, 0o600) return ioutil.WriteFile(p.path, b, 0o600)
} }
func (p *keyValueStore) setDefault(key, value string) { func (p *keyValueStore) setDefault(key Key, value string) {
if p.Get(key) == "" { if p.Get(key) == "" {
p.Set(key, value) p.Set(key, value)
} }
} }
func (p *keyValueStore) Get(key string) string { func (p *keyValueStore) Get(key Key) string {
p.lock.RLock() p.lock.RLock()
defer p.lock.RUnlock() defer p.lock.RUnlock()
return p.cache[key] return p.vals[key]
} }
func (p *keyValueStore) GetBool(key string) bool { func (p *keyValueStore) GetBool(key Key) bool {
return p.Get(key) == "true" return p.Get(key) == "true"
} }
func (p *keyValueStore) GetInt(key string) int { func (p *keyValueStore) GetInt(key Key) int {
if p.Get(key) == "" { if p.Get(key) == "" {
return 0 return 0
} }
@ -112,7 +112,7 @@ func (p *keyValueStore) GetInt(key string) int {
return value return value
} }
func (p *keyValueStore) GetFloat64(key string) float64 { func (p *keyValueStore) GetFloat64(key Key) float64 {
if p.Get(key) == "" { if p.Get(key) == "" {
return 0 return 0
} }
@ -125,9 +125,9 @@ func (p *keyValueStore) GetFloat64(key string) float64 {
return value return value
} }
func (p *keyValueStore) Set(key, value string) { func (p *keyValueStore) Set(key Key, value string) {
p.lock.Lock() p.lock.Lock()
p.cache[key] = value p.vals[key] = value
p.lock.Unlock() p.lock.Unlock()
if err := p.save(); err != nil { if err := p.save(); err != nil {
@ -135,7 +135,7 @@ func (p *keyValueStore) Set(key, value string) {
} }
} }
func (p *keyValueStore) SetBool(key string, value bool) { func (p *keyValueStore) SetBool(key Key, value bool) {
if value { if value {
p.Set(key, "true") p.Set(key, "true")
} else { } else {
@ -143,10 +143,10 @@ func (p *keyValueStore) SetBool(key string, value bool) {
} }
} }
func (p *keyValueStore) SetInt(key string, value int) { func (p *keyValueStore) SetInt(key Key, value int) {
p.Set(key, strconv.Itoa(value)) p.Set(key, strconv.Itoa(value))
} }
func (p *keyValueStore) SetFloat64(key string, value float64) { func (p *keyValueStore) SetFloat64(key Key, value float64) {
p.Set(key, fmt.Sprintf("%v", value)) p.Set(key, fmt.Sprintf("%v", value))
} }

View File

@ -25,36 +25,38 @@ import (
"time" "time"
) )
type Key string
// Keys of preferences in JSON file. // Keys of preferences in JSON file.
const ( const (
FirstStartKey = "first_time_start" FirstStartKey Key = "first_time_start"
FirstStartGUIKey = "first_time_start_gui" FirstStartGUIKey Key = "first_time_start_gui"
LastHeartbeatKey = "last_heartbeat" LastHeartbeatKey Key = "last_heartbeat"
APIPortKey = "user_port_api" APIPortKey Key = "user_port_api"
IMAPPortKey = "user_port_imap" IMAPPortKey Key = "user_port_imap"
SMTPPortKey = "user_port_smtp" SMTPPortKey Key = "user_port_smtp"
SMTPSSLKey = "user_ssl_smtp" SMTPSSLKey Key = "user_ssl_smtp"
AllowProxyKey = "allow_proxy" AllowProxyKey Key = "allow_proxy"
AutostartKey = "autostart" AutostartKey Key = "autostart"
AutoUpdateKey = "autoupdate" AutoUpdateKey Key = "autoupdate"
CookiesKey = "cookies" CookiesKey Key = "cookies"
LastVersionKey = "last_used_version" LastVersionKey Key = "last_used_version"
UpdateChannelKey = "update_channel" UpdateChannelKey Key = "update_channel"
RolloutKey = "rollout" RolloutKey Key = "rollout"
PreferredKeychainKey = "preferred_keychain" PreferredKeychainKey Key = "preferred_keychain"
CacheEnabledKey = "cache_enabled" CacheEnabledKey Key = "cache_enabled"
CacheCompressionKey = "cache_compression" CacheCompressionKey Key = "cache_compression"
CacheLocationKey = "cache_location" CacheLocationKey Key = "cache_location"
CacheMinFreeAbsKey = "cache_min_free_abs" CacheMinFreeAbsKey Key = "cache_min_free_abs"
CacheMinFreeRatKey = "cache_min_free_rat" CacheMinFreeRatKey Key = "cache_min_free_rat"
CacheConcurrencyRead = "cache_concurrent_read" CacheConcurrencyRead Key = "cache_concurrent_read"
CacheConcurrencyWrite = "cache_concurrent_write" CacheConcurrencyWrite Key = "cache_concurrent_write"
IMAPWorkers = "imap_workers" IMAPWorkers Key = "imap_workers"
FetchWorkers = "fetch_workers" FetchWorkers Key = "fetch_workers"
AttachmentWorkers = "attachment_workers" AttachmentWorkers Key = "attachment_workers"
ColorScheme = "color_scheme" ColorScheme Key = "color_scheme"
RebrandingMigrationKey = "rebranding_migrated" RebrandingMigrationKey Key = "rebranding_migrated"
IsAllMailVisible = "is_all_mail_visible" IsAllMailVisible Key = "is_all_mail_visible"
) )
type Settings struct { type Settings struct {

View File

@ -66,13 +66,13 @@ func (f *frontendCLI) showAccountInfo(c *ishell.Context) {
func (f *frontendCLI) showAccountAddressInfo(user types.User, address string) { func (f *frontendCLI) showAccountAddressInfo(user types.User, address string) {
smtpSecurity := "STARTTLS" smtpSecurity := "STARTTLS"
if f.settings.GetBool(settings.SMTPSSLKey) { if f.bridge.GetBool(settings.SMTPSSLKey) {
smtpSecurity = "SSL" smtpSecurity = "SSL"
} }
f.Println(bold("Configuration for " + address)) f.Println(bold("Configuration for " + address))
f.Printf("IMAP Settings\nAddress: %s\nIMAP port: %d\nUsername: %s\nPassword: %s\nSecurity: %s\n", f.Printf("IMAP Settings\nAddress: %s\nIMAP port: %d\nUsername: %s\nPassword: %s\nSecurity: %s\n",
bridge.Host, bridge.Host,
f.settings.GetInt(settings.IMAPPortKey), f.bridge.GetInt(settings.IMAPPortKey),
address, address,
user.GetBridgePassword(), user.GetBridgePassword(),
"STARTTLS", "STARTTLS",
@ -80,7 +80,7 @@ func (f *frontendCLI) showAccountAddressInfo(user types.User, address string) {
f.Println("") f.Println("")
f.Printf("SMTP Settings\nAddress: %s\nSMTP port: %d\nUsername: %s\nPassword: %s\nSecurity: %s\n", f.Printf("SMTP Settings\nAddress: %s\nSMTP port: %d\nUsername: %s\nPassword: %s\nSecurity: %s\n",
bridge.Host, bridge.Host,
f.settings.GetInt(settings.SMTPPortKey), f.bridge.GetInt(settings.SMTPPortKey),
address, address,
user.GetBridgePassword(), user.GetBridgePassword(),
smtpSecurity, smtpSecurity,

View File

@ -19,7 +19,6 @@
package cli package cli
import ( import (
"github.com/ProtonMail/proton-bridge/v2/internal/config/settings"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/types" "github.com/ProtonMail/proton-bridge/v2/internal/frontend/types"
"github.com/ProtonMail/proton-bridge/v2/internal/updater" "github.com/ProtonMail/proton-bridge/v2/internal/updater"
@ -34,7 +33,6 @@ var log = logrus.WithField("pkg", "frontend/cli") //nolint:gochecknoglobals
type frontendCLI struct { type frontendCLI struct {
*ishell.Shell *ishell.Shell
settings *settings.Settings
eventListener listener.Listener eventListener listener.Listener
updater types.Updater updater types.Updater
bridge types.Bridger bridge types.Bridger
@ -46,7 +44,6 @@ type frontendCLI struct {
func New( //nolint:funlen func New( //nolint:funlen
panicHandler types.PanicHandler, panicHandler types.PanicHandler,
settings *settings.Settings,
eventListener listener.Listener, eventListener listener.Listener,
updater types.Updater, updater types.Updater,
bridge types.Bridger, bridge types.Bridger,
@ -55,7 +52,6 @@ func New( //nolint:funlen
fe := &frontendCLI{ fe := &frontendCLI{
Shell: ishell.New(), Shell: ishell.New(),
settings: settings,
eventListener: eventListener, eventListener: eventListener,
updater: updater, updater: updater,
bridge: bridge, bridge: bridge,

View File

@ -75,7 +75,7 @@ func (f *frontendCLI) changeSMTPSecurity(c *ishell.Context) {
f.ShowPrompt(false) f.ShowPrompt(false)
defer f.ShowPrompt(true) defer f.ShowPrompt(true)
isSSL := f.settings.GetBool(settings.SMTPSSLKey) isSSL := f.bridge.GetBool(settings.SMTPSSLKey)
newSecurity := "SSL" newSecurity := "SSL"
if isSSL { if isSSL {
newSecurity = "STARTTLS" newSecurity = "STARTTLS"
@ -84,7 +84,7 @@ func (f *frontendCLI) changeSMTPSecurity(c *ishell.Context) {
msg := fmt.Sprintf("Are you sure you want to change SMTP setting to %q and restart the Bridge", newSecurity) msg := fmt.Sprintf("Are you sure you want to change SMTP setting to %q and restart the Bridge", newSecurity)
if f.yesNoQuestion(msg) { if f.yesNoQuestion(msg) {
f.settings.SetBool(settings.SMTPSSLKey, !isSSL) f.bridge.SetBool(settings.SMTPSSLKey, !isSSL)
f.Println("Restarting Bridge...") f.Println("Restarting Bridge...")
f.restarter.SetToRestart() f.restarter.SetToRestart()
f.Stop() f.Stop()
@ -95,14 +95,14 @@ func (f *frontendCLI) changePort(c *ishell.Context) {
f.ShowPrompt(false) f.ShowPrompt(false)
defer f.ShowPrompt(true) defer f.ShowPrompt(true)
currentPort = f.settings.Get(settings.IMAPPortKey) currentPort = f.bridge.Get(settings.IMAPPortKey)
newIMAPPort := f.readStringInAttempts("Set IMAP port (current "+currentPort+")", c.ReadLine, f.isPortFree) newIMAPPort := f.readStringInAttempts("Set IMAP port (current "+currentPort+")", c.ReadLine, f.isPortFree)
if newIMAPPort == "" { if newIMAPPort == "" {
newIMAPPort = currentPort newIMAPPort = currentPort
} }
imapPortChanged := newIMAPPort != currentPort imapPortChanged := newIMAPPort != currentPort
currentPort = f.settings.Get(settings.SMTPPortKey) currentPort = f.bridge.Get(settings.SMTPPortKey)
newSMTPPort := f.readStringInAttempts("Set SMTP port (current "+currentPort+")", c.ReadLine, f.isPortFree) newSMTPPort := f.readStringInAttempts("Set SMTP port (current "+currentPort+")", c.ReadLine, f.isPortFree)
if newSMTPPort == "" { if newSMTPPort == "" {
newSMTPPort = currentPort newSMTPPort = currentPort
@ -116,8 +116,8 @@ func (f *frontendCLI) changePort(c *ishell.Context) {
if imapPortChanged || smtpPortChanged { if imapPortChanged || smtpPortChanged {
f.Println("Saving values IMAP:", newIMAPPort, "SMTP:", newSMTPPort) f.Println("Saving values IMAP:", newIMAPPort, "SMTP:", newSMTPPort)
f.settings.Set(settings.IMAPPortKey, newIMAPPort) f.bridge.Set(settings.IMAPPortKey, newIMAPPort)
f.settings.Set(settings.SMTPPortKey, newSMTPPort) f.bridge.Set(settings.SMTPPortKey, newSMTPPort)
f.Println("Restarting Bridge...") f.Println("Restarting Bridge...")
f.restarter.SetToRestart() f.restarter.SetToRestart()
f.Stop() f.Stop()
@ -179,7 +179,7 @@ func (f *frontendCLI) showAllMail(c *ishell.Context) {
} }
func (f *frontendCLI) enableCacheOnDisk(c *ishell.Context) { func (f *frontendCLI) enableCacheOnDisk(c *ishell.Context) {
if f.settings.GetBool(settings.CacheEnabledKey) { if f.bridge.GetBool(settings.CacheEnabledKey) {
f.Println("The local cache is already enabled.") f.Println("The local cache is already enabled.")
return return
} }
@ -196,7 +196,7 @@ func (f *frontendCLI) enableCacheOnDisk(c *ishell.Context) {
} }
func (f *frontendCLI) disableCacheOnDisk(c *ishell.Context) { func (f *frontendCLI) disableCacheOnDisk(c *ishell.Context) {
if !f.settings.GetBool(settings.CacheEnabledKey) { if !f.bridge.GetBool(settings.CacheEnabledKey) {
f.Println("The local cache is already disabled.") f.Println("The local cache is already disabled.")
return return
} }
@ -213,17 +213,17 @@ func (f *frontendCLI) disableCacheOnDisk(c *ishell.Context) {
} }
func (f *frontendCLI) setCacheOnDiskLocation(c *ishell.Context) { func (f *frontendCLI) setCacheOnDiskLocation(c *ishell.Context) {
if !f.settings.GetBool(settings.CacheEnabledKey) { if !f.bridge.GetBool(settings.CacheEnabledKey) {
f.Println("The local cache must be enabled.") f.Println("The local cache must be enabled.")
return return
} }
if location := f.settings.Get(settings.CacheLocationKey); location != "" { if location := f.bridge.Get(settings.CacheLocationKey); location != "" {
f.Println("The current local cache location is:", location) f.Println("The current local cache location is:", location)
} }
if location := f.readStringInAttempts("Enter a new location for the cache", c.ReadLine, f.isCacheLocationUsable); location != "" { if location := f.readStringInAttempts("Enter a new location for the cache", c.ReadLine, f.isCacheLocationUsable); location != "" {
if err := f.bridge.MigrateCache(f.settings.Get(settings.CacheLocationKey), location); err != nil { if err := f.bridge.MigrateCache(f.bridge.Get(settings.CacheLocationKey), location); err != nil {
f.Println("The local cache location could not be changed.") f.Println("The local cache location could not be changed.")
return return
} }

View File

@ -47,7 +47,7 @@ func (f *frontendCLI) printCredits(c *ishell.Context) {
} }
func (f *frontendCLI) enableAutoUpdates(c *ishell.Context) { func (f *frontendCLI) enableAutoUpdates(c *ishell.Context) {
if f.settings.GetBool(settings.AutoUpdateKey) { if f.bridge.GetBool(settings.AutoUpdateKey) {
f.Println("Bridge is already set to automatically install updates.") f.Println("Bridge is already set to automatically install updates.")
return return
} }
@ -55,12 +55,12 @@ func (f *frontendCLI) enableAutoUpdates(c *ishell.Context) {
f.Println("Bridge is currently set to NOT automatically install updates.") f.Println("Bridge is currently set to NOT automatically install updates.")
if f.yesNoQuestion("Are you sure you want to allow bridge to do this") { if f.yesNoQuestion("Are you sure you want to allow bridge to do this") {
f.settings.SetBool(settings.AutoUpdateKey, true) f.bridge.SetBool(settings.AutoUpdateKey, true)
} }
} }
func (f *frontendCLI) disableAutoUpdates(c *ishell.Context) { func (f *frontendCLI) disableAutoUpdates(c *ishell.Context) {
if !f.settings.GetBool(settings.AutoUpdateKey) { if !f.bridge.GetBool(settings.AutoUpdateKey) {
f.Println("Bridge is already set to NOT automatically install updates.") f.Println("Bridge is already set to NOT automatically install updates.")
return return
} }
@ -68,7 +68,7 @@ func (f *frontendCLI) disableAutoUpdates(c *ishell.Context) {
f.Println("Bridge is currently set to automatically install updates.") f.Println("Bridge is currently set to automatically install updates.")
if f.yesNoQuestion("Are you sure you want to stop bridge from doing this") { if f.yesNoQuestion("Are you sure you want to stop bridge from doing this") {
f.settings.SetBool(settings.AutoUpdateKey, false) f.bridge.SetBool(settings.AutoUpdateKey, false)
} }
} }

View File

@ -20,7 +20,6 @@ package frontend
import ( import (
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/config/settings"
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/cli" "github.com/ProtonMail/proton-bridge/v2/internal/frontend/cli"
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/grpc" "github.com/ProtonMail/proton-bridge/v2/internal/frontend/grpc"
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/types" "github.com/ProtonMail/proton-bridge/v2/internal/frontend/types"
@ -42,7 +41,6 @@ func New(
frontendType string, frontendType string,
showWindowOnStart bool, showWindowOnStart bool,
panicHandler types.PanicHandler, panicHandler types.PanicHandler,
settings *settings.Settings,
eventListener listener.Listener, eventListener listener.Listener,
updater types.Updater, updater types.Updater,
bridge *bridge.Bridge, bridge *bridge.Bridge,
@ -54,7 +52,6 @@ func New(
return grpc.NewService( return grpc.NewService(
showWindowOnStart, showWindowOnStart,
panicHandler, panicHandler,
settings,
eventListener, eventListener,
updater, updater,
bridgeWrap, bridgeWrap,
@ -64,7 +61,6 @@ func New(
case "cli": case "cli":
return cli.New( return cli.New(
panicHandler, panicHandler,
settings,
eventListener, eventListener,
updater, updater,
bridgeWrap, bridgeWrap,

View File

@ -50,7 +50,6 @@ type Service struct { // nolint:structcheck
eventStreamDoneCh chan struct{} eventStreamDoneCh chan struct{}
panicHandler types.PanicHandler panicHandler types.PanicHandler
settings *settings.Settings
eventListener listener.Listener eventListener listener.Listener
updater types.Updater updater types.Updater
updateCheckMutex sync.Mutex updateCheckMutex sync.Mutex
@ -71,7 +70,6 @@ type Service struct { // nolint:structcheck
func NewService( func NewService(
showOnStartup bool, showOnStartup bool,
panicHandler types.PanicHandler, panicHandler types.PanicHandler,
settings *settings.Settings,
eventListener listener.Listener, eventListener listener.Listener,
updater types.Updater, updater types.Updater,
bridge types.Bridger, bridge types.Bridger,
@ -80,7 +78,6 @@ func NewService(
s := Service{ s := Service{
UnimplementedBridgeServer: UnimplementedBridgeServer{}, UnimplementedBridgeServer: UnimplementedBridgeServer{},
panicHandler: panicHandler, panicHandler: panicHandler,
settings: settings,
eventListener: eventListener, eventListener: eventListener,
updater: updater, updater: updater,
bridge: bridge, bridge: bridge,
@ -126,7 +123,7 @@ func (s *Service) initAutostart() {
// TO-DO GODT-1681 Autostart needs to be properly implement for gRPC approach. // TO-DO GODT-1681 Autostart needs to be properly implement for gRPC approach.
s.firstTimeAutostart.Do(func() { s.firstTimeAutostart.Do(func() {
shouldAutostartBeOn := s.settings.GetBool(settings.AutostartKey) shouldAutostartBeOn := s.bridge.GetBool(settings.AutostartKey)
if s.bridge.IsFirstStart() || shouldAutostartBeOn { if s.bridge.IsFirstStart() || shouldAutostartBeOn {
if err := s.bridge.EnableAutostart(); err != nil { if err := s.bridge.EnableAutostart(); err != nil {
s.log.WithField("prefs", shouldAutostartBeOn).WithError(err).Error("Failed to enable first autostart") s.log.WithField("prefs", shouldAutostartBeOn).WithError(err).Error("Failed to enable first autostart")
@ -138,7 +135,7 @@ func (s *Service) initAutostart() {
func (s *Service) Loop() error { func (s *Service) Loop() error {
defer func() { defer func() {
s.settings.SetBool(settings.FirstStartGUIKey, false) s.bridge.SetBool(settings.FirstStartGUIKey, false)
}() }()
go func() { go func() {

View File

@ -129,7 +129,7 @@ func (s *Service) ShowSplashScreen(context.Context, *emptypb.Empty) (*wrapperspb
func (s *Service) IsFirstGuiStart(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { func (s *Service) IsFirstGuiStart(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) {
s.log.Info("IsFirstGuiStart") s.log.Info("IsFirstGuiStart")
return wrapperspb.Bool(s.settings.GetBool(settings.FirstStartGUIKey)), nil return wrapperspb.Bool(s.bridge.GetBool(settings.FirstStartGUIKey)), nil
} }
func (s *Service) SetIsAutostartOn(_ context.Context, isOn *wrapperspb.BoolValue) (*emptypb.Empty, error) { func (s *Service) SetIsAutostartOn(_ context.Context, isOn *wrapperspb.BoolValue) (*emptypb.Empty, error) {
@ -238,7 +238,7 @@ func (s *Service) SetColorSchemeName(_ context.Context, name *wrapperspb.StringV
return nil, status.Error(codes.NotFound, "Color scheme not available") return nil, status.Error(codes.NotFound, "Color scheme not available")
} }
s.settings.Set(settings.ColorScheme, name.Value) s.bridge.Set(settings.ColorScheme, name.Value)
return &emptypb.Empty{}, nil return &emptypb.Empty{}, nil
} }
@ -246,10 +246,10 @@ func (s *Service) SetColorSchemeName(_ context.Context, name *wrapperspb.StringV
func (s *Service) ColorSchemeName(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { func (s *Service) ColorSchemeName(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) {
s.log.Info("ColorSchemeName") s.log.Info("ColorSchemeName")
current := s.settings.Get(settings.ColorScheme) current := s.bridge.Get(settings.ColorScheme)
if !theme.IsAvailable(theme.Theme(current)) { if !theme.IsAvailable(theme.Theme(current)) {
current = string(theme.DefaultTheme()) current = string(theme.DefaultTheme())
s.settings.Set(settings.ColorScheme, current) s.bridge.Set(settings.ColorScheme, current)
} }
return wrapperspb.String(current), nil return wrapperspb.String(current), nil
@ -459,12 +459,12 @@ func (s *Service) InstallUpdate(context.Context, *emptypb.Empty) (*emptypb.Empty
func (s *Service) SetIsAutomaticUpdateOn(_ context.Context, isOn *wrapperspb.BoolValue) (*emptypb.Empty, error) { func (s *Service) SetIsAutomaticUpdateOn(_ context.Context, isOn *wrapperspb.BoolValue) (*emptypb.Empty, error) {
s.log.WithField("isOn", isOn.Value).Info("SetIsAutomaticUpdateOn") s.log.WithField("isOn", isOn.Value).Info("SetIsAutomaticUpdateOn")
currentlyOn := s.settings.GetBool(settings.AutoUpdateKey) currentlyOn := s.bridge.GetBool(settings.AutoUpdateKey)
if currentlyOn == isOn.Value { if currentlyOn == isOn.Value {
return &emptypb.Empty{}, nil return &emptypb.Empty{}, nil
} }
s.settings.SetBool(settings.AutoUpdateKey, isOn.Value) s.bridge.SetBool(settings.AutoUpdateKey, isOn.Value)
s.checkUpdateAndNotify(false) s.checkUpdateAndNotify(false)
return &emptypb.Empty{}, nil return &emptypb.Empty{}, nil
@ -473,17 +473,17 @@ func (s *Service) SetIsAutomaticUpdateOn(_ context.Context, isOn *wrapperspb.Boo
func (s *Service) IsAutomaticUpdateOn(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { func (s *Service) IsAutomaticUpdateOn(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) {
s.log.Info("IsAutomaticUpdateOn") s.log.Info("IsAutomaticUpdateOn")
return wrapperspb.Bool(s.settings.GetBool(settings.AutoUpdateKey)), nil return wrapperspb.Bool(s.bridge.GetBool(settings.AutoUpdateKey)), nil
} }
func (s *Service) IsCacheOnDiskEnabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { func (s *Service) IsCacheOnDiskEnabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) {
s.log.Info("IsCacheOnDiskEnabled") s.log.Info("IsCacheOnDiskEnabled")
return wrapperspb.Bool(s.settings.GetBool(settings.CacheEnabledKey)), nil return wrapperspb.Bool(s.bridge.GetBool(settings.CacheEnabledKey)), nil
} }
func (s *Service) DiskCachePath(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { func (s *Service) DiskCachePath(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) {
s.log.Info("DiskCachePath") s.log.Info("DiskCachePath")
return wrapperspb.String(s.settings.Get(settings.CacheLocationKey)), nil return wrapperspb.String(s.bridge.Get(settings.CacheLocationKey)), nil
} }
func (s *Service) ChangeLocalCache(_ context.Context, change *ChangeLocalCacheRequest) (*emptypb.Empty, error) { func (s *Service) ChangeLocalCache(_ context.Context, change *ChangeLocalCacheRequest) (*emptypb.Empty, error) {
@ -492,10 +492,10 @@ func (s *Service) ChangeLocalCache(_ context.Context, change *ChangeLocalCacheRe
Info("DiskCachePath") Info("DiskCachePath")
defer func() { _ = s.SendEvent(NewCacheChangeLocalCacheFinishedEvent()) }() defer func() { _ = s.SendEvent(NewCacheChangeLocalCacheFinishedEvent()) }()
defer func() { _ = s.SendEvent(NewIsCacheOnDiskEnabledChanged(s.settings.GetBool(settings.CacheEnabledKey))) }() defer func() { _ = s.SendEvent(NewIsCacheOnDiskEnabledChanged(s.bridge.GetBool(settings.CacheEnabledKey))) }()
defer func() { _ = s.SendEvent(NewDiskCachePathChanged(s.settings.Get(settings.CacheCompressionKey))) }() defer func() { _ = s.SendEvent(NewDiskCachePathChanged(s.bridge.Get(settings.CacheCompressionKey))) }()
if change.EnableDiskCache != s.settings.GetBool(settings.CacheEnabledKey) { if change.EnableDiskCache != s.bridge.GetBool(settings.CacheEnabledKey) {
if change.EnableDiskCache { if change.EnableDiskCache {
if err := s.bridge.EnableCache(); err != nil { if err := s.bridge.EnableCache(); err != nil {
s.log.WithError(err).Error("Cannot enable disk cache") s.log.WithError(err).Error("Cannot enable disk cache")
@ -513,13 +513,13 @@ func (s *Service) ChangeLocalCache(_ context.Context, change *ChangeLocalCacheRe
path = path[1:] path = path[1:]
} }
if change.EnableDiskCache && path != s.settings.Get(settings.CacheLocationKey) { if change.EnableDiskCache && path != s.bridge.Get(settings.CacheLocationKey) {
if err := s.bridge.MigrateCache(s.settings.Get(settings.CacheLocationKey), path); err != nil { if err := s.bridge.MigrateCache(s.bridge.Get(settings.CacheLocationKey), path); err != nil {
s.log.WithError(err).Error("The local cache location could not be changed.") s.log.WithError(err).Error("The local cache location could not be changed.")
_ = s.SendEvent(NewCacheErrorEvent(CacheErrorType_CACHE_CANT_MOVE_ERROR)) _ = s.SendEvent(NewCacheErrorEvent(CacheErrorType_CACHE_CANT_MOVE_ERROR))
return &emptypb.Empty{}, nil return &emptypb.Empty{}, nil
} }
s.settings.Set(settings.CacheLocationKey, path) s.bridge.Set(settings.CacheLocationKey, path)
} }
_ = s.SendEvent(NewCacheLocationChangeSuccessEvent()) _ = s.SendEvent(NewCacheLocationChangeSuccessEvent())
@ -545,13 +545,13 @@ func (s *Service) IsDoHEnabled(context.Context, *emptypb.Empty) (*wrapperspb.Boo
func (s *Service) SetUseSslForSmtp(_ context.Context, useSsl *wrapperspb.BoolValue) (*emptypb.Empty, error) { //nolint:revive,stylecheck func (s *Service) SetUseSslForSmtp(_ context.Context, useSsl *wrapperspb.BoolValue) (*emptypb.Empty, error) { //nolint:revive,stylecheck
s.log.WithField("useSsl", useSsl.Value).Info("SetUseSslForSmtp") s.log.WithField("useSsl", useSsl.Value).Info("SetUseSslForSmtp")
if s.settings.GetBool(settings.SMTPSSLKey) == useSsl.Value { if s.bridge.GetBool(settings.SMTPSSLKey) == useSsl.Value {
return &emptypb.Empty{}, nil return &emptypb.Empty{}, nil
} }
defer func() { _ = s.SendEvent(NewMailSettingsUseSslForSmtpFinishedEvent()) }() defer func() { _ = s.SendEvent(NewMailSettingsUseSslForSmtpFinishedEvent()) }()
s.settings.SetBool(settings.SMTPSSLKey, useSsl.Value) s.bridge.SetBool(settings.SMTPSSLKey, useSsl.Value)
s.restart() s.restart()
return &emptypb.Empty{}, nil return &emptypb.Empty{}, nil
@ -560,7 +560,7 @@ func (s *Service) SetUseSslForSmtp(_ context.Context, useSsl *wrapperspb.BoolVal
func (s *Service) UseSslForSmtp(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { //nolint:revive,stylecheck func (s *Service) UseSslForSmtp(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { //nolint:revive,stylecheck
s.log.Info("UseSslForSmtp") s.log.Info("UseSslForSmtp")
return wrapperspb.Bool(s.settings.GetBool(settings.SMTPSSLKey)), nil return wrapperspb.Bool(s.bridge.GetBool(settings.SMTPSSLKey)), nil
} }
func (s *Service) Hostname(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { func (s *Service) Hostname(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) {
@ -572,13 +572,13 @@ func (s *Service) Hostname(context.Context, *emptypb.Empty) (*wrapperspb.StringV
func (s *Service) ImapPort(context.Context, *emptypb.Empty) (*wrapperspb.Int32Value, error) { func (s *Service) ImapPort(context.Context, *emptypb.Empty) (*wrapperspb.Int32Value, error) {
s.log.Info("ImapPort") s.log.Info("ImapPort")
return wrapperspb.Int32(int32(s.settings.GetInt(settings.IMAPPortKey))), nil return wrapperspb.Int32(int32(s.bridge.GetInt(settings.IMAPPortKey))), nil
} }
func (s *Service) SmtpPort(context.Context, *emptypb.Empty) (*wrapperspb.Int32Value, error) { //nolint:revive,stylecheck func (s *Service) SmtpPort(context.Context, *emptypb.Empty) (*wrapperspb.Int32Value, error) { //nolint:revive,stylecheck
s.log.Info("SmtpPort") s.log.Info("SmtpPort")
return wrapperspb.Int32(int32(s.settings.GetInt(settings.SMTPPortKey))), nil return wrapperspb.Int32(int32(s.bridge.GetInt(settings.SMTPPortKey))), nil
} }
func (s *Service) ChangePorts(_ context.Context, ports *ChangePortsRequest) (*emptypb.Empty, error) { func (s *Service) ChangePorts(_ context.Context, ports *ChangePortsRequest) (*emptypb.Empty, error) {
@ -586,8 +586,8 @@ func (s *Service) ChangePorts(_ context.Context, ports *ChangePortsRequest) (*em
defer func() { _ = s.SendEvent(NewMailSettingsChangePortFinishedEvent()) }() defer func() { _ = s.SendEvent(NewMailSettingsChangePortFinishedEvent()) }()
s.settings.SetInt(settings.IMAPPortKey, int(ports.ImapPort)) s.bridge.SetInt(settings.IMAPPortKey, int(ports.ImapPort))
s.settings.SetInt(settings.SMTPPortKey, int(ports.SmtpPort)) s.bridge.SetInt(settings.SMTPPortKey, int(ports.SmtpPort))
s.restart() s.restart()
return &emptypb.Empty{}, nil return &emptypb.Empty{}, nil

View File

@ -19,9 +19,7 @@ package grpc
import ( import (
"context" "context"
"time"
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/clientconfig"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb" "google.golang.org/protobuf/types/known/emptypb"
@ -108,25 +106,29 @@ func (s *Service) RemoveUser(_ context.Context, userID *wrapperspb.StringValue)
} }
func (s *Service) ConfigureUserAppleMail(_ context.Context, request *ConfigureAppleMailRequest) (*emptypb.Empty, error) { func (s *Service) ConfigureUserAppleMail(_ context.Context, request *ConfigureAppleMailRequest) (*emptypb.Empty, error) {
s.log.WithField("UserID", request.UserID).WithField("Address", request.Address).Info("ConfigureUserAppleMail") // NOTE: Configure apple mail should be part of bridge (and thus not need to deal with accounts/settings!
user, err := s.bridge.GetUser(request.UserID) /*
if err != nil { s.log.WithField("UserID", request.UserID).WithField("Address", request.Address).Info("ConfigureUserAppleMail")
s.log.WithField("userID", request.UserID).Error("Cannot configure AppleMail for user")
return nil, status.Error(codes.NotFound, "Cannot configure AppleMail for user")
}
needRestart, err := clientconfig.ConfigureAppleMail(user, request.Address, s.settings) user, err := s.bridge.GetUser(request.UserID)
if err != nil { if err != nil {
s.log.WithError(err).Error("Apple Mail config failed") s.log.WithField("userID", request.UserID).Error("Cannot configure AppleMail for user")
return nil, status.Error(codes.Internal, "Apple Mail config failed") return nil, status.Error(codes.NotFound, "Cannot configure AppleMail for user")
} }
if needRestart { needRestart, err := clientconfig.ConfigureAppleMail(user, request.Address, s.settings)
// There is delay needed for external window to open if err != nil {
time.Sleep(2 * time.Second) s.log.WithError(err).Error("Apple Mail config failed")
s.restart() return nil, status.Error(codes.Internal, "Apple Mail config failed")
} }
if needRestart {
// There is delay needed for external window to open
time.Sleep(2 * time.Second)
s.restart()
}
*/
return &emptypb.Empty{}, nil return &emptypb.Empty{}, nil
} }

View File

@ -22,6 +22,7 @@ import (
"crypto/tls" "crypto/tls"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/config/settings"
"github.com/ProtonMail/proton-bridge/v2/internal/updater" "github.com/ProtonMail/proton-bridge/v2/internal/updater"
"github.com/ProtonMail/proton-bridge/v2/pkg/pmapi" "github.com/ProtonMail/proton-bridge/v2/pkg/pmapi"
) )
@ -84,6 +85,13 @@ type Bridger interface {
GetCurrentUserAgent() string GetCurrentUserAgent() string
SetCurrentPlatform(string) SetCurrentPlatform(string)
Get(settings.Key) string
Set(settings.Key, string)
GetBool(settings.Key) bool
SetBool(settings.Key, bool)
GetInt(settings.Key) int
SetInt(settings.Key, int)
// -- old -- // -- old --
ReportBug(osType, osVersion, description, accountName, address, emailClient string, attachLogs bool) error ReportBug(osType, osVersion, description, accountName, address, emailClient string, attachLogs bool) error

View File

@ -65,7 +65,7 @@ type imapBackend struct {
} }
type settingsProvider interface { type settingsProvider interface {
GetInt(string) int GetInt(settings.Key) int
} }
// NewIMAPBackend returns struct implementing go-imap/backend interface. // NewIMAPBackend returns struct implementing go-imap/backend interface.

View File

@ -22,6 +22,7 @@ import (
"time" "time"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/config/settings"
"github.com/ProtonMail/proton-bridge/v2/internal/users" "github.com/ProtonMail/proton-bridge/v2/internal/users"
"github.com/ProtonMail/proton-bridge/v2/pkg/listener" "github.com/ProtonMail/proton-bridge/v2/pkg/listener"
goSMTPBackend "github.com/emersion/go-smtp" goSMTPBackend "github.com/emersion/go-smtp"
@ -33,7 +34,7 @@ type panicHandler interface {
} }
type settingsProvider interface { type settingsProvider interface {
GetBool(string) bool GetBool(settings.Key) bool
} }
type smtpBackend struct { type smtpBackend struct {

View File

@ -37,9 +37,9 @@ type Installer interface {
} }
type Settings interface { type Settings interface {
Get(string) string Get(settings.Key) string
Set(string, string) Set(settings.Key, string)
GetFloat64(string) float64 GetFloat64(settings.Key) float64
} }
type Updater struct { type Updater struct {