summaryrefslogtreecommitdiff
path: root/system/api
diff options
context:
space:
mode:
Diffstat (limited to 'system/api')
-rw-r--r--system/api/handlers.go88
-rw-r--r--system/api/push.go37
2 files changed, 98 insertions, 27 deletions
diff --git a/system/api/handlers.go b/system/api/handlers.go
index 7b59dbd..8b4a387 100644
--- a/system/api/handlers.go
+++ b/system/api/handlers.go
@@ -15,8 +15,10 @@ import (
func typesHandler(res http.ResponseWriter, req *http.Request) {
var types = []string{}
- for t := range item.Types {
- types = append(types, string(t))
+ for t, fn := range item.Types {
+ if !hide(fn(), res, req) {
+ types = append(types, t)
+ }
}
j, err := toJSON(types)
@@ -36,11 +38,16 @@ func contentsHandler(res http.ResponseWriter, req *http.Request) {
return
}
- if _, ok := item.Types[t]; !ok {
+ it, ok := item.Types[t]
+ if !ok {
res.WriteHeader(http.StatusNotFound)
return
}
+ if hide(it(), res, req) {
+ return
+ }
+
count, err := strconv.Atoi(q.Get("count")) // int: determines number of posts to return (10 default, -1 is all)
if err != nil {
if q.Get("count") == "" {
@@ -98,13 +105,18 @@ func contentHandler(res http.ResponseWriter, req *http.Request) {
return
}
- if _, ok := item.Types[t]; !ok {
+ if t == "" || id == "" {
+ res.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ pt, ok := item.Types[t]
+ if !ok {
res.WriteHeader(http.StatusNotFound)
return
}
- if t == "" || id == "" {
- res.WriteHeader(http.StatusBadRequest)
+ if hide(pt(), res, req) {
return
}
@@ -114,6 +126,8 @@ func contentHandler(res http.ResponseWriter, req *http.Request) {
return
}
+ defer push(res, req, pt, post)
+
j, err := fmtJSON(json.RawMessage(post))
if err != nil {
res.WriteHeader(http.StatusInternalServerError)
@@ -126,14 +140,31 @@ func contentHandler(res http.ResponseWriter, req *http.Request) {
func contentHandlerBySlug(res http.ResponseWriter, req *http.Request) {
slug := req.URL.Query().Get("slug")
+ if slug == "" {
+ res.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
// lookup type:id by slug key in __contentIndex
- post, err := db.ContentBySlug(slug)
+ t, post, err := db.ContentBySlug(slug)
if err != nil {
log.Println("Error finding content by slug:", slug, err)
res.WriteHeader(http.StatusInternalServerError)
return
}
+ it, ok := item.Types[t]
+ if !ok {
+ res.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ if hide(it(), res, req) {
+ return
+ }
+
+ defer push(res, req, it, post)
+
j, err := fmtJSON(json.RawMessage(post))
if err != nil {
res.WriteHeader(http.StatusInternalServerError)
@@ -143,6 +174,26 @@ func contentHandlerBySlug(res http.ResponseWriter, req *http.Request) {
sendData(res, j, http.StatusOK)
}
+func hide(it interface{}, res http.ResponseWriter, req *http.Request) bool {
+ // check if should be hidden
+ if h, ok := it.(item.Hideable); ok {
+ err := h.Hide(req)
+ if err != nil && err.Error() == item.AllowHiddenItem {
+ return false
+ }
+
+ if err != nil {
+ res.WriteHeader(http.StatusInternalServerError)
+ return true
+ }
+
+ res.WriteHeader(http.StatusNotFound)
+ return true
+ }
+
+ return false
+}
+
func fmtJSON(data ...json.RawMessage) ([]byte, error) {
var msg = []json.RawMessage{}
for _, d := range data {
@@ -193,36 +244,19 @@ func sendData(res http.ResponseWriter, data []byte, code int) {
}
}
-// SendPreflight is used to respond to a cross-origin "OPTIONS" request
-func SendPreflight(res http.ResponseWriter) {
+// sendPreflight is used to respond to a cross-origin "OPTIONS" request
+func sendPreflight(res http.ResponseWriter) {
res.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type")
res.Header().Set("Access-Control-Allow-Origin", "*")
res.WriteHeader(200)
return
}
-// SendJSON returns a Response to a client as JSON
-func SendJSON(res http.ResponseWriter, j map[string]interface{}) {
- var data []byte
- var err error
-
- data, err = json.Marshal(j)
- if err != nil {
- log.Println(err)
- data, _ = json.Marshal(map[string]interface{}{
- "status": "fail",
- "message": err.Error(),
- })
- }
-
- sendData(res, data, 200)
-}
-
// CORS wraps a HandleFunc to respond to OPTIONS requests properly
func CORS(next http.HandlerFunc) http.HandlerFunc {
return db.CacheControl(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.Method == http.MethodOptions {
- SendPreflight(res)
+ sendPreflight(res)
return
}
diff --git a/system/api/push.go b/system/api/push.go
new file mode 100644
index 0000000..5db0a53
--- /dev/null
+++ b/system/api/push.go
@@ -0,0 +1,37 @@
+package api
+
+import (
+ "log"
+ "net/http"
+
+ "github.com/ponzu-cms/ponzu/system/item"
+
+ "github.com/tidwall/gjson"
+)
+
+func push(res http.ResponseWriter, req *http.Request, pt func() interface{}, data []byte) {
+ // Push(target string, opts *PushOptions) error
+ if pusher, ok := res.(http.Pusher); ok {
+ if p, ok := pt().(item.Pushable); ok {
+ // get fields to pull values from data
+ fields := p.Push()
+
+ // parse values from data to push
+ values := gjson.GetManyBytes(data, fields...)
+
+ // push all values from Pushable items' fields
+ for i := range values {
+ val := values[i]
+ val.ForEach(func(k, v gjson.Result) bool {
+ err := pusher.Push(req.URL.Path+v.String(), nil)
+ if err != nil {
+ log.Println("Error during Push of value:", v.String())
+ }
+
+ return true
+ })
+ }
+ }
+ }
+
+}