forked from Silverfish/proton-bridge
Other(refactor): Use normal value + mutex for user.apiUser
This commit is contained in:
@ -25,6 +25,7 @@ import (
|
||||
"github.com/ProtonMail/gluon/queue"
|
||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||
"github.com/ProtonMail/proton-bridge/v2/internal/events"
|
||||
"github.com/ProtonMail/proton-bridge/v2/internal/safe"
|
||||
"github.com/ProtonMail/proton-bridge/v2/internal/vault"
|
||||
"github.com/bradenaw/juniper/xslices"
|
||||
"gitlab.protontech.ch/go/liteapi"
|
||||
@ -61,13 +62,15 @@ func (user *User) handleAPIEvent(ctx context.Context, event liteapi.Event) error
|
||||
|
||||
// handleUserEvent handles the given user event.
|
||||
func (user *User) handleUserEvent(_ context.Context, userEvent liteapi.User) error {
|
||||
user.apiUser.Save(userEvent)
|
||||
return safe.LockRet(func() error {
|
||||
user.apiUser = userEvent
|
||||
|
||||
user.eventCh.Enqueue(events.UserChanged{
|
||||
UserID: user.ID(),
|
||||
})
|
||||
user.eventCh.Enqueue(events.UserChanged{
|
||||
UserID: user.ID(),
|
||||
})
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}, &user.apiUserLock)
|
||||
}
|
||||
|
||||
// handleAddressEvents handles the given address events.
|
||||
|
||||
@ -21,19 +21,20 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||
"github.com/ProtonMail/proton-bridge/v2/internal/safe"
|
||||
"gitlab.protontech.ch/go/liteapi"
|
||||
)
|
||||
|
||||
func (user *User) withUserKR(fn func(*crypto.KeyRing) error) error {
|
||||
return user.apiUser.LoadErr(func(apiUser liteapi.User) error {
|
||||
userKR, err := apiUser.Keys.Unlock(user.vault.KeyPass(), nil)
|
||||
return safe.RLockRet(func() error {
|
||||
userKR, err := user.apiUser.Keys.Unlock(user.vault.KeyPass(), nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unlock user keys: %w", err)
|
||||
}
|
||||
defer userKR.ClearPrivateParams()
|
||||
|
||||
return fn(userKR)
|
||||
})
|
||||
}, &user.apiUserLock)
|
||||
}
|
||||
|
||||
func (user *User) withAddrKR(addrID string, fn func(*crypto.KeyRing, *crypto.KeyRing) error) error {
|
||||
|
||||
@ -52,7 +52,9 @@ type User struct {
|
||||
client *liteapi.Client
|
||||
eventCh *queue.QueuedChannel[events.Event]
|
||||
|
||||
apiUser *safe.Value[liteapi.User]
|
||||
apiUser liteapi.User
|
||||
apiUserLock sync.RWMutex
|
||||
|
||||
apiAddrs *safe.Map[string, liteapi.Address]
|
||||
apiLabels *safe.Map[string, liteapi.Label]
|
||||
updateCh *safe.Map[string, *queue.QueuedChannel[imap.Update]]
|
||||
@ -131,7 +133,7 @@ func New(
|
||||
client: client,
|
||||
eventCh: queue.NewQueuedChannel[events.Event](0, 0),
|
||||
|
||||
apiUser: safe.NewValue(apiUser),
|
||||
apiUser: apiUser,
|
||||
apiAddrs: safe.NewMapFrom(groupBy(apiAddrs, func(addr liteapi.Address) string { return addr.ID }), sortAddr),
|
||||
apiLabels: safe.NewMapFrom(groupBy(apiLabels, func(label liteapi.Label) string { return label.ID }), nil),
|
||||
updateCh: safe.NewMapFrom(updateCh, nil),
|
||||
@ -196,29 +198,29 @@ func New(
|
||||
|
||||
// ID returns the user's ID.
|
||||
func (user *User) ID() string {
|
||||
return safe.LoadRet(user.apiUser, func(apiUser liteapi.User) string {
|
||||
return apiUser.ID
|
||||
})
|
||||
return safe.RLockRet(func() string {
|
||||
return user.apiUser.ID
|
||||
}, &user.apiUserLock)
|
||||
}
|
||||
|
||||
// Name returns the user's username.
|
||||
func (user *User) Name() string {
|
||||
return safe.LoadRet(user.apiUser, func(apiUser liteapi.User) string {
|
||||
return apiUser.Name
|
||||
})
|
||||
return safe.RLockRet(func() string {
|
||||
return user.apiUser.Name
|
||||
}, &user.apiUserLock)
|
||||
}
|
||||
|
||||
// Match matches the given query against the user's username and email addresses.
|
||||
func (user *User) Match(query string) bool {
|
||||
return safe.LoadRet(user.apiUser, func(apiUser liteapi.User) bool {
|
||||
if query == apiUser.Name {
|
||||
return safe.RLockRet(func() bool {
|
||||
if query == user.apiUser.Name {
|
||||
return true
|
||||
}
|
||||
|
||||
return user.apiAddrs.HasFunc(func(_ string, addr liteapi.Address) bool {
|
||||
return addr.Email == query
|
||||
})
|
||||
})
|
||||
}, &user.apiUserLock)
|
||||
}
|
||||
|
||||
// Emails returns all the user's email addresses via the callback.
|
||||
@ -305,16 +307,16 @@ func (user *User) BridgePass() []byte {
|
||||
|
||||
// UsedSpace returns the total space used by the user on the API.
|
||||
func (user *User) UsedSpace() int {
|
||||
return safe.LoadRet(user.apiUser, func(apiUser liteapi.User) int {
|
||||
return apiUser.UsedSpace
|
||||
})
|
||||
return safe.RLockRet(func() int {
|
||||
return user.apiUser.UsedSpace
|
||||
}, &user.apiUserLock)
|
||||
}
|
||||
|
||||
// MaxSpace returns the amount of space the user can use on the API.
|
||||
func (user *User) MaxSpace() int {
|
||||
return safe.LoadRet(user.apiUser, func(apiUser liteapi.User) int {
|
||||
return apiUser.MaxSpace
|
||||
})
|
||||
return safe.RLockRet(func() int {
|
||||
return user.apiUser.MaxSpace
|
||||
}, &user.apiUserLock)
|
||||
}
|
||||
|
||||
// GetEventCh returns a channel which notifies of events happening to the user (such as deauth, address change).
|
||||
|
||||
Reference in New Issue
Block a user