Add auth and user package

This commit is contained in:
Andinus 2020-03-26 23:29:48 +05:30
parent 288d04779e
commit 7a3e2f9552
Signed by: andinus
GPG Key ID: B67D55D482A799FD
8 changed files with 170 additions and 9 deletions

14
auth/genid.go Normal file
View File

@ -0,0 +1,14 @@
package auth
import (
"crypto/rand"
"encoding/base64"
)
// genID generates a random id string of length n. Don't forget to
// seed the random number generator otherwise it won't be random.
func genID(n int) string {
b := make([]byte, n/2)
rand.Read(b)
return base64.StdEncoding.EncodeToString(b)
}

13
auth/hashpass.go Normal file
View File

@ -0,0 +1,13 @@
package auth
import (
"golang.org/x/crypto/bcrypt"
)
// hashPass takes a string as input and returns the hash of the
// password.
func hashPass(password string) (string, error) {
// 10 is the default cost.
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 10)
return string(bytes), err
}

81
auth/register.go Normal file
View File

@ -0,0 +1,81 @@
package auth
import (
"log"
"strings"
"time"
"tildegit.org/andinus/perseus/storage/sqlite3"
"tildegit.org/andinus/perseus/user"
)
// Register takes in registration details and returns an error. If
// error doesn't equal nil then the registration was unsucessful.
// regInfo should have username, password & ip.
func Register(db *sqlite3.DB, regInfo map[string]string) error {
u := user.User{}
u.SetID(genID(64))
u.SetUsername(strings.ToLower(regInfo["username"]))
pass, err := hashPass(regInfo["password"])
if err != nil {
log.Printf("auth/register.go: %s\n",
"hashPass func failed")
return err
}
u.SetPassword(pass)
// Acquire write lock on the database.
db.Mu.Lock()
defer db.Mu.Unlock()
err = insertRecords(db, u, regInfo)
return err
}
func insertRecords(db *sqlite3.DB, u user.User, regInfo map[string]string) error {
// Start the transaction
tx, err := db.Conn.Begin()
if err != nil {
log.Printf("auth/register.go: %s\n",
"Failed to begin transaction")
return err
}
// Insert the record into registration table
regStmt, err := db.Conn.Prepare(`
INSERT INTO registration(id, username, reg_time, reg_ip) values(?, ?, ?, ?)`)
if err != nil {
log.Printf("auth/register.go: %s\n",
"Failed to prepare statement")
return err
}
defer regStmt.Close()
_, err = regStmt.Exec(u.ID(), u.Username(), time.Now().UTC(), regInfo["ip"])
if err != nil {
log.Printf("auth/register.go: %s\n",
"Failed to execute statement")
return err
}
// Insert the record into users table
usrStmt, err := db.Conn.Prepare(`
INSERT INTO users(id, username, password) values(?, ?, ?)`)
if err != nil {
log.Printf("auth/register.go: %s\n",
"Failed to prepare statement")
return err
}
defer usrStmt.Close()
_, err = usrStmt.Exec(u.ID(), u.Username(), u.Password())
if err != nil {
log.Printf("auth/register.go: %s\n",
"Failed to execute statement")
return err
}
tx.Commit()
return err
}

5
go.mod
View File

@ -2,4 +2,7 @@ module tildegit.org/andinus/perseus
go 1.13
require github.com/mattn/go-sqlite3 v2.0.3+incompatible
require (
github.com/mattn/go-sqlite3 v2.0.3+incompatible
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59
)

7
go.sum
View File

@ -1,2 +1,9 @@
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

13
storage/sqlite3/db.go Normal file
View File

@ -0,0 +1,13 @@
package sqlite3
import (
"database/sql"
"sync"
)
// DB holds the database connection, mutex & path.
type DB struct {
Path string
Mu *sync.RWMutex
Conn *sql.DB
}

View File

@ -4,18 +4,10 @@ import (
"database/sql"
"log"
"os"
"sync"
_ "github.com/mattn/go-sqlite3"
)
// DB holds the database connection, mutex & path.
type DB struct {
Path string
Mu *sync.RWMutex
Conn *sql.DB
}
// initErr will log the error and close the database connection if
// necessary.
func initErr(db *DB, err error) {

38
user/user.go Normal file
View File

@ -0,0 +1,38 @@
package user
// User holds information about the user.
type User struct {
id string
username string
password string
}
// SetUsername will set the username.
func (u *User) SetUsername(username string) {
u.username = username
}
// Username returns the username.
func (u *User) Username() string {
return u.username
}
// SetPassword will set the password.
func (u *User) SetPassword(password string) {
u.password = password
}
// Password returns the password.
func (u *User) Password() string {
return u.password
}
// SetID will set the id.
func (u *User) SetID(id string) {
u.id = id
}
// ID returns the id.
func (u *User) ID() string {
return u.id
}