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