diff options
Diffstat (limited to 'auth_sqlite3.go')
-rw-r--r-- | auth_sqlite3.go | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/auth_sqlite3.go b/auth_sqlite3.go new file mode 100644 index 0000000..02a3de4 --- /dev/null +++ b/auth_sqlite3.go @@ -0,0 +1,146 @@ +package main + +import ( + "database/sql" + "time" + + _ "github.com/mattn/go-sqlite3" +) + +type authSQLite3 struct { + db *sql.DB +} + +func (a authSQLite3) Exists(name string) bool { + if err := a.init(); err != nil { + return false + } + defer a.close() + + var name2 string + err := a.db.QueryRow(`SELECT name FROM user WHERE name = ?;`, name).Scan(&name2) + return err == nil +} + +func (a authSQLite3) Passwd(name string) (salt, verifier []byte, err error) { + if err = a.init(); err != nil { + return + } + defer a.close() + + a.db.QueryRow(`SELECT salt, verifier FROM user WHERE name = ?;`, name).Scan(&salt, &verifier) + a.updateTimestamp(name) + return +} + +func (a authSQLite3) SetPasswd(name string, salt, verifier []byte) error { + if err := a.init(); err != nil { + return err + } + defer a.close() + + _, err := a.db.Exec(`REPLACE INTO user (name, salt, verifier) VALUES (?, ?, ?);`, name, salt, verifier) + if err != nil { + return err + } + + a.updateTimestamp(name) + return nil +} + +func (a authSQLite3) Timestamp(name string) (time.Time, error) { + if err := a.init(); err != nil { + return time.Time{}, err + } + defer a.close() + + var tstr string + err := a.db.QueryRow(`SELECT timestamp FROM user WHERE name = ?;`, name).Scan(&tstr) + if err != nil { + return time.Time{}, err + } + + return time.Parse("2006-01-02 15:04:05", tstr) +} + +func (a authSQLite3) Import(in []user) { + if err := a.init(); err != nil { + return + } + defer a.close() + + a.db.Exec(`DELETE FROM user;`) + for _, u := range in { + a.SetPasswd(u.name, u.salt, u.verifier) + a.db.Query(`UPDATE user SET timestamp = ? WHERE name = ?;`, u.timestamp.Format("2006-01-02 15:04:05"), u.name) + } +} + +func (a authSQLite3) Export() ([]user, error) { + if err := a.init(); err != nil { + return nil, err + } + defer a.close() + + rows, err := a.db.Query(`SELECT * FROM user;`) + if err != nil { + return nil, err + } + defer rows.Close() + + var names []string + for rows.Next() { + var name string + if err := rows.Scan(&name); err != nil { + return nil, err + } + + names = append(names, name) + } + + var out []user + for _, name := range names { + var u user + u.timestamp, err = a.Timestamp(name) + if err != nil { + return nil, err + } + + u.salt, u.verifier, err = a.Passwd(name) + if err != nil { + return nil, err + } + + out = append(out, u) + } + + return out, nil +} + +func (a authSQLite3) updateTimestamp(name string) { + a.db.Exec(`UPDATE user SET timestamp = datetime("now") WHERE name = ?;`, name) +} + +func (a *authSQLite3) init() error { + var err error + a.db, err = sql.Open("sqlite3", "auth.sqlite") + if err != nil { + return err + } + + init := `CREATE TABLE IF NOT EXISTS user ( + name VARCHAR(20) PRIMARY KEY NOT NULL, + salt BLOB NOT NULL, + verifier BLOB NOT NULL, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP);` + + if _, err := a.db.Exec(init); err != nil { + return err + } + + return nil +} + +func (a authSQLite3) close() error { + return a.db.Close() +} |