-
Notifications
You must be signed in to change notification settings - Fork 0
/
bind.go
123 lines (116 loc) · 2.96 KB
/
bind.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package service
import (
"context"
"database/sql"
"github.com/gernest/signedjson"
"github.com/gernest/sydent-go/core"
"github.com/gernest/sydent-go/models"
)
const associationLifetime = 100 * 365 * 24 * 60 * 60 * 1000
func AddBinding(coreContext *core.Ctx) func(context.Context, string, string, string) (signedjson.Message, error) {
key := coreContext.Config.Server.Crypto.Key()
serverName := coreContext.Config.Server.Name
sign := Signer(coreContext)
return func(ctx context.Context, medium, address, mxid string) (signedjson.Message, error) {
createdAt := models.Time()
expiresAt := createdAt + associationLifetime
as := &models.Association{
Medium: medium,
Address: address,
MatrixID: mxid,
Timestamp: createdAt,
NotBefore: createdAt,
NotAfter: expiresAt,
}
err := coreContext.Store.LocalAddOrUpdateAssociation(ctx, as)
if err != nil {
return nil, err
}
tokens, err := coreContext.Store.GetTokens(ctx, medium, address)
if err != nil {
return nil, err
}
var invites []map[string]interface{}
for _, token := range tokens {
m := token.ToMap()
m["mxid"] = mxid
signed := signedjson.Message{
"mxid": mxid,
"token": m["token"],
}
err = key.Sign(signed, serverName)
if err != nil {
return nil, err
}
m["signed"] = signed
invites = append(invites, m)
}
if len(invites) > 0 {
as.ExtraFields = map[string]interface{}{
"invites": invites,
}
err := coreContext.Store.MarkTokensAsSent(ctx, medium, address)
if err != nil {
return nil, err
}
}
a, err := sign(as)
if err != nil {
return nil, err
}
return a, nil
}
}
func RemoveBinding(coreContext *core.Ctx) func(context.Context, *models.Association) error {
push := LocalPusher(coreContext)
return func(ctx context.Context, as *models.Association) error {
err := coreContext.Store.LocalRemoveAssociation(ctx, as)
if err != nil {
return err
}
return push(ctx)
}
}
func LocalPusher(coreContext *core.Ctx) func(context.Context) error {
push := PushLocal(coreContext)
name := coreContext.Config.Server.Name
db := coreContext.Store
sign := Signer(coreContext)
return func(ctx context.Context) error {
lastID, err := db.GlobalLastIDFromServer(ctx, name)
if err != nil {
if err != sql.ErrNoRows {
return err
}
lastID = -1
}
as, err := db.GetAssociationsAfterID(ctx, lastID, 0)
if err != nil {
return err
}
out := make([]Association, len(as))
for k, v := range as {
a, err := sign(&v)
if err != nil {
return err
}
out[k] = Association{
OriginID: v.ID,
SignedAssociation: a,
}
}
return push(ctx, out)
}
}
func Signer(coreContext *core.Ctx) func(*models.Association) (signedjson.Message, error) {
key := coreContext.Config.Server.Crypto.Key()
name := coreContext.Config.Server.Name
return func(as *models.Association) (signedjson.Message, error) {
m := as.ToMap()
err := key.Sign(m, name)
if err != nil {
return nil, err
}
return m, nil
}
}