Other(refactor): Move client config to bridge
This commit is contained in:
70
internal/bridge/configure.go
Normal file
70
internal/bridge/configure.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// 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 (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ProtonMail/proton-bridge/v2/internal/clientconfig"
|
||||||
|
"github.com/ProtonMail/proton-bridge/v2/internal/config/settings"
|
||||||
|
"github.com/ProtonMail/proton-bridge/v2/internal/config/useragent"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (b *Bridge) ConfigureAppleMail(userID, address string) (bool, error) {
|
||||||
|
user, err := b.GetUser(userID)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if address == "" {
|
||||||
|
address = user.GetPrimaryAddress()
|
||||||
|
}
|
||||||
|
|
||||||
|
username := address
|
||||||
|
addresses := address
|
||||||
|
|
||||||
|
if user.IsCombinedAddressMode() {
|
||||||
|
username = user.GetPrimaryAddress()
|
||||||
|
addresses = strings.Join(user.GetAddresses(), ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
restart = false
|
||||||
|
smtpSSL = b.settings.GetBool(settings.SMTPSSLKey)
|
||||||
|
)
|
||||||
|
|
||||||
|
// If configuring apple mail for Catalina or newer, users should use SSL.
|
||||||
|
if useragent.IsCatalinaOrNewer() && !smtpSSL {
|
||||||
|
smtpSSL = true
|
||||||
|
restart = true
|
||||||
|
b.settings.SetBool(settings.SMTPSSLKey, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := (&clientconfig.AppleMail{}).Configure(
|
||||||
|
Host,
|
||||||
|
b.settings.GetInt(settings.IMAPPortKey),
|
||||||
|
b.settings.GetInt(settings.SMTPPortKey),
|
||||||
|
false, smtpSSL,
|
||||||
|
username, addresses,
|
||||||
|
user.GetBridgePassword(),
|
||||||
|
); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return restart, nil
|
||||||
|
}
|
||||||
@ -15,9 +15,6 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//go:build darwin
|
|
||||||
// +build darwin
|
|
||||||
|
|
||||||
package clientconfig
|
package clientconfig
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -25,12 +22,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"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/config/useragent"
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/types"
|
|
||||||
"github.com/ProtonMail/proton-bridge/v2/pkg/mobileconfig"
|
"github.com/ProtonMail/proton-bridge/v2/pkg/mobileconfig"
|
||||||
"golang.org/x/sys/execabs"
|
"golang.org/x/sys/execabs"
|
||||||
)
|
)
|
||||||
@ -40,16 +34,15 @@ const (
|
|||||||
venturaPreferencesPane = "x-apple.systempreferences:com.apple.preferences.configurationprofiles"
|
venturaPreferencesPane = "x-apple.systempreferences:com.apple.preferences.configurationprofiles"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { //nolint:gochecknoinits
|
type AppleMail struct{}
|
||||||
available[AppleMailClient] = &appleMail{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type appleMail struct{}
|
func (c *AppleMail) Configure(
|
||||||
|
hostname string,
|
||||||
func (c *appleMail) Name() string { return AppleMailClient }
|
imapPort, smtpPort int,
|
||||||
|
imapSSL, smtpSSL bool,
|
||||||
func (c *appleMail) Configure(imapPort, smtpPort int, imapSSL, smtpSSL bool, user types.User, address string) error {
|
username, addresses, password string,
|
||||||
mc := prepareMobileConfig(imapPort, smtpPort, imapSSL, smtpSSL, user, address)
|
) error {
|
||||||
|
mc := prepareMobileConfig(hostname, imapPort, smtpPort, imapSSL, smtpSSL, username, addresses, password)
|
||||||
|
|
||||||
confPath, err := saveConfigTemporarily(mc)
|
confPath, err := saveConfigTemporarily(mc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -69,33 +62,28 @@ func (c *appleMail) Configure(imapPort, smtpPort int, imapSSL, smtpSSL bool, use
|
|||||||
return execabs.Command("open", 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 {
|
func prepareMobileConfig(
|
||||||
displayName := address
|
hostname string,
|
||||||
addresses := address
|
imapPort, smtpPort int,
|
||||||
|
imapSSL, smtpSSL bool,
|
||||||
if user.IsCombinedAddressMode() {
|
username, addresses, password string,
|
||||||
displayName = user.GetPrimaryAddress()
|
) *mobileconfig.Config {
|
||||||
addresses = strings.Join(user.GetAddresses(), ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
|
|
||||||
|
|
||||||
return &mobileconfig.Config{
|
return &mobileconfig.Config{
|
||||||
|
DisplayName: username,
|
||||||
EmailAddress: addresses,
|
EmailAddress: addresses,
|
||||||
DisplayName: displayName,
|
Identifier: "protonmail " + username + strconv.FormatInt(time.Now().Unix(), 10),
|
||||||
Identifier: "protonmail " + displayName + timestamp,
|
|
||||||
IMAP: &mobileconfig.IMAP{
|
IMAP: &mobileconfig.IMAP{
|
||||||
Hostname: bridge.Host,
|
Hostname: hostname,
|
||||||
Port: imapPort,
|
Port: imapPort,
|
||||||
TLS: imapSSL,
|
TLS: imapSSL,
|
||||||
Username: displayName,
|
Username: username,
|
||||||
Password: user.GetBridgePassword(),
|
Password: password,
|
||||||
},
|
},
|
||||||
SMTP: &mobileconfig.SMTP{
|
SMTP: &mobileconfig.SMTP{
|
||||||
Hostname: bridge.Host,
|
Hostname: hostname,
|
||||||
Port: smtpPort,
|
Port: smtpPort,
|
||||||
TLS: smtpSSL,
|
TLS: smtpSSL,
|
||||||
Username: displayName,
|
Username: username,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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)
|
|
||||||
}
|
|
||||||
@ -19,6 +19,7 @@ package grpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"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) {
|
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")
|
||||||
|
|
||||||
/*
|
restart, err := s.bridge.ConfigureAppleMail(request.UserID, request.Address)
|
||||||
s.log.WithField("UserID", request.UserID).WithField("Address", request.Address).Info("ConfigureUserAppleMail")
|
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)
|
// There is delay needed for external window to open.
|
||||||
if err != nil {
|
if restart {
|
||||||
s.log.WithField("userID", request.UserID).Error("Cannot configure AppleMail for user")
|
s.log.Warn("Detected Catalina or newer with bad SMTP SSL settings, now using SSL, bridge needs to restart")
|
||||||
return nil, status.Error(codes.NotFound, "Cannot configure AppleMail for user")
|
time.Sleep(2 * time.Second)
|
||||||
}
|
s.restart()
|
||||||
|
}
|
||||||
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()
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return &emptypb.Empty{}, nil
|
return &emptypb.Empty{}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -92,6 +92,8 @@ type Bridger interface {
|
|||||||
GetInt(settings.Key) int
|
GetInt(settings.Key) int
|
||||||
SetInt(settings.Key, int)
|
SetInt(settings.Key, int)
|
||||||
|
|
||||||
|
ConfigureAppleMail(userID, address string) (bool, error)
|
||||||
|
|
||||||
// -- old --
|
// -- old --
|
||||||
|
|
||||||
ReportBug(osType, osVersion, description, accountName, address, emailClient string, attachLogs bool) error
|
ReportBug(osType, osVersion, description, accountName, address, emailClient string, attachLogs bool) error
|
||||||
|
|||||||
Reference in New Issue
Block a user