diff options
author | Andinus <andinus@nand.sh> | 2020-03-27 18:10:32 +0530 |
---|---|---|
committer | Andinus <andinus@nand.sh> | 2020-03-27 18:10:32 +0530 |
commit | ad9332dcd5912005917f4bf2f4c544115008138a (patch) | |
tree | 2819aff280a7c4d0c109ae9038ec891e97e0b483 /auth | |
parent | 5c62f93da80611fc03b96f73f8787513e86c0477 (diff) | |
download | perseus-ad9332dcd5912005917f4bf2f4c544115008138a.tar.gz |
Add token related functions
Diffstat (limited to 'auth')
-rw-r--r-- | auth/gentoken.go | 8 | ||||
-rw-r--r-- | auth/token.go | 101 |
2 files changed, 109 insertions, 0 deletions
diff --git a/auth/gentoken.go b/auth/gentoken.go new file mode 100644 index 0000000..1e01875 --- /dev/null +++ b/auth/gentoken.go @@ -0,0 +1,8 @@ +package auth + +// genToken generates a random token string of length n. Don't forget to +// seed the random number generator otherwise it won't be random. +func genToken(n int) string { + // Currently this is just a wrapper to genID. + return genID(n) +} diff --git a/auth/token.go b/auth/token.go new file mode 100644 index 0000000..3f831fb --- /dev/null +++ b/auth/token.go @@ -0,0 +1,101 @@ +package auth + +import ( + "errors" + "log" + "time" + + "tildegit.org/andinus/perseus/storage/sqlite3" + "tildegit.org/andinus/perseus/user" +) + +// ValToken will validate the token and returns an error. If error +// doesn't equal nil then consider token invalid. +func ValToken(db *sqlite3.DB, uInfo map[string]string) error { + // Acquire read lock on the database. + db.Mu.RLock() + defer db.Mu.RUnlock() + + u := user.User{} + u.SetUsername(uInfo["username"]) + + // Set user id from username. + err := u.GetID(db) + if err != nil { + log.Printf("auth/token.go: %s\n", + "failed to get id from username") + return err + } + + // Check if user's token is valid. + stmt, err := db.Conn.Prepare("SELECT token FROM access WHERE id = ?") + if err != nil { + log.Printf("auth/token.go: %s\n", + "failed to prepare statement") + return err + } + defer stmt.Close() + + var token string + err = stmt.QueryRow(u.ID()).Scan(&token) + if err != nil { + log.Printf("auth/token.go: %s\n", + "query failed") + return err + } + + if token != uInfo["token"] { + err = errors.New("token mismatch") + } + + return err +} + +// AddToken will generate a random token, add it to database and +// return the token. +func AddToken(db *sqlite3.DB, uInfo map[string]string) (token string, err error) { + // Acquire write lock on the database. + db.Mu.Lock() + defer db.Mu.Unlock() + + token = genToken(64) + + u := user.User{} + u.SetUsername(uInfo["username"]) + + // Set user id from username. + err = u.GetID(db) + if err != nil { + log.Printf("auth/token.go: %s\n", + "failed to get id from username") + return + } + + // Start the transaction + tx, err := db.Conn.Begin() + if err != nil { + log.Printf("auth/token.go: %s\n", + "failed to begin transaction") + return + } + + stmt, err := db.Conn.Prepare(` +INSERT INTO access(id, username, genTime) values(?, ?, ?)`) + if err != nil { + log.Printf("auth/tokenr.go: %s\n", + "failed to prepare statement") + return + } + defer stmt.Close() + + _, err = stmt.Exec(u.ID(), u.Username(), time.Now().UTC()) + if err != nil { + log.Printf("auth/token.go: %s\n", + "failed to execute statement") + return + } + + tx.Commit() + return + +} |