1
0

Other(refactor): Move client config to bridge

This commit is contained in:
James Houlahan
2022-08-22 15:55:16 +02:00
committed by Jakub
parent 0c7453684b
commit 40b3f77db0
5 changed files with 106 additions and 130 deletions

View File

@ -1,76 +0,0 @@
// 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 clientconfig provides automatic config of IMAP and SMTP.
// For now only for Apple Mail.
package clientconfig
import (
"errors"
"github.com/ProtonMail/proton-bridge/v2/internal/config/settings"
"github.com/ProtonMail/proton-bridge/v2/internal/config/useragent"
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/types"
"github.com/sirupsen/logrus"
)
type AutoConfig interface {
Name() string
Configure(imapPort int, smtpPort int, imapSSl, smtpSSL bool, user types.User, address string) error
}
var (
available = map[string]AutoConfig{} //nolint:gochecknoglobals
ErrNotAvailable = errors.New("configuration not available")
)
const AppleMailClient = "Apple Mail"
func ConfigureAppleMail(user types.User, address string, s *settings.Settings) (needRestart bool, err error) {
return configure(AppleMailClient, user, address, s)
}
func configure(configName string, user types.User, address string, s *settings.Settings) (needRestart bool, err error) {
log := logrus.WithField("pkg", "client_config").WithField("client", configName)
config, ok := available[configName]
if !ok {
return false, ErrNotAvailable
}
imapPort := s.GetInt(settings.IMAPPortKey)
imapSSL := false
smtpPort := s.GetInt(settings.SMTPPortKey)
smtpSSL := s.GetBool(settings.SMTPSSLKey)
if address == "" {
address = user.GetPrimaryAddress()
}
if configName == AppleMailClient {
// If configuring apple mail for Catalina or newer, users should use SSL.
needRestart = false
if !smtpSSL && useragent.IsCatalinaOrNewer() {
smtpSSL = true
s.SetBool(settings.SMTPSSLKey, true)
log.Warn("Detected Catalina or newer with bad SMTP SSL settings, now using SSL, bridge needs to restart")
needRestart = true
}
}
return needRestart, config.Configure(imapPort, smtpPort, imapSSL, smtpSSL, user, address)
}

View File

@ -1,129 +0,0 @@
// 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/>.
//go:build darwin
// +build darwin
package clientconfig
import (
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/config/useragent"
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/types"
"github.com/ProtonMail/proton-bridge/v2/pkg/mobileconfig"
"golang.org/x/sys/execabs"
)
const (
bigSurPreferencesPane = "/System/Library/PreferencePanes/Profiles.prefPane"
venturaPreferencesPane = "x-apple.systempreferences:com.apple.preferences.configurationprofiles"
)
func init() { //nolint:gochecknoinits
available[AppleMailClient] = &appleMail{}
}
type appleMail struct{}
func (c *appleMail) Name() string { return AppleMailClient }
func (c *appleMail) Configure(imapPort, smtpPort int, imapSSL, smtpSSL bool, user types.User, address string) error {
mc := prepareMobileConfig(imapPort, smtpPort, imapSSL, smtpSSL, user, address)
confPath, err := saveConfigTemporarily(mc)
if err != nil {
return err
}
if useragent.IsBigSurOrNewer() {
prefPane := bigSurPreferencesPane
if useragent.IsVenturaOrNewer() {
prefPane = venturaPreferencesPane
}
return execabs.Command("open", prefPane, confPath).Run() //nolint:gosec // G204 open command is safe, mobileconfig is generated by us
}
return execabs.Command("open", confPath).Run() //nolint:gosec // G204 open command is safe, mobileconfig is generated by us
}
func prepareMobileConfig(imapPort, smtpPort int, imapSSL, smtpSSL bool, user types.User, address string) *mobileconfig.Config {
displayName := address
addresses := address
if user.IsCombinedAddressMode() {
displayName = user.GetPrimaryAddress()
addresses = strings.Join(user.GetAddresses(), ",")
}
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
return &mobileconfig.Config{
EmailAddress: addresses,
DisplayName: displayName,
Identifier: "protonmail " + displayName + timestamp,
IMAP: &mobileconfig.IMAP{
Hostname: bridge.Host,
Port: imapPort,
TLS: imapSSL,
Username: displayName,
Password: user.GetBridgePassword(),
},
SMTP: &mobileconfig.SMTP{
Hostname: bridge.Host,
Port: smtpPort,
TLS: smtpSSL,
Username: displayName,
},
}
}
func saveConfigTemporarily(mc *mobileconfig.Config) (fname string, err error) {
dir, err := ioutil.TempDir("", "protonmail-autoconfig")
if err != nil {
return
}
// Make sure the temporary file is deleted.
go func() {
<-time.After(10 * time.Minute)
_ = os.RemoveAll(dir)
}()
// Make sure the file is only readable for the current user.
fname = filepath.Clean(filepath.Join(dir, "protonmail.mobileconfig"))
f, err := os.OpenFile(fname, os.O_RDWR|os.O_CREATE, 0o600) //nolint:gosec
if err != nil {
return
}
if err = mc.WriteOut(f); err != nil {
_ = f.Close()
return
}
_ = f.Close()
return
}

View File

@ -19,6 +19,7 @@ package grpc
import (
"context"
"time"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@ -106,29 +107,20 @@ func (s *Service) RemoveUser(_ context.Context, userID *wrapperspb.StringValue)
}
func (s *Service) ConfigureUserAppleMail(_ context.Context, request *ConfigureAppleMailRequest) (*emptypb.Empty, error) {
// NOTE: Configure apple mail should be part of bridge (and thus not need to deal with accounts/settings!
s.log.WithField("UserID", request.UserID).WithField("Address", request.Address).Info("ConfigureUserAppleMail")
/*
s.log.WithField("UserID", request.UserID).WithField("Address", request.Address).Info("ConfigureUserAppleMail")
restart, err := s.bridge.ConfigureAppleMail(request.UserID, request.Address)
if err != nil {
s.log.WithField("userID", request.UserID).Error("Cannot configure AppleMail for user")
return nil, status.Error(codes.Internal, "Apple Mail config failed")
}
user, err := s.bridge.GetUser(request.UserID)
if err != nil {
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)
if err != nil {
s.log.WithError(err).Error("Apple Mail config failed")
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()
}
*/
// There is delay needed for external window to open.
if restart {
s.log.Warn("Detected Catalina or newer with bad SMTP SSL settings, now using SSL, bridge needs to restart")
time.Sleep(2 * time.Second)
s.restart()
}
return &emptypb.Empty{}, nil
}

View File

@ -92,6 +92,8 @@ type Bridger interface {
GetInt(settings.Key) int
SetInt(settings.Key, int)
ConfigureAppleMail(userID, address string) (bool, error)
// -- old --
ReportBug(osType, osVersion, description, accountName, address, emailClient string, attachLogs bool) error