this repo has no description
1package db 2 3import ( 4 "database/sql" 5 "fmt" 6 "log" 7 8 "github.com/google/uuid" 9 10 _ "github.com/mattn/go-sqlite3" 11) 12 13type DB struct { 14 db *sql.DB 15} 16 17func Make(dbPath string) (*DB, error) { 18 db, err := sql.Open("sqlite3", dbPath) 19 if err != nil { 20 return nil, err 21 } 22 _, err = db.Exec(` 23 create table if not exists registrations ( 24 id integer primary key autoincrement, 25 domain text not null unique, 26 did text not null, 27 secret text not null, 28 created integer default (strftime('%s', 'now')), 29 registered integer); 30 create table if not exists public_keys ( 31 id integer primary key autoincrement, 32 did text not null, 33 name text not null, 34 key text not null, 35 created timestamp default current_timestamp, 36 unique(did, name, key) 37 ); 38 `) 39 if err != nil { 40 return nil, err 41 } 42 return &DB{db: db}, nil 43} 44 45type RegStatus uint32 46 47const ( 48 Registered RegStatus = iota 49 Unregistered 50 Pending 51) 52 53// returns registered status, did of owner, error 54func (d *DB) RegistrationStatus(domain string) (RegStatus, string, error) { 55 var registeredBy string 56 var registratedAt *uint64 57 err := d.db.QueryRow(` 58 select did, registered from registrations 59 where domain = ? 60 `, domain).Scan(&registeredBy, &registratedAt) 61 if err != nil { 62 if err == sql.ErrNoRows { 63 return Unregistered, "", nil 64 } else { 65 return Unregistered, "", err 66 } 67 } 68 69 if registratedAt != nil { 70 return Registered, registeredBy, nil 71 } else { 72 return Pending, registeredBy, nil 73 } 74} 75 76func (d *DB) GenerateRegistrationKey(domain, did string) (string, error) { 77 // sanity check: does this domain already have a registration? 78 status, owner, err := d.RegistrationStatus(domain) 79 if err != nil { 80 return "", err 81 } 82 switch status { 83 case Registered: 84 // already registered by `owner` 85 return "", fmt.Errorf("%s already registered by %s", domain, owner) 86 case Pending: 87 log.Printf("%s registered by %s, status pending", domain, owner) 88 // TODO: provide a warning here, and allow the current user to overwrite 89 // the registration, this prevents users from registering domains that they 90 // do not own 91 default: 92 // ok, we can register this domain 93 } 94 95 secret := uuid.New().String() 96 97 _, err = d.db.Exec(` 98 insert into registrations (domain, did, secret) 99 values (?, ?, ?) 100 on conflict(domain) do update set did = excluded.did, secret = excluded.secret 101 `, domain, did, secret) 102 103 if err != nil { 104 return "", err 105 } 106 107 return secret, nil 108} 109 110func (d *DB) GetRegistrationKey(domain string) (string, error) { 111 res := d.db.QueryRow(`select secret from registrations where domain = ?`, domain) 112 113 var secret string 114 err := res.Scan(&secret) 115 if err != nil || secret == "" { 116 return "", err 117 } 118 119 log.Println("domain, secret: ", domain, secret) 120 121 return secret, nil 122} 123 124func (d *DB) Register(domain string) error { 125 _, err := d.db.Exec(` 126 update registrations 127 set registered = strftime('%s', 'now') 128 where domain = ?; 129 `, domain) 130 131 if err != nil { 132 return err 133 } 134 135 return nil 136} 137 138// type Registration struct { 139// status RegStatus 140// } 141// func (d *DB) RegistrationsForDid(did string) ()