Update strain (rough)

This commit is contained in:
Matthew Dillon 2015-05-26 14:44:23 -08:00
parent 06938a9f2b
commit 6403622d19
2 changed files with 89 additions and 20 deletions

View file

@ -8,10 +8,20 @@ import (
"strings" "strings"
"time" "time"
"github.com/gorilla/context"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/thermokarst/jwt" "github.com/thermokarst/jwt"
) )
type Claims struct {
Name string
Iss string
Sub int64
Role string
Iat int64
Exp int64
}
func Handler() http.Handler { func Handler() http.Handler {
claimsFunc := func(email string) (map[string]interface{}, error) { claimsFunc := func(email string) (map[string]interface{}, error) {
currentTime := time.Now() currentTime := time.Now()
@ -29,16 +39,9 @@ func Handler() http.Handler {
}, nil }, nil
} }
verifyClaims := func(claims []byte) error { verifyClaims := func(claims []byte, r *http.Request) error {
currentTime := time.Now() currentTime := time.Now()
var c struct { var c Claims
Name string
Iss string
Sub int64
Role string
Iat int64
Exp int64
}
err := json.Unmarshal(claims, &c) err := json.Unmarshal(claims, &c)
if err != nil { if err != nil {
return err return err
@ -46,6 +49,7 @@ func Handler() http.Handler {
if currentTime.After(time.Unix(c.Exp, 0)) { if currentTime.After(time.Unix(c.Exp, 0)) {
return errors.New("this token has expired") return errors.New("this token has expired")
} }
context.Set(r, "claims", c)
return nil return nil
} }
@ -75,19 +79,21 @@ func Handler() http.Handler {
type r struct { type r struct {
f http.HandlerFunc f http.HandlerFunc
m string m string
p string
} }
routes := map[string]r{ routes := []r{
"/strains": r{serveStrainsList, "GET"}, r{serveStrainsList, "GET", "/strains"},
"/strains/{Id:.+}": r{serveStrain, "GET"}, r{serveStrain, "GET", "/strains/{Id:.+}"},
"/measurements": r{serveMeasurementsList, "GET"}, r{serveUpdateStrain, "PUT", "/strains/{Id:.+}"},
"/measurements/{Id:.+}": r{serveMeasurement, "GET"}, r{serveMeasurementsList, "GET", "/measurements"},
"/characteristics": r{serveCharacteristicsList, "GET"}, r{serveMeasurement, "GET", "/measurements/{Id:.+}"},
"/characteristics/{Id:.+}": r{serveCharacteristic, "GET"}, r{serveCharacteristicsList, "GET", "/characteristics"},
r{serveCharacteristic, "GET", "/characteristics/{Id:.+}"},
} }
for path, route := range routes { for _, route := range routes {
s.Handle(path, j.Secure(http.HandlerFunc(route.f), verifyClaims)).Methods(route.m) s.Handle(route.p, j.Secure(http.HandlerFunc(route.f), verifyClaims)).Methods(route.m)
} }
return corsHandler(m) return corsHandler(m)

View file

@ -10,10 +10,14 @@ import (
"strings" "strings"
"time" "time"
"github.com/gorilla/context"
"github.com/gorilla/mux" "github.com/gorilla/mux"
) )
var ErrStrainNotFound = errors.New("strain not found") var (
ErrStrainNotFound = errors.New("strain not found")
ErrStrainNotUpdated = errors.New("strain not updated")
)
func init() { func init() {
DB.AddTableWithName(StrainBase{}, "strains").SetKeys(true, "Id") DB.AddTableWithName(StrainBase{}, "strains").SetKeys(true, "Id")
@ -21,7 +25,7 @@ func init() {
// StrainBase is what the DB expects to see for inserts/updates // StrainBase is what the DB expects to see for inserts/updates
type StrainBase struct { type StrainBase struct {
Id int64 `json:"id,omitempty"` Id int64 `db:"id" json:"id"`
SpeciesId int64 `db:"species_id" json:"-"` SpeciesId int64 `db:"species_id" json:"-"`
StrainName string `db:"strain_name" json:"strainName"` StrainName string `db:"strain_name" json:"strainName"`
TypeStrain bool `db:"type_strain" json:"typeStrain"` TypeStrain bool `db:"type_strain" json:"typeStrain"`
@ -105,6 +109,48 @@ func serveStrain(w http.ResponseWriter, r *http.Request) {
w.Write(data) w.Write(data)
} }
func serveUpdateStrain(w http.ResponseWriter, r *http.Request) {
id, err := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var strainjson StrainJSON
err = json.NewDecoder(r.Body).Decode(&strainjson)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c := context.Get(r, "claims")
var claims Claims = c.(Claims)
strainjson.Strain.UpdatedBy = claims.Sub
strainjson.Strain.UpdatedAt = time.Now()
strainjson.Strain.Id = id
err = dbUpdateStrain(strainjson.Strain)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var strain *Strain
strain, err = dbGetStrain(id, mux.Vars(r)["genus"])
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
data, err := json.Marshal(StrainJSON{Strain: strain})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.Write(data)
}
func dbGetStrains(opt *StrainListOptions) ([]*Strain, error) { func dbGetStrains(opt *StrainListOptions) ([]*Strain, error) {
if opt == nil { if opt == nil {
return nil, errors.New("must provide options") return nil, errors.New("must provide options")
@ -159,3 +205,20 @@ func dbGetStrain(id int64, genus string) (*Strain, error) {
} }
return &strain, nil return &strain, nil
} }
func dbUpdateStrain(strain *Strain) error {
var species_id struct{ Id int64 }
q := `SELECT id FROM species WHERE species_name = $1;`
if err := DBH.SelectOne(&species_id, q, strain.SpeciesName); err != nil {
return err
}
strain.StrainBase.SpeciesId = species_id.Id
count, err := DBH.Update(strain.StrainBase)
if err != nil {
return err
}
if count != 1 {
return ErrStrainNotUpdated
}
return nil
}