) var MiddlewarePostHack = he.Middleware{ Outside: func(req he.Request, handle func(he.Request) he.Response) he.Response { if req.Method != "POST" { return handle(req) } decoder, ok := req.Entity.(*json.Decoder) if !ok { return handle(req) } var entity interface{} err := decoder.Decode(&entity) if err != nil { return rfc7231.StatusUnsupportedMediaType(he.ErrorToNetEntity(415, locale.Errorf("Couldn't parse: %v", err))) } hash, ok := entity.(map[string]interface{}) if !ok { return handle(req) } method, ok := hash["_method"].(string) delete(hash, "_method") if ok { req.Method = method } xsrf_token, ok := hash["_xsrf_token"].(string) delete(hash, "_xsrf_token")
func (usr *user) Methods() map[string]func(he.Request) he.Response { return map[string]func(he.Request) he.Response{ "GET": func(req he.Request) he.Response { var addresses []backend.UserAddress for _, addr := range usr.Addresses { if addr.Medium != "noop" && addr.Medium != "admin" { addresses = append(addresses, addr) } } usr.Addresses = addresses return rfc7231.StatusOK(usr) }, "PUT": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) sess := req.Things["session"].(*backend.Session) if sess.UserID != usr.ID { return rfc7231.StatusForbidden(he.NetPrintf("Unauthorized user")) } var newUser user httperr := safeDecodeJSON(req.Entity, &newUser) if httperr != nil { return *httperr } if usr.ID != newUser.ID { return rfc7231.StatusConflict(he.NetPrintf("Cannot change user id")) } // TODO: this won't play nice with the // password hash (because it's private), or // with addresses (because the (private) IDs // need to be made to match up) *usr = newUser usr.backend().Save(db) return rfc7231.StatusOK(usr) }, "PATCH": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) sess := req.Things["session"].(*backend.Session) if sess.UserID != usr.ID { return rfc7231.StatusForbidden(he.NetPrintf("Unauthorized user")) } patch, ok := req.Entity.(jsonpatch.Patch) if !ok { return rfc7231.StatusUnsupportedMediaType(he.NetPrintf("PATCH request must have a patch media type")) } httperr := usr.patchPassword(&patch) if httperr != nil { return *httperr } var newUser user err := patch.Apply(usr, &newUser) if err != nil { return rfc7231.StatusConflict(he.ErrorToNetEntity(409, err)) } if usr.ID != newUser.ID { return rfc7231.StatusConflict(he.NetPrintf("Cannot change user id")) } if newUser.PwHash == nil || len(newUser.PwHash) == 0 { newUser.PwHash = usr.PwHash } *usr = newUser usr.backend().Save(db) return rfc7231.StatusOK(usr) }, "DELETE": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) usr.backend().Delete(db) return rfc7231.StatusNoContent() }, } }