Implement token add and get

This commit is contained in:
Nicolas Duhamel 2016-02-10 16:15:05 +01:00
parent 4e9072c28a
commit a173f15a57
3 changed files with 130 additions and 3 deletions

37
random/random.go Normal file
View File

@ -0,0 +1,37 @@
package random
import (
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const (
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)
var src = rand.NewSource(time.Now().UnixNano())
func String(n int) string {
b := make([]byte, n)
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = src.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
}
return string(b)
}

View File

@ -1,18 +1,30 @@
package users
import "github.com/jmoiron/sqlx"
import (
"github.com/jmoiron/sqlx"
"gitlab.quimbo.fr/odwrtw/canape-sql/random"
)
const usersCreate = `
CREATE TABLE users (
id SERIAL,
id SERIAL PRIMARY KEY,
name text NOT NULL UNIQUE
);
CREATE TABLE token (
id SERIAL,
value text NOT NULL UNIQUE,
users_id integer REFERENCES users (id) ON DELETE CASCADE
);
`
const (
addUserQuery = `INSERT INTO users (name) VALUES ($1) RETURNING id;`
getUserQuery = `SELECT * FROM users WHERE name=$1;`
updateUserQuery = `UPDATE users SET (name)=(:name);`
deleteUseQuery = `DELETE FROM users WHERE id=:id;`
addTokenQuery = `INSERT INTO token (value, users_id) VALUES ($1, $2) RETURNING id;`
getTokensQuery = `SELECT id, value FROM token WHERE users_id=$1;`
)
// User represents an user
@ -21,6 +33,11 @@ type User struct {
Name string
}
type Token struct {
ID int
Value string
}
// Get returns user with specified name
func Get(q sqlx.Queryer, name string) (*User, error) {
u := &User{}
@ -59,3 +76,34 @@ func (u *User) Delete(ex *sqlx.DB) error {
}
return nil
}
func (u *User) GetTokens(ex *sqlx.DB) ([]*Token, error) {
tokens := []*Token{}
err := ex.Select(&tokens, getTokensQuery, u.ID)
if err != nil {
return nil, err
}
return tokens, nil
}
func (u *User) NewToken(ex *sqlx.DB) (*Token, error) {
t := &Token{
Value: random.String(50),
}
var id int
err := ex.QueryRowx(addTokenQuery, t.Value, u.ID).Scan(&id)
if err != nil {
return nil, err
}
t.ID = id
return t, nil
}
func (u *User) CheckToken(ex *sqlx.DB, value string) error {
return nil
}
func (u *User) DeleteToken(ex *sqlx.DB, value string) error {
return nil
}

View File

@ -11,7 +11,9 @@ import (
"github.com/lib/pq"
)
const drop = `DROP TABLE users;`
const drop = `
DROP TABLE token;
DROP TABLE users;`
var db *sqlx.DB
@ -94,3 +96,43 @@ func TestUser(t *testing.T) {
}
})
}
func TestTokenAddDelete(t *testing.T) {
sqltest.RunWithSchema(db, usersCreate, drop, t, func(db *sqlx.DB, t *testing.T) {
// Add a new user
u := &User{Name: "plop"}
err := u.Add(db)
if err != nil {
t.Fatal(err)
}
// Add many token
_, err = u.NewToken(db)
_, err = u.NewToken(db)
if err != nil {
t.Fatal(err)
}
// Get token
tokens, err := u.GetTokens(db)
if err != nil {
t.Fatal(err)
}
if len(tokens) != 2 {
t.Fatalf("Unexpected number of token: %q", len(tokens))
}
// Remove user and test auto delete token
u.Delete(db)
q := `SELECT count(*) FROM token WHERE users_id=$1;`
var count int
err = db.QueryRowx(q, u.ID).Scan(&count)
if err != nil {
t.Fatal(err)
}
if count != 0 {
t.Fatalf("Unexpected number of token: %d", count)
}
})
}