Auth (subroutes), password.

This commit is contained in:
Matthew Dillon 2015-01-07 15:54:47 -09:00
parent 16e742fcd7
commit 7da59ffef2
13 changed files with 116 additions and 28 deletions

View file

@ -4,6 +4,7 @@
CREATE TABLE users (
id BIGSERIAL NOT NULL,
username CHARACTER VARYING(100) NOT NULL,
password CHARACTER VARYING(100) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL,

View file

@ -1,6 +1,8 @@
package datastore
import (
"fmt"
"strings"
"time"
"github.com/thermokarst/bactdb/models"
@ -39,8 +41,27 @@ func (s *speciesStore) List(opt *models.SpeciesListOptions) ([]*models.Species,
if opt == nil {
opt = &models.SpeciesListOptions{}
}
sql := `SELECT * FROM species`
var conds []string
var vals []interface{}
if opt.Genus != "" {
conds = append(conds, "genus_id = (SELECT id FROM genera WHERE lower(genus_name) = $1)")
vals = append(vals, opt.Genus)
}
if len(conds) > 0 {
sql += " WHERE (" + strings.Join(conds, ") AND (") + ")"
}
sql += fmt.Sprintf(" LIMIT $%v OFFSET $%v;", len(conds)+1, len(conds)+2)
vals = append(vals, opt.PerPageOrDefault())
vals = append(vals, opt.Offset())
var species []*models.Species
err := s.dbh.Select(&species, `SELECT * FROM species LIMIT $1 OFFSET $2;`, opt.PerPageOrDefault(), opt.Offset())
err := s.dbh.Select(&species, sql, vals...)
if err != nil {
return nil, err
}

View file

@ -1,11 +1,11 @@
package datastore
import (
"fmt"
"strings"
"time"
"github.com/thermokarst/bactdb/models"
"golang.org/x/crypto/bcrypt"
)
func init() {
@ -31,7 +31,11 @@ func (s *usersStore) Create(user *models.User) (bool, error) {
currentTime := time.Now()
user.CreatedAt = currentTime
user.UpdatedAt = currentTime
fmt.Println(user)
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), 10)
if err != nil {
panic(err)
}
user.Password = string(hashedPassword)
if err := s.dbh.Insert(user); err != nil {
if strings.Contains(err.Error(), `violates unique constraint "username_idx"`) {
return false, err
@ -52,14 +56,20 @@ func (s *usersStore) List(opt *models.UserListOptions) ([]*models.User, error) {
return users, nil
}
func (s *usersStore) Authenticate(username string, password string) (*string, error) {
func (s *usersStore) Authenticate(username string, password string) (*models.UserSession, error) {
var users []*models.User
var user_session models.UserSession
if err := s.dbh.Select(&users, `SELECT * FROM users WHERE username=$1;`, username); err != nil {
return nil, err
}
if len(users) == 0 {
return nil, models.ErrUserNotFound
}
auth_level := "read"
return &auth_level, nil
if err := bcrypt.CompareHashAndPassword([]byte(users[0].Password), []byte(password)); err != nil {
return nil, err
}
user_session.AccessLevel = "read"
user_session.Genus = "hymenobacter"
return &user_session, nil
}

View file

@ -6,6 +6,7 @@ import (
"github.com/jmoiron/modl"
"github.com/thermokarst/bactdb/models"
"golang.org/x/crypto/bcrypt"
)
func insertUser(t *testing.T, tx *modl.Transaction) *models.User {
@ -20,7 +21,11 @@ func insertUser(t *testing.T, tx *modl.Transaction) *models.User {
}
func newUser() *models.User {
return &models.User{Username: "Test User"}
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte("password"), 10)
return &models.User{
Username: "Test User",
Password: string(hashedPassword),
}
}
func TestUsersStore_Get_db(t *testing.T) {
@ -93,14 +98,18 @@ func TestUsersStore_Authenticate_db(t *testing.T) {
user := insertUser(t, tx)
want := &models.UserSession{
AccessLevel: "read",
Genus: "hymenobacter",
}
d := NewDatastore(tx)
auth_level, err := d.Users.Authenticate(user.Username, "password")
user_session, err := d.Users.Authenticate(user.Username, "password")
if err != nil {
t.Fatal(err)
}
if *auth_level != "read" {
t.Errorf("expecting read, got %+v", auth_level)
if !reflect.DeepEqual(user_session, want) {
t.Errorf("got session %+v, want %+v", user_session, want)
}
}