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) RegistrationByDomainTx(tx *sql.Tx, domain string) (*Registration, error) {
105 var createdAt *int64
106 var registeredAt *int64
107 var registration Registration
108
109 err := tx.QueryRow(`
110 select domain, did, created, registered from registrations
111 where domain = ?
112 `, domain).Scan(®istration.Domain, ®istration.ByDid, &createdAt, ®isteredAt)
113
114 if err != nil {
115 if err == sql.ErrNoRows {
116 return nil, nil
117 } else {
118 return nil, err
119 }
120 }
121
122 createdAtTime := time.Unix(*createdAt, 0)
123 var registeredAtTime *time.Time
124 if registeredAt != nil {
125 x := time.Unix(*registeredAt, 0)
126 registeredAtTime = &x
127 }
128
129 registration.Created = &createdAtTime
130 registration.Registered = registeredAtTime
131
132 return ®istration, nil
133}
134
135func (d *DB) GenerateRegistrationKey(domain, did string) (string, error) {
136 // sanity check: does this domain already have a registration?
137 reg, err := d.RegistrationByDomain(domain)
138 if err != nil {
139 return "", err
140 }
141
142 // registration is open
143 if reg != nil {
144 switch reg.Status() {
145 case Registered:
146 // already registered by `owner`
147 return "", fmt.Errorf("%s already registered by %s", domain, reg.ByDid)
148 case Pending:
149 // TODO: be loud about this
150 log.Printf("%s registered by %s, status pending", domain, reg.ByDid)
151 }
152 }
153
154 secret := uuid.New().String()
155
156 _, err = d.Db.Exec(`
157 insert into registrations (domain, did, secret)
158 values (?, ?, ?)
159 on conflict(domain) do update set did = excluded.did, secret = excluded.secret
160 `, domain, did, secret)
161
162 if err != nil {
163 return "", err
164 }
165
166 return secret, nil
167}
168
169func (d *DB) GetRegistrationKey(domain string) (string, error) {
170 res := d.Db.QueryRow(`select secret from registrations where domain = ?`, domain)
171
172 var secret string
173 err := res.Scan(&secret)
174 if err != nil || secret == "" {
175 return "", err
176 }
177
178 return secret, nil
179}
180
181func (d *DB) GetRegistrationKeyTx(tx *sql.Tx, domain string) (string, error) {
182 res := tx.QueryRow(`select secret from registrations where domain = ?`, domain)
183
184 var secret string
185 err := res.Scan(&secret)
186 if err != nil || secret == "" {
187 return "", err
188 }
189
190 return secret, nil
191}
192
193func (d *DB) Register(domain string) error {
194 _, err := d.Db.Exec(`
195 update registrations
196 set registered = strftime('%s', 'now')
197 where domain = ?;
198 `, domain)
199
200 return err
201}
202
203func (d *DB) RegisterTx(tx *sql.Tx, domain string) error {
204 _, err := tx.Exec(`
205 update registrations
206 set registered = strftime('%s', 'now')
207 where domain = ?;
208 `, domain)
209
210 return err
211}