mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-11 13:16:53 +00:00
Other(refactor): Remove unencrypted recipient confirmation
This commit is contained in:
@ -1,70 +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 confirmer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NOTE: For now, Confirmer only supports bool values but it could easily be made generic.
|
||||
|
||||
// Confirmer is used to ask for some value (e.g. a confirmation from a GUI element)
|
||||
// in a threadsafe manner and retrieve that value later.
|
||||
type Confirmer struct {
|
||||
requests map[string]*Request
|
||||
locker sync.Locker
|
||||
}
|
||||
|
||||
func New() *Confirmer {
|
||||
return &Confirmer{
|
||||
requests: make(map[string]*Request),
|
||||
locker: &sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
// NewRequest creates a new request object that waits up to the given amount of time for the result.
|
||||
func (c *Confirmer) NewRequest(timeout time.Duration) *Request {
|
||||
c.locker.Lock()
|
||||
defer c.locker.Unlock()
|
||||
|
||||
req := newRequest(timeout)
|
||||
|
||||
c.requests[req.ID()] = req
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
// SetResult sets the result value of the request with the given ID.
|
||||
func (c *Confirmer) SetResult(id string, value bool) error {
|
||||
c.locker.Lock()
|
||||
defer c.locker.Unlock()
|
||||
|
||||
req, ok := c.requests[id]
|
||||
if !ok {
|
||||
return errors.New("no such request")
|
||||
}
|
||||
|
||||
req.ch <- value
|
||||
|
||||
close(req.ch)
|
||||
delete(c.requests, id)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1,120 +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 confirmer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestConfirmerYes(t *testing.T) {
|
||||
c := New()
|
||||
|
||||
req := c.NewRequest(1 * time.Second)
|
||||
|
||||
go func() {
|
||||
assert.NoError(t, c.SetResult(req.ID(), true))
|
||||
}()
|
||||
|
||||
res, err := req.Result()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, res)
|
||||
}
|
||||
|
||||
func TestConfirmerNo(t *testing.T) {
|
||||
c := New()
|
||||
|
||||
req := c.NewRequest(1 * time.Second)
|
||||
|
||||
go func() {
|
||||
assert.NoError(t, c.SetResult(req.ID(), false))
|
||||
}()
|
||||
|
||||
res, err := req.Result()
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, res)
|
||||
}
|
||||
|
||||
func TestConfirmerTimeout(t *testing.T) {
|
||||
c := New()
|
||||
|
||||
req := c.NewRequest(1 * time.Second)
|
||||
|
||||
go func() {
|
||||
time.Sleep(2 * time.Second)
|
||||
assert.NoError(t, c.SetResult(req.ID(), true))
|
||||
}()
|
||||
|
||||
_, err := req.Result()
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestConfirmerMultipleResultCalls(t *testing.T) {
|
||||
c := New()
|
||||
|
||||
req := c.NewRequest(1 * time.Second)
|
||||
|
||||
go func() {
|
||||
assert.NoError(t, c.SetResult(req.ID(), true))
|
||||
}()
|
||||
|
||||
res, err := req.Result()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, res)
|
||||
|
||||
_, errAgain := req.Result()
|
||||
assert.Error(t, errAgain)
|
||||
}
|
||||
|
||||
func TestConfirmerMultipleSimultaneousResultCalls(t *testing.T) {
|
||||
c := New()
|
||||
|
||||
req := c.NewRequest(1 * time.Second)
|
||||
|
||||
go func() {
|
||||
time.Sleep(1 * time.Second)
|
||||
assert.NoError(t, c.SetResult(req.ID(), true))
|
||||
}()
|
||||
|
||||
// We just check that nothing panics. We can't know which Result() will get the result though.
|
||||
|
||||
go func() { _, _ = req.Result() }()
|
||||
go func() { _, _ = req.Result() }()
|
||||
go func() { _, _ = req.Result() }()
|
||||
|
||||
_, _ = req.Result()
|
||||
}
|
||||
|
||||
func TestConfirmerMultipleSetResultCalls(t *testing.T) {
|
||||
c := New()
|
||||
|
||||
req := c.NewRequest(1 * time.Second)
|
||||
|
||||
go func() {
|
||||
assert.NoError(t, c.SetResult(req.ID(), true))
|
||||
assert.Error(t, c.SetResult(req.ID(), true))
|
||||
assert.Error(t, c.SetResult(req.ID(), true))
|
||||
assert.Error(t, c.SetResult(req.ID(), true))
|
||||
}()
|
||||
|
||||
res, err := req.Result()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, res)
|
||||
}
|
||||
@ -1,70 +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 confirmer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// Request provides a result when it becomes available.
|
||||
type Request struct {
|
||||
uuid string
|
||||
ch chan bool
|
||||
timeout time.Duration
|
||||
|
||||
expired bool
|
||||
locker sync.Locker
|
||||
}
|
||||
|
||||
func newRequest(timeout time.Duration) *Request {
|
||||
return &Request{
|
||||
uuid: uuid.New().String(),
|
||||
ch: make(chan bool),
|
||||
timeout: timeout,
|
||||
locker: &sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
// ID returns the request's ID, used to set the request's value.
|
||||
func (r *Request) ID() string {
|
||||
return r.uuid
|
||||
}
|
||||
|
||||
// Result returns the result or an error if it is not available within the request timeout.
|
||||
func (r *Request) Result() (bool, error) {
|
||||
r.locker.Lock()
|
||||
defer r.locker.Unlock()
|
||||
|
||||
if r.expired {
|
||||
return false, errors.New("this result has expired")
|
||||
}
|
||||
|
||||
defer func() { r.expired = true }()
|
||||
|
||||
select {
|
||||
case res := <-r.ch:
|
||||
return res, nil
|
||||
|
||||
case <-time.After(r.timeout):
|
||||
return false, errors.New("timed out waiting for result")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user