Clean up users in DB and auth handlers

This commit is contained in:
Matthew Dillon 2015-04-09 11:29:32 -08:00
parent fe8e5ef832
commit eb6f7f6e44
2 changed files with 19 additions and 32 deletions

View file

@ -1,10 +1,17 @@
-- bactdb -- bactdb
-- Matthew R Dillon -- Matthew R Dillon
CREATE TYPE e_roles AS ENUM('R', 'W', 'A');
-- 'R': read-only, default
-- 'W': read-write
-- 'A': administrator
CREATE TABLE users ( CREATE TABLE users (
id BIGSERIAL NOT NULL, id BIGSERIAL NOT NULL,
username CHARACTER VARYING(100) NOT NULL, email CHARACTER VARYING(254) NOT NULL UNIQUE,
password CHARACTER VARYING(100) NOT NULL, password CHARACTER VARYING(100) NOT NULL,
name CHARACTER VARYING(100) NOT NULL,
role e_roles DEFAULT 'R' NOT NULL,
created_at TIMESTAMP WITH TIME ZONE NOT NULL, created_at TIMESTAMP WITH TIME ZONE NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL, updated_at TIMESTAMP WITH TIME ZONE NOT NULL,
@ -13,8 +20,3 @@ CREATE TABLE users (
CONSTRAINT users_pkey PRIMARY KEY (id) CONSTRAINT users_pkey PRIMARY KEY (id)
); );
CREATE UNIQUE INDEX username_idx
ON users
USING btree
(username COLLATE pg_catalog."default");

View file

@ -3,7 +3,6 @@ package main
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"net/http" "net/http"
"time" "time"
@ -23,8 +22,10 @@ func init() {
// Todo: add password // Todo: add password
type User struct { type User struct {
Id int64 `json:"id,omitempty"` Id int64 `json:"id,omitempty"`
Username string `db:"username" json:"username"` Email string `db:"email" json:"email"`
Password string `db:"password" json:"-"` Password string `db:"password" json:"-"`
Name string `db:"name" json:"name"`
Role string `db:"role" json:"role"`
CreatedAt time.Time `db:"created_at" json:"createdAt"` CreatedAt time.Time `db:"created_at" json:"createdAt"`
UpdatedAt time.Time `db:"updated_at" json:"updatedAt"` UpdatedAt time.Time `db:"updated_at" json:"updatedAt"`
DeletedAt NullTime `db:"deleted_at" json:"deletedAt"` DeletedAt NullTime `db:"deleted_at" json:"deletedAt"`
@ -38,41 +39,30 @@ type UsersJSON struct {
Users []*User `json:"users"` Users []*User `json:"users"`
} }
func (m *User) String() string {
return fmt.Sprintf("%v", *m)
}
type UserSession struct {
*User
Role string `json:"access_level"`
Genus string `json:"genus"`
}
func serveAuthenticateUser(w http.ResponseWriter, r *http.Request) { func serveAuthenticateUser(w http.ResponseWriter, r *http.Request) {
var a struct { var a struct {
Username string Email string
Password string Password string
} }
if err := json.NewDecoder(r.Body).Decode(&a); err != nil { if err := json.NewDecoder(r.Body).Decode(&a); err != nil {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
return return
} }
user_session, err := dbAuthenticate(a.Username, a.Password) user_session, err := dbAuthenticate(a.Email, a.Password)
if err != nil { if err != nil {
w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusUnauthorized) w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(`{"error":"Invalid username or password"}`)) w.Write([]byte(`{"error":"Invalid email or password"}`))
return return
} }
currentTime := time.Now() currentTime := time.Now()
t := jwt.New(jwt.SigningMethodRS256) t := jwt.New(jwt.SigningMethodRS256)
t.Claims["name"] = user_session.Username t.Claims["name"] = user_session.Name
t.Claims["iss"] = "bactdb" t.Claims["iss"] = "bactdb"
t.Claims["sub"] = "user@example.com" // TODO: fix this t.Claims["sub"] = user_session.Email
t.Claims["role"] = user_session.Role t.Claims["role"] = user_session.Role
t.Claims["genus"] = user_session.Genus
t.Claims["iat"] = currentTime.Unix() t.Claims["iat"] = currentTime.Unix()
t.Claims["exp"] = currentTime.Add(time.Minute * 60 * 24).Unix() t.Claims["exp"] = currentTime.Add(time.Minute * 60 * 24).Unix()
tokenString, err := t.SignedString(signKey) tokenString, err := t.SignedString(signKey)
@ -93,11 +83,9 @@ func serveAuthenticateUser(w http.ResponseWriter, r *http.Request) {
w.Write(data) w.Write(data)
} }
func dbAuthenticate(username string, password string) (*UserSession, error) { func dbAuthenticate(email string, password string) (*User, error) {
var users []User var users []User
var user_session UserSession if err := DBH.Select(&users, `SELECT * FROM users WHERE lower(email)=lower($1);`, email); err != nil {
if err := DBH.Select(&users, `SELECT * FROM users WHERE username=$1;`, username); err != nil {
return nil, err return nil, err
} }
if len(users) == 0 { if len(users) == 0 {
@ -106,8 +94,5 @@ func dbAuthenticate(username string, password string) (*UserSession, error) {
if err := bcrypt.CompareHashAndPassword([]byte(users[0].Password), []byte(password)); err != nil { if err := bcrypt.CompareHashAndPassword([]byte(users[0].Password), []byte(password)); err != nil {
return nil, err return nil, err
} }
user_session.User = &users[0] return &users[0], nil
user_session.Role = "admin"
user_session.Genus = "hymenobacter"
return &user_session, nil
} }