this repo has no description
1package db
2
3import (
4 "database/sql"
5 "fmt"
6 "log"
7 "time"
8
9 "github.com/google/uuid"
10)
11
12type Registration struct {
13 Domain string
14 ByDid string
15 Created *time.Time
16 Registered *time.Time
17}
18
19func (r *Registration) Status() Status {
20 if r.Registered != nil {
21 return Registered
22 } else {
23 return Pending
24 }
25}
26
27type Status uint32
28
29const (
30 Registered Status = iota
31 Pending
32)
33
34// returns registered status, did of owner, error
35func (d *DB) RegistrationsByDid(did string) ([]Registration, error) {
36 var registrations []Registration
37
38 rows, err := d.db.Query(`
39 select domain, did, created, registered from registrations
40 where did = ?
41 `, did)
42 if err != nil {
43 return nil, err
44 }
45
46 for rows.Next() {
47 var createdAt *int64
48 var registeredAt *int64
49 var registration Registration
50 err = rows.Scan(®istration.Domain, ®istration.ByDid, &createdAt, ®isteredAt)
51
52 if err != nil {
53 log.Println(err)
54 } else {
55 createdAtTime := time.Unix(*createdAt, 0)
56
57 var registeredAtTime *time.Time
58 if registeredAt != nil {
59 x := time.Unix(*registeredAt, 0)
60 registeredAtTime = &x
61 }
62
63 registration.Created = &createdAtTime
64 registration.Registered = registeredAtTime
65 registrations = append(registrations, registration)
66 }
67 }
68
69 return registrations, nil
70}
71
72// returns registered status, did of owner, error
73func (d *DB) RegistrationByDomain(domain string) (*Registration, error) {
74 var createdAt *int64
75 var registeredAt *int64
76 var registration Registration
77
78 err := d.db.QueryRow(`
79 select domain, did, created, registered from registrations
80 where domain = ?
81 `, domain).Scan(®istration.Domain, ®istration.ByDid, &createdAt, ®isteredAt)
82
83 if err != nil {
84 if err == sql.ErrNoRows {
85 return nil, nil
86 } else {
87 return nil, err
88 }
89 }
90
91 createdAtTime := time.Unix(*createdAt, 0)
92 var registeredAtTime *time.Time
93 if registeredAt != nil {
94 x := time.Unix(*registeredAt, 0)
95 registeredAtTime = &x
96 }
97
98 registration.Created = &createdAtTime
99 registration.Registered = registeredAtTime
100
101 return ®istration, nil
102}
103
104func (d *DB) GenerateRegistrationKey(domain, did string) (string, error) {
105 // sanity check: does this domain already have a registration?
106 reg, err := d.RegistrationByDomain(domain)
107 if err != nil {
108 return "", err
109 }
110
111 // registration is open
112 if reg != nil {
113 switch reg.Status() {
114 case Registered:
115 // already registered by `owner`
116 return "", fmt.Errorf("%s already registered by %s", domain, reg.ByDid)
117 case Pending:
118 // TODO: be loud about this
119 log.Printf("%s registered by %s, status pending", domain, reg.ByDid)
120 }
121 }
122
123 secret := uuid.New().String()
124
125 _, err = d.db.Exec(`
126 insert into registrations (domain, did, secret)
127 values (?, ?, ?)
128 on conflict(domain) do update set did = excluded.did, secret = excluded.secret
129 `, domain, did, secret)
130
131 if err != nil {
132 return "", err
133 }
134
135 return secret, nil
136}
137
138func (d *DB) GetRegistrationKey(domain string) (string, error) {
139 res := d.db.QueryRow(`select secret from registrations where domain = ?`, domain)
140
141 var secret string
142 err := res.Scan(&secret)
143 if err != nil || secret == "" {
144 return "", err
145 }
146
147 return secret, nil
148}
149
150func (d *DB) Register(domain string) error {
151 _, err := d.db.Exec(`
152 update registrations
153 set registered = strftime('%s', 'now')
154 where domain = ?;
155 `, domain)
156
157 return err
158}