Implement delete and check token
This commit is contained in:
parent
a173f15a57
commit
dc873a12a5
35
users.go
35
users.go
@ -1,6 +1,8 @@
|
|||||||
package users
|
package users
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
"gitlab.quimbo.fr/odwrtw/canape-sql/random"
|
"gitlab.quimbo.fr/odwrtw/canape-sql/random"
|
||||||
)
|
)
|
||||||
@ -11,7 +13,7 @@ CREATE TABLE users (
|
|||||||
name text NOT NULL UNIQUE
|
name text NOT NULL UNIQUE
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE token (
|
CREATE TABLE tokens (
|
||||||
id SERIAL,
|
id SERIAL,
|
||||||
value text NOT NULL UNIQUE,
|
value text NOT NULL UNIQUE,
|
||||||
users_id integer REFERENCES users (id) ON DELETE CASCADE
|
users_id integer REFERENCES users (id) ON DELETE CASCADE
|
||||||
@ -23,8 +25,10 @@ const (
|
|||||||
updateUserQuery = `UPDATE users SET (name)=(:name);`
|
updateUserQuery = `UPDATE users SET (name)=(:name);`
|
||||||
deleteUseQuery = `DELETE FROM users WHERE id=:id;`
|
deleteUseQuery = `DELETE FROM users WHERE id=:id;`
|
||||||
|
|
||||||
addTokenQuery = `INSERT INTO token (value, users_id) VALUES ($1, $2) RETURNING id;`
|
addTokenQuery = `INSERT INTO tokens (value, users_id) VALUES ($1, $2) RETURNING id;`
|
||||||
getTokensQuery = `SELECT id, value FROM token WHERE users_id=$1;`
|
getTokensQuery = `SELECT id, value FROM tokens WHERE users_id=$1;`
|
||||||
|
checkTokenQuery = `SELECT count(*) FROM tokens WHERE users_id=$1 AND value=$2;`
|
||||||
|
deleteTokenQuery = `DELETE FROM tokens WHERE users_id=$1 AND value=$2;`
|
||||||
)
|
)
|
||||||
|
|
||||||
// User represents an user
|
// User represents an user
|
||||||
@ -33,6 +37,7 @@ type User struct {
|
|||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Token represents a token
|
||||||
type Token struct {
|
type Token struct {
|
||||||
ID int
|
ID int
|
||||||
Value string
|
Value string
|
||||||
@ -77,6 +82,7 @@ func (u *User) Delete(ex *sqlx.DB) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTokens returns all tokens owned by the user
|
||||||
func (u *User) GetTokens(ex *sqlx.DB) ([]*Token, error) {
|
func (u *User) GetTokens(ex *sqlx.DB) ([]*Token, error) {
|
||||||
tokens := []*Token{}
|
tokens := []*Token{}
|
||||||
err := ex.Select(&tokens, getTokensQuery, u.ID)
|
err := ex.Select(&tokens, getTokensQuery, u.ID)
|
||||||
@ -86,6 +92,7 @@ func (u *User) GetTokens(ex *sqlx.DB) ([]*Token, error) {
|
|||||||
return tokens, nil
|
return tokens, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewToken generates a new token for the user
|
||||||
func (u *User) NewToken(ex *sqlx.DB) (*Token, error) {
|
func (u *User) NewToken(ex *sqlx.DB) (*Token, error) {
|
||||||
t := &Token{
|
t := &Token{
|
||||||
Value: random.String(50),
|
Value: random.String(50),
|
||||||
@ -100,10 +107,28 @@ func (u *User) NewToken(ex *sqlx.DB) (*Token, error) {
|
|||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) CheckToken(ex *sqlx.DB, value string) error {
|
// CheckToken checks if specified value exists in token's values for the user
|
||||||
return nil
|
func (u *User) CheckToken(ex *sqlx.DB, value string) (bool, error) {
|
||||||
|
var count int
|
||||||
|
err := ex.QueryRowx(checkTokenQuery, u.ID, value).Scan(&count)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if count != 1 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteToken delete token by value
|
||||||
func (u *User) DeleteToken(ex *sqlx.DB, value string) error {
|
func (u *User) DeleteToken(ex *sqlx.DB, value string) error {
|
||||||
|
r, err := ex.Exec(deleteTokenQuery, u.ID, value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
count, _ := r.RowsAffected()
|
||||||
|
if count != 1 {
|
||||||
|
return fmt.Errorf("Unexpected number of row deleted: %d", count)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const drop = `
|
const drop = `
|
||||||
DROP TABLE token;
|
DROP TABLE tokens;
|
||||||
DROP TABLE users;`
|
DROP TABLE users;`
|
||||||
|
|
||||||
var db *sqlx.DB
|
var db *sqlx.DB
|
||||||
@ -109,6 +109,7 @@ func TestTokenAddDelete(t *testing.T) {
|
|||||||
// Add many token
|
// Add many token
|
||||||
_, err = u.NewToken(db)
|
_, err = u.NewToken(db)
|
||||||
_, err = u.NewToken(db)
|
_, err = u.NewToken(db)
|
||||||
|
token, err := u.NewToken(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -118,13 +119,32 @@ func TestTokenAddDelete(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
if len(tokens) != 3 {
|
||||||
|
t.Fatalf("Unexpected number of token: %q", len(tokens))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete token
|
||||||
|
err = u.DeleteToken(db, token.Value)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
tokens, _ = u.GetTokens(db)
|
||||||
if len(tokens) != 2 {
|
if len(tokens) != 2 {
|
||||||
t.Fatalf("Unexpected number of token: %q", len(tokens))
|
t.Fatalf("Unexpected number of token: %q", len(tokens))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete a fake token
|
||||||
|
err = u.DeleteToken(db, "plop")
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("We expect an error when try to delete a fake token")
|
||||||
|
}
|
||||||
|
if err.Error() != "Unexpected number of row deleted: 0" {
|
||||||
|
t.Fatalf("Unexpected error: %q", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Remove user and test auto delete token
|
// Remove user and test auto delete token
|
||||||
u.Delete(db)
|
u.Delete(db)
|
||||||
q := `SELECT count(*) FROM token WHERE users_id=$1;`
|
q := `SELECT count(*) FROM tokens WHERE users_id=$1;`
|
||||||
var count int
|
var count int
|
||||||
err = db.QueryRowx(q, u.ID).Scan(&count)
|
err = db.QueryRowx(q, u.ID).Scan(&count)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -136,3 +156,29 @@ func TestTokenAddDelete(t *testing.T) {
|
|||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTokenCheck(t *testing.T) {
|
||||||
|
sqltest.RunWithSchema(db, usersCreate, drop, t, func(db *sqlx.DB, t *testing.T) {
|
||||||
|
u := &User{Name: "plop"}
|
||||||
|
u.Add(db)
|
||||||
|
token, err := u.NewToken(db)
|
||||||
|
|
||||||
|
ok, err := u.CheckToken(db, token.Value)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Token not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// test fake token
|
||||||
|
ok, err = u.CheckToken(db, "plop")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if ok {
|
||||||
|
t.Fatalf("Token found otherwise we don't expect")
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user