diff --git a/migrations/00001_AddUsers_up.sql b/migrations/00001_AddUsers_up.sql index 82bf368..4b1121d 100644 --- a/migrations/00001_AddUsers_up.sql +++ b/migrations/00001_AddUsers_up.sql @@ -1,10 +1,17 @@ -- bactdb -- Matthew R Dillon +CREATE TYPE e_roles AS ENUM('R', 'W', 'A'); +-- 'R': read-only, default +-- 'W': read-write +-- 'A': administrator + CREATE TABLE users ( id BIGSERIAL NOT NULL, - username CHARACTER VARYING(100) NOT NULL, + email CHARACTER VARYING(254) NOT NULL UNIQUE, 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, updated_at TIMESTAMP WITH TIME ZONE NOT NULL, @@ -13,8 +20,3 @@ CREATE TABLE users ( CONSTRAINT users_pkey PRIMARY KEY (id) ); -CREATE UNIQUE INDEX username_idx - ON users - USING btree - (username COLLATE pg_catalog."default"); - diff --git a/users.go b/users.go index 955bc39..9f5bf58 100644 --- a/users.go +++ b/users.go @@ -3,7 +3,6 @@ package main import ( "encoding/json" "errors" - "fmt" "net/http" "time" @@ -23,8 +22,10 @@ func init() { // Todo: add password type User struct { Id int64 `json:"id,omitempty"` - Username string `db:"username" json:"username"` + Email string `db:"email" json:"email"` 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"` UpdatedAt time.Time `db:"updated_at" json:"updatedAt"` DeletedAt NullTime `db:"deleted_at" json:"deletedAt"` @@ -38,41 +39,30 @@ type UsersJSON struct { 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) { var a struct { - Username string + Email string Password string } if err := json.NewDecoder(r.Body).Decode(&a); err != nil { w.WriteHeader(http.StatusInternalServerError) return } - user_session, err := dbAuthenticate(a.Username, a.Password) + user_session, err := dbAuthenticate(a.Email, a.Password) if err != nil { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusUnauthorized) - w.Write([]byte(`{"error":"Invalid username or password"}`)) + w.Write([]byte(`{"error":"Invalid email or password"}`)) return } currentTime := time.Now() t := jwt.New(jwt.SigningMethodRS256) - t.Claims["name"] = user_session.Username + t.Claims["name"] = user_session.Name 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["genus"] = user_session.Genus t.Claims["iat"] = currentTime.Unix() t.Claims["exp"] = currentTime.Add(time.Minute * 60 * 24).Unix() tokenString, err := t.SignedString(signKey) @@ -93,11 +83,9 @@ func serveAuthenticateUser(w http.ResponseWriter, r *http.Request) { w.Write(data) } -func dbAuthenticate(username string, password string) (*UserSession, error) { +func dbAuthenticate(email string, password string) (*User, error) { var users []User - var user_session UserSession - - if err := DBH.Select(&users, `SELECT * FROM users WHERE username=$1;`, username); err != nil { + if err := DBH.Select(&users, `SELECT * FROM users WHERE lower(email)=lower($1);`, email); err != nil { return nil, err } 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 { return nil, err } - user_session.User = &users[0] - user_session.Role = "admin" - user_session.Genus = "hymenobacter" - return &user_session, nil + return &users[0], nil }