This repository has been archived by the owner on Jul 7, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathpush.go
100 lines (78 loc) · 2.16 KB
/
push.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package push
import (
"context"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"io/ioutil"
zpErrors "berty.tech/zero-push/errors"
proto "berty.tech/zero-push/proto/push"
"github.com/pkg/errors"
)
type Dispatcher interface {
CanDispatch(*proto.PushDestination) bool
Dispatch(*proto.PushData, *proto.PushDestination) error
}
type Manager struct {
dispatchers []Dispatcher
tokenDecrypter crypto.Decrypter
}
func (m *Manager) Dispatch(pushData *proto.PushData, pushDestination *proto.PushDestination) error {
var err error
logger().Info("dispatch push")
for _, dispatcher := range m.dispatchers {
if !dispatcher.CanDispatch(pushDestination) {
continue
}
if err = dispatcher.Dispatch(pushData, pushDestination); err == nil {
return nil
}
}
if err != nil {
return err
}
return zpErrors.ErrPushUnknownProvider
}
func (m *Manager) PushTo(ctx context.Context, pushAttrs *proto.PushData) error {
logger().Info("Sending push to device")
identifier, err := m.Decrypt(pushAttrs.PushIdentifier)
if err != nil {
return errors.Wrap(err, zpErrors.ErrPushUnknownDestination.Error())
}
pushDestination := &proto.PushDestination{}
if err := pushDestination.Unmarshal(identifier); err != nil {
return errors.Wrap(err, zpErrors.ErrPushUnknownDestination.Error())
}
if err := m.Dispatch(&proto.PushData{
PushIdentifier: pushAttrs.PushIdentifier,
Envelope: pushAttrs.Envelope,
Priority: pushAttrs.Priority,
}, pushDestination); err != nil {
return err
}
return nil
}
func (m *Manager) Decrypt(msg []byte) (plaintext []byte, err error) {
return m.tokenDecrypter.Decrypt(rand.Reader, msg, nil)
}
func LoadAndParsePrivateKey(path string) (*rsa.PrivateKey, error) {
privPem, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
block, _ := pem.Decode(privPem)
rsaKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, zpErrors.ErrInvalidPrivateKey
}
return rsaKey, nil
}
func NewManager(tokenDecrypter crypto.Decrypter, dispatchers ...Dispatcher) *Manager {
pushManager := &Manager{
dispatchers: dispatchers,
tokenDecrypter: tokenDecrypter,
}
return pushManager
}