diff options
author | Steve <nilslice@gmail.com> | 2016-12-06 15:24:36 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-06 15:24:36 -0800 |
commit | f39c1519ab382a343c05163f00f38c83bff3583d (patch) | |
tree | 254f75834f2cb787179f7880b0063e667d8ad234 /system/api | |
parent | 5527117e706114c1188afaa10188d96170874047 (diff) | |
parent | 64050ef8065bccdef0aab1748040995c637fe9ed (diff) |
Merge pull request #19 from bosssauce/ponzu-dev
[core] Added account recovery process and content pagination in admin UI
Diffstat (limited to 'system/api')
-rw-r--r-- | system/api/analytics/init.go | 4 | ||||
-rw-r--r-- | system/api/external.go | 134 | ||||
-rw-r--r-- | system/api/handlers.go | 6 | ||||
-rw-r--r-- | system/api/server.go | 6 |
4 files changed, 90 insertions, 60 deletions
diff --git a/system/api/analytics/init.go b/system/api/analytics/init.go index 41c24c7..6558adf 100644 --- a/system/api/analytics/init.go +++ b/system/api/analytics/init.go @@ -66,7 +66,7 @@ func Init() { } err = store.Update(func(tx *bolt.Tx) error { - _, err := tx.CreateBucketIfNotExists([]byte("requests")) + _, err := tx.CreateBucketIfNotExists([]byte("__requests")) if err != nil { return err } @@ -138,7 +138,7 @@ func ChartData() (map[string]interface{}, error) { // get api request analytics from db var requests = []apiRequest{} err := store.View(func(tx *bolt.Tx) error { - b := tx.Bucket([]byte("requests")) + b := tx.Bucket([]byte("__requests")) err := b.ForEach(func(k, v []byte) error { var r apiRequest diff --git a/system/api/external.go b/system/api/external.go index 4e008af..0d1ea03 100644 --- a/system/api/external.go +++ b/system/api/external.go @@ -15,11 +15,17 @@ 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 } -func externalPostHandler(res http.ResponseWriter, req *http.Request) { +// 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 externalContentHandler(res http.ResponseWriter, req *http.Request) { if req.Method != http.MethodPost { res.WriteHeader(http.StatusMethodNotAllowed) return @@ -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.Set(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 + } + } diff --git a/system/api/handlers.go b/system/api/handlers.go index afe5819..8a1517b 100644 --- a/system/api/handlers.go +++ b/system/api/handlers.go @@ -28,7 +28,7 @@ func typesHandler(res http.ResponseWriter, req *http.Request) { sendData(res, j, http.StatusOK) } -func postsHandler(res http.ResponseWriter, req *http.Request) { +func contentsHandler(res http.ResponseWriter, req *http.Request) { q := req.URL.Query() t := q.Get("type") if t == "" { @@ -72,7 +72,7 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { Order: order, } - bb := db.Query(t+"_sorted", opts) + _, bb := db.Query(t+"__sorted", opts) var result = []json.RawMessage{} for i := range bb { result = append(result, bb[i]) @@ -87,7 +87,7 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { sendData(res, j, http.StatusOK) } -func postHandler(res http.ResponseWriter, req *http.Request) { +func contentHandler(res http.ResponseWriter, req *http.Request) { q := req.URL.Query() id := q.Get("id") t := q.Get("type") diff --git a/system/api/server.go b/system/api/server.go index 70add10..823ec16 100644 --- a/system/api/server.go +++ b/system/api/server.go @@ -8,9 +8,9 @@ import ( func Run() { http.HandleFunc("/api/types", CORS(Record(typesHandler))) - http.HandleFunc("/api/contents", CORS(Record(postsHandler))) + http.HandleFunc("/api/contents", CORS(Record(contentsHandler))) - http.HandleFunc("/api/content", CORS(Record(postHandler))) + http.HandleFunc("/api/content", CORS(Record(contentHandler))) - http.HandleFunc("/api/content/external", CORS(Record(externalPostHandler))) + http.HandleFunc("/api/content/external", CORS(Record(externalContentHandler))) } |