summaryrefslogtreecommitdiff
path: root/system/api/external.go
diff options
context:
space:
mode:
Diffstat (limited to 'system/api/external.go')
-rw-r--r--system/api/external.go132
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
+ }
+
}