+5
cmd/knotserver/main.go
+5
cmd/knotserver/main.go
+2
knotserver/config/config.go
+2
knotserver/config/config.go
+6
-8
knotserver/db/init.go
+6
-8
knotserver/db/init.go
···
17
17
}
18
18
19
19
_, err = db.Exec(`
20
+
create table if not exists known_dids (
21
+
did text primary key
22
+
);
20
23
create table if not exists public_keys (
21
24
id integer primary key autoincrement,
22
25
did text not null,
23
-
name text not null,
24
26
key text not null,
25
27
created timestamp default current_timestamp,
26
-
unique(did, name, key)
27
-
);
28
-
create table if not exists users (
29
-
id integer primary key autoincrement,
30
-
did text not null,
31
-
unique(did),
32
-
foreign key (did) references public_keys(did) on delete cascade
28
+
unique(did, key),
29
+
foreign key (did) references known_dids(did) on delete cascade
33
30
);
31
+
34
32
create table if not exists repos (
35
33
id integer primary key autoincrement,
36
34
did text not null,
+44
knotserver/db/known_dids.go
+44
knotserver/db/known_dids.go
···
1
+
package db
2
+
3
+
func (d *DB) AddDID(did string) error {
4
+
_, err := d.db.Exec(`insert into known_dids (did) values (?)`, did)
5
+
return err
6
+
}
7
+
8
+
func (d *DB) RemoveDID(did string) error {
9
+
_, err := d.db.Exec(`delete from known_dids where did = ?`, did)
10
+
return err
11
+
}
12
+
13
+
func (d *DB) GetAllDIDs() ([]string, error) {
14
+
var dids []string
15
+
16
+
rows, err := d.db.Query(`select did from known_dids`)
17
+
if err != nil {
18
+
return nil, err
19
+
}
20
+
defer rows.Close()
21
+
22
+
for rows.Next() {
23
+
var did string
24
+
if err := rows.Scan(&did); err != nil {
25
+
return nil, err
26
+
}
27
+
dids = append(dids, did)
28
+
}
29
+
30
+
if err := rows.Err(); err != nil {
31
+
return nil, err
32
+
}
33
+
34
+
return dids, nil
35
+
}
36
+
37
+
func (d *DB) HasKnownDIDs() bool {
38
+
var count int
39
+
err := d.db.QueryRow(`select count(*) from known_dids`).Scan(&count)
40
+
if err != nil {
41
+
return false
42
+
}
43
+
return count > 0
44
+
}
+6
-8
knotserver/db/pubkeys.go
+6
-8
knotserver/db/pubkeys.go
···
22
22
pk := PublicKey{
23
23
Did: did,
24
24
}
25
-
pk.Name = record["name"]
26
25
pk.Key = record["key"]
27
26
pk.Created = record["created"]
28
27
···
34
33
pk.Created = time.Now().Format("2006-01-02 15:04:05.99999999 -0700 MST m=-0000.000000000")
35
34
}
36
35
37
-
query := `insert into public_keys (did, name, key, created) values (?, ?, ?, ?)`
38
-
_, err := d.db.Exec(query, pk.Did, pk.Name, pk.Key, pk.Created)
36
+
query := `insert into public_keys (did, key, created) values (?, ?, ?)`
37
+
_, err := d.db.Exec(query, pk.Did, pk.Key, pk.Created)
39
38
return err
40
39
}
41
40
···
49
48
return map[string]interface{}{
50
49
pk.Did: map[string]interface{}{
51
50
"key": pk.Key,
52
-
"name": pk.Name,
53
51
"created": pk.Created,
54
52
},
55
53
}
···
58
56
func (d *DB) GetAllPublicKeys() ([]PublicKey, error) {
59
57
var keys []PublicKey
60
58
61
-
rows, err := d.db.Query(`select key, name, did, created from public_keys`)
59
+
rows, err := d.db.Query(`select key, did, created from public_keys`)
62
60
if err != nil {
63
61
return nil, err
64
62
}
···
66
64
67
65
for rows.Next() {
68
66
var publicKey PublicKey
69
-
if err := rows.Scan(&publicKey.Key, &publicKey.Name, &publicKey.Did, &publicKey.Created); err != nil {
67
+
if err := rows.Scan(&publicKey.Key, &publicKey.Did, &publicKey.Created); err != nil {
70
68
return nil, err
71
69
}
72
70
keys = append(keys, publicKey)
···
82
80
func (d *DB) GetPublicKeys(did string) ([]PublicKey, error) {
83
81
var keys []PublicKey
84
82
85
-
rows, err := d.db.Query(`select did, key, name, created from public_keys where did = ?`, did)
83
+
rows, err := d.db.Query(`select did, key, created from public_keys where did = ?`, did)
86
84
if err != nil {
87
85
return nil, err
88
86
}
···
90
88
91
89
for rows.Next() {
92
90
var publicKey PublicKey
93
-
if err := rows.Scan(&publicKey.Did, &publicKey.Key, &publicKey.Name, &publicKey.Created); err != nil {
91
+
if err := rows.Scan(&publicKey.Did, &publicKey.Key, &publicKey.Created); err != nil {
94
92
return nil, err
95
93
}
96
94
keys = append(keys, publicKey)
-11
knotserver/db/users.go
-11
knotserver/db/users.go
+17
-9
knotserver/handler.go
+17
-9
knotserver/handler.go
···
39
39
return nil, fmt.Errorf("failed to start jetstream: %w", err)
40
40
}
41
41
42
-
// TODO: close this channel and set h.knotInitialized *only after*
43
-
// checking if we have an owner.
44
-
close(h.init)
45
-
h.knotInitialized = true
42
+
// Check if the knot knows about any DIDs;
43
+
// if it does, it is already initialized and we can repopulate the
44
+
// Jetstream subscriptions.
45
+
dids, err := db.GetAllDIDs()
46
+
if err != nil {
47
+
return nil, fmt.Errorf("failed to get all DIDs: %w", err)
48
+
}
49
+
if len(dids) > 0 {
50
+
h.knotInitialized = true
51
+
close(h.init)
52
+
h.js.UpdateDids(dids)
53
+
}
46
54
47
55
r.Get("/", h.Index)
48
56
r.Route("/{did}", func(r chi.Router) {
···
67
75
})
68
76
})
69
77
70
-
// Create a new repository
78
+
// Create a new repository.
71
79
r.Route("/repo", func(r chi.Router) {
72
80
r.Use(h.VerifySignature)
73
81
r.Put("/new", h.NewRepo)
74
82
})
75
83
76
-
// Add a new user to the knot
77
-
r.With(h.VerifySignature).Put("/user", h.AddUser)
84
+
// Initialize the knot with an owner and public key.
78
85
r.With(h.VerifySignature).Post("/init", h.Init)
79
86
80
87
// Health check. Used for two-way verification with appview.
81
88
r.With(h.VerifySignature).Get("/health", h.Health)
82
89
83
-
// All public keys on the knot
90
+
// All public keys on the knot.
84
91
r.Get("/keys", h.Keys)
85
92
86
93
return r, nil
···
117
124
record := commit["record"].(map[string]interface{})
118
125
if err := h.db.AddPublicKeyFromRecord(did, record); err != nil {
119
126
log.Printf("failed to add public key: %v", err)
127
+
} else {
128
+
log.Printf("added public key from firehose: %s", data["did"])
120
129
}
121
-
log.Printf("added public key from firehose: %s", data["did"])
122
130
default:
123
131
}
124
132
}
+3
knotserver/middleware.go
+3
knotserver/middleware.go
+18
-36
knotserver/routes.go
+18
-36
knotserver/routes.go
···
391
391
w.WriteHeader(http.StatusNoContent)
392
392
}
393
393
394
-
func (h *Handle) AddUser(w http.ResponseWriter, r *http.Request) {
394
+
// TODO: make this set the initial user as the owner
395
+
func (h *Handle) Init(w http.ResponseWriter, r *http.Request) {
396
+
if h.knotInitialized {
397
+
writeError(w, "knot already initialized", http.StatusConflict)
398
+
return
399
+
}
400
+
395
401
data := struct {
396
402
DID string `json:"did"`
397
-
PublicKey string `json:"pubkey"`
403
+
PublicKey string `json:"key"`
404
+
Created string `json:"created"`
398
405
}{}
399
406
400
407
if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
···
404
411
405
412
did := data.DID
406
413
key := data.PublicKey
414
+
created := data.Created
407
415
408
-
if err := h.db.AddUser(did); err == nil {
409
-
pk := db.PublicKey{
410
-
Did: did,
411
-
}
412
-
pk.Key = key
413
-
pk.Name = "default"
414
-
err := h.db.AddPublicKey(pk)
415
-
if err != nil {
416
-
writeError(w, err.Error(), http.StatusInternalServerError)
417
-
return
418
-
}
419
-
} else {
420
-
writeError(w, err.Error(), http.StatusInternalServerError)
416
+
if did == "" {
417
+
writeError(w, "did is empty", http.StatusBadRequest)
421
418
return
422
419
}
423
420
424
-
h.js.UpdateDids([]string{did})
425
-
426
-
w.WriteHeader(http.StatusNoContent)
427
-
}
428
-
429
-
// TODO: make this set the initial user as the owner
430
-
func (h *Handle) Init(w http.ResponseWriter, r *http.Request) {
431
-
if h.knotInitialized {
432
-
writeError(w, "knot already initialized", http.StatusConflict)
421
+
if key == "" {
422
+
writeError(w, "key is empty", http.StatusBadRequest)
433
423
return
434
424
}
435
425
436
-
data := struct {
437
-
DID string `json:"did"`
438
-
PublicKey string `json:"pubkey"`
439
-
}{}
440
-
441
-
if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
442
-
writeError(w, "invalid request body", http.StatusBadRequest)
426
+
if created == "" {
427
+
writeError(w, "created timestamp is empty", http.StatusBadRequest)
443
428
return
444
429
}
445
430
446
-
did := data.DID
447
-
key := data.PublicKey
448
-
449
-
if err := h.db.AddUser(did); err == nil {
431
+
if err := h.db.AddDID(did); err == nil {
450
432
pk := db.PublicKey{
451
433
Did: did,
452
434
}
453
435
pk.Key = key
454
-
pk.Name = "default"
436
+
pk.Created = created
455
437
err := h.db.AddPublicKey(pk)
456
438
if err != nil {
457
439
writeError(w, err.Error(), http.StatusInternalServerError)