From 6403622d1916da245600c3bff6f1193d71375668 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 26 May 2015 14:44:23 -0800 Subject: [PATCH] Update strain (rough) --- handlers.go | 42 +++++++++++++++++++-------------- strains.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 20 deletions(-) diff --git a/handlers.go b/handlers.go index 5555c80..22a8404 100644 --- a/handlers.go +++ b/handlers.go @@ -8,10 +8,20 @@ import ( "strings" "time" + "github.com/gorilla/context" "github.com/gorilla/mux" "github.com/thermokarst/jwt" ) +type Claims struct { + Name string + Iss string + Sub int64 + Role string + Iat int64 + Exp int64 +} + func Handler() http.Handler { claimsFunc := func(email string) (map[string]interface{}, error) { currentTime := time.Now() @@ -29,16 +39,9 @@ func Handler() http.Handler { }, nil } - verifyClaims := func(claims []byte) error { + verifyClaims := func(claims []byte, r *http.Request) error { currentTime := time.Now() - var c struct { - Name string - Iss string - Sub int64 - Role string - Iat int64 - Exp int64 - } + var c Claims err := json.Unmarshal(claims, &c) if err != nil { return err @@ -46,6 +49,7 @@ func Handler() http.Handler { if currentTime.After(time.Unix(c.Exp, 0)) { return errors.New("this token has expired") } + context.Set(r, "claims", c) return nil } @@ -75,19 +79,21 @@ func Handler() http.Handler { type r struct { f http.HandlerFunc m string + p string } - routes := map[string]r{ - "/strains": r{serveStrainsList, "GET"}, - "/strains/{Id:.+}": r{serveStrain, "GET"}, - "/measurements": r{serveMeasurementsList, "GET"}, - "/measurements/{Id:.+}": r{serveMeasurement, "GET"}, - "/characteristics": r{serveCharacteristicsList, "GET"}, - "/characteristics/{Id:.+}": r{serveCharacteristic, "GET"}, + routes := []r{ + r{serveStrainsList, "GET", "/strains"}, + r{serveStrain, "GET", "/strains/{Id:.+}"}, + r{serveUpdateStrain, "PUT", "/strains/{Id:.+}"}, + r{serveMeasurementsList, "GET", "/measurements"}, + r{serveMeasurement, "GET", "/measurements/{Id:.+}"}, + r{serveCharacteristicsList, "GET", "/characteristics"}, + r{serveCharacteristic, "GET", "/characteristics/{Id:.+}"}, } - for path, route := range routes { - s.Handle(path, j.Secure(http.HandlerFunc(route.f), verifyClaims)).Methods(route.m) + for _, route := range routes { + s.Handle(route.p, j.Secure(http.HandlerFunc(route.f), verifyClaims)).Methods(route.m) } return corsHandler(m) diff --git a/strains.go b/strains.go index 1215e5e..b72883a 100644 --- a/strains.go +++ b/strains.go @@ -10,10 +10,14 @@ import ( "strings" "time" + "github.com/gorilla/context" "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() { DB.AddTableWithName(StrainBase{}, "strains").SetKeys(true, "Id") @@ -21,7 +25,7 @@ func init() { // StrainBase is what the DB expects to see for inserts/updates type StrainBase struct { - Id int64 `json:"id,omitempty"` + Id int64 `db:"id" json:"id"` SpeciesId int64 `db:"species_id" json:"-"` StrainName string `db:"strain_name" json:"strainName"` TypeStrain bool `db:"type_strain" json:"typeStrain"` @@ -105,6 +109,48 @@ func serveStrain(w http.ResponseWriter, r *http.Request) { 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) { if opt == nil { return nil, errors.New("must provide options") @@ -159,3 +205,20 @@ func dbGetStrain(id int64, genus string) (*Strain, error) { } 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 +}