diff options
-rw-r--r-- | system/api/external.go | 132 |
1 files changed, 81 insertions, 51 deletions
diff --git a/system/api/external.go b/system/api/external.go index 4e008af..0c2423b 100644 --- a/system/api/external.go +++ b/system/api/external.go @@ -15,8 +15,14 @@ import ( // Externalable accepts or rejects external POST requests to endpoints such as: // /external/content?type=Review type Externalable interface { - // Accepts determines whether a type will allow external submissions - Accepts() bool + // Accept allows external content submissions of a specific type + Accept(req *http.Request) error +} + +// Trustable allows external content to be auto-approved, meaning content sent +// as an Externalable will be stored in the public content bucket +type Trustable interface { + AutoApprove(req *http.Request) error } func externalPostHandler(res http.ResponseWriter, req *http.Request) { @@ -54,69 +60,93 @@ func externalPostHandler(res http.ResponseWriter, req *http.Request) { return } - if ext.Accepts() { - ts := fmt.Sprintf("%d", time.Now().Unix()*1000) - req.PostForm.Set("timestamp", ts) - req.PostForm.Set("updated", ts) + ts := fmt.Sprintf("%d", time.Now().Unix()*1000) + req.PostForm.Set("timestamp", ts) + req.PostForm.Set("updated", ts) - urlPaths, err := upload.StoreFiles(req) - if err != nil { - log.Println(err) - res.WriteHeader(http.StatusInternalServerError) - return - } + urlPaths, err := upload.StoreFiles(req) + if err != nil { + log.Println(err) + res.WriteHeader(http.StatusInternalServerError) + return + } - for name, urlPath := range urlPaths { - req.PostForm.Add(name, urlPath) - } + for name, urlPath := range urlPaths { + req.PostForm.Add(name, urlPath) + } - // check for any multi-value fields (ex. checkbox fields) - // and correctly format for db storage. Essentially, we need - // fieldX.0: value1, fieldX.1: value2 => fieldX: []string{value1, value2} - var discardKeys []string - for k, v := range req.PostForm { - if strings.Contains(k, ".") { - key := strings.Split(k, ".")[0] - - if req.PostForm.Get(key) == "" { - req.PostForm.Set(key, v[0]) - discardKeys = append(discardKeys, k) - } else { - req.PostForm.Add(key, v[0]) - } + // check for any multi-value fields (ex. checkbox fields) + // and correctly format for db storage. Essentially, we need + // fieldX.0: value1, fieldX.1: value2 => fieldX: []string{value1, value2} + var discardKeys []string + for k, v := range req.PostForm { + if strings.Contains(k, ".") { + key := strings.Split(k, ".")[0] + + if req.PostForm.Get(key) == "" { + req.PostForm.Set(key, v[0]) + discardKeys = append(discardKeys, k) + } else { + req.PostForm.Add(key, v[0]) } } + } - for _, discardKey := range discardKeys { - req.PostForm.Del(discardKey) - } + for _, discardKey := range discardKeys { + req.PostForm.Del(discardKey) + } - hook, ok := post.(content.Hookable) - if !ok { - log.Println("[External] error: Type", t, "does not implement content.Hookable or embed content.Item.") - res.WriteHeader(http.StatusBadRequest) - return - } + // call Accept with the request, enabling developer to add or chack data + // before saving to DB + err = ext.Accept(req) + if err != nil { + log.Println(err) + res.WriteHeader(http.StatusInternalServerError) + return + } - err = hook.BeforeSave(req) - if err != nil { - log.Println("[External] error:", err) - res.WriteHeader(http.StatusInternalServerError) - return - } + hook, ok := post.(content.Hookable) + if !ok { + log.Println("[External] error: Type", t, "does not implement content.Hookable or embed content.Item.") + res.WriteHeader(http.StatusBadRequest) + return + } - _, err = db.SetContent(t+"_pending:-1", req.PostForm) - if err != nil { - log.Println("[External] error:", err) - res.WriteHeader(http.StatusInternalServerError) - return - } + err = hook.BeforeSave(req) + if err != nil { + log.Println("[External] error:", err) + res.WriteHeader(http.StatusInternalServerError) + return + } + + // set specifier for db bucket in case content is/isn't Trustable + var spec string - err = hook.AfterSave(req) + // check if the content is Trustable should be auto-approved + trusted, ok := post.(Trustable) + if ok { + err := trusted.AutoApprove(req) if err != nil { log.Println("[External] error:", err) res.WriteHeader(http.StatusInternalServerError) return } + } else { + spec = "_pending" } + + _, err = db.SetContent(t+spec+":-1", req.PostForm) + if err != nil { + log.Println("[External] error:", err) + res.WriteHeader(http.StatusInternalServerError) + return + } + + err = hook.AfterSave(req) + if err != nil { + log.Println("[External] error:", err) + res.WriteHeader(http.StatusInternalServerError) + return + } + } |