diff options
-rw-r--r-- | system/api/handlers.go | 42 | ||||
-rw-r--r-- | system/db/content.go | 10 | ||||
-rw-r--r-- | system/item/item.go | 5 |
3 files changed, 48 insertions, 9 deletions
diff --git a/system/api/handlers.go b/system/api/handlers.go index 40a4a1d..ae21500 100644 --- a/system/api/handlers.go +++ b/system/api/handlers.go @@ -36,11 +36,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) { + 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,14 +103,18 @@ func contentHandler(res http.ResponseWriter, req *http.Request) { return } + 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) { return } @@ -129,14 +138,29 @@ 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) { + return + } + j, err := fmtJSON(json.RawMessage(post)) if err != nil { res.WriteHeader(http.StatusInternalServerError) @@ -146,6 +170,16 @@ func contentHandlerBySlug(res http.ResponseWriter, req *http.Request) { sendData(res, j, http.StatusOK) } +func hide(it interface{}, res http.ResponseWriter) bool { + // check if should be hidden + if _, ok := it.(item.Hideable); ok { + res.WriteHeader(http.StatusNotFound) + return true + } + + return false +} + func fmtJSON(data ...json.RawMessage) ([]byte, error) { var msg = []json.RawMessage{} for _, d := range data { diff --git a/system/db/content.go b/system/db/content.go index 8bc76a6..dc4477f 100644 --- a/system/db/content.go +++ b/system/db/content.go @@ -229,11 +229,11 @@ func Content(target string) ([]byte, error) { // ContentBySlug does a lookup in the content index to find the type and id of // the requested content. Subsequently, issues the lookup in the type bucket and -// returns the data at that ID or nil if nothing exists. -func ContentBySlug(slug string) ([]byte, error) { +// returns the the type and data at that ID or nil if nothing exists. +func ContentBySlug(slug string) (string, []byte, error) { val := &bytes.Buffer{} + var t, id string err := store.View(func(tx *bolt.Tx) error { - var t, id string b := tx.Bucket([]byte("__contentIndex")) idx := b.Get([]byte(slug)) @@ -256,10 +256,10 @@ func ContentBySlug(slug string) ([]byte, error) { return nil }) if err != nil { - return nil, err + return t, nil, err } - return val.Bytes(), nil + return t, val.Bytes(), nil } // ContentAll retrives all items from the database within the provided namespace diff --git a/system/item/item.go b/system/item/item.go index 85ec5f9..761b2cf 100644 --- a/system/item/item.go +++ b/system/item/item.go @@ -55,6 +55,11 @@ type Hookable interface { AfterReject(req *http.Request) error } +// Hideable lets a user keep items hidden +type Hideable interface { + Hide(*http.Request) error +} + // Pushable lets a user define which values of certain struct fields are // 'pushed' down to a client via HTTP/2 Server Push. All items in the slice // should be the json tag names of the struct fields to which they coorespond |