Improve micropub handling

This commit is contained in:
Peter Stuifzand 2019-03-23 23:13:32 +01:00
parent dbfe957f63
commit e55232e00b
Signed by: peter
GPG Key ID: 374322D56E5209E8

View File

@ -59,18 +59,21 @@ func parseIncomingItem(r *http.Request) (*microsub.Item, error) {
return &item, nil return &item, nil
} }
/*
* URLs needed:
* - / with endpoint urls
* - /micropub micropub endpoint
* - /auth auth endpoint
* - /token token endpoint
*/
func (h *micropubHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *micropubHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close() defer func() {
err := r.Body.Close()
if err != nil {
log.Printf("could not close request body: %v", err)
}
}()
conn := h.pool.Get() conn := h.pool.Get()
defer conn.Close() defer func() {
err := conn.Close()
if err != nil {
log.Printf("could not close redis connection: %v", err)
}
}()
err := r.ParseForm() err := r.ParseForm()
if err != nil { if err != nil {
@ -79,20 +82,19 @@ func (h *micropubHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
if r.Method == http.MethodPost { if r.Method == http.MethodPost {
sourceID := r.URL.Query().Get("source_id") var channel string
authHeader := r.Header.Get("Authorization") channel, err = getChannelFromAuthorization(r, conn)
if strings.HasPrefix(authHeader, "Bearer ") { if err != nil {
sourceID = authHeader[7:] log.Println(err)
http.Error(w, "unauthorized", 401)
return
} }
channel, err := redis.String(conn.Do("HGET", "sources", sourceID)) // no channel is found
if err != nil { if channel == "" {
channel, err = redis.String(conn.Do("HGET", "token:"+sourceID, "channel")) http.Error(w, "bad request, unknown channel", 400)
if err != nil { return
http.Error(w, "unauthorized", 401)
return
}
} }
item, err := parseIncomingItem(r) item, err := parseIncomingItem(r)
@ -102,9 +104,12 @@ func (h *micropubHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
item.Read = false item.Read = false
id, _ := redis.Int(conn.Do("INCR", "source:"+sourceID+"next_id")) id, _ := redis.Int(conn.Do("INCR", fmt.Sprintf("source:%s:next_id", channel)))
item.ID = fmt.Sprintf("%x", sha1.Sum([]byte(fmt.Sprintf("source:%s:%d", sourceID, id)))) item.ID = fmt.Sprintf("%x", sha1.Sum([]byte(fmt.Sprintf("source:%s:%d", channel, id))))
err = h.Backend.channelAddItemWithMatcher(channel, *item) err = h.Backend.channelAddItemWithMatcher(channel, *item)
if err != nil {
log.Printf("could not add item to channel %s: %v", channel, err)
}
err = h.Backend.updateChannelUnreadCount(channel) err = h.Backend.updateChannelUnreadCount(channel)
if err != nil { if err != nil {
log.Printf("could not update channel unread content %s: %v", channel, err) log.Printf("could not update channel unread content %s: %v", channel, err)
@ -112,13 +117,38 @@ func (h *micropubHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
enc := json.NewEncoder(w) if err = json.NewEncoder(w).Encode(map[string]string{"ok": "1"}); err != nil {
err = enc.Encode(map[string]string{ http.Error(w, "internal server error", 500)
"ok": "1", }
})
return return
} }
http.Error(w, "Method not allowed", 405) http.Error(w, "Method not allowed", 405)
} }
func getChannelFromAuthorization(r *http.Request, conn redis.Conn) (string, error) {
// backward compatible
sourceID := r.URL.Query().Get("source_id")
if sourceID != "" {
channel, err := redis.String(conn.Do("HGET", "sources", sourceID))
if err != nil {
return "", errors.Wrapf(err, "could not get channel for sourceID: %s", sourceID)
}
return channel, nil
}
// full micropub with indieauth
authHeader := r.Header.Get("Authorization")
if strings.HasPrefix(authHeader, "Bearer ") {
token := authHeader[7:]
channel, err := redis.String(conn.Do("HGET", "token:"+token, "channel"))
if err != nil {
return "", errors.Wrap(err, "could not get channel for token")
}
return channel, nil
}
return "", fmt.Errorf("could not get channel from authorization")
}