mirror of https://github.com/jlelse/GoBlog
Improve error rendering
This commit is contained in:
parent
59388e8654
commit
9e4a03549f
|
@ -74,13 +74,13 @@ func initActivityPub() error {
|
||||||
func apHandleWebfinger(w http.ResponseWriter, r *http.Request) {
|
func apHandleWebfinger(w http.ResponseWriter, r *http.Request) {
|
||||||
re, err := regexp.Compile(`^acct:(.*)@` + regexp.QuoteMeta(appConfig.Server.Domain) + `$`)
|
re, err := regexp.Compile(`^acct:(.*)@` + regexp.QuoteMeta(appConfig.Server.Domain) + `$`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
name := re.ReplaceAllString(r.URL.Query().Get("resource"), "$1")
|
name := re.ReplaceAllString(r.URL.Query().Get("resource"), "$1")
|
||||||
blog := appConfig.Blogs[name]
|
blog := appConfig.Blogs[name]
|
||||||
if blog == nil {
|
if blog == nil {
|
||||||
http.Error(w, "Not found", http.StatusNotFound)
|
serveError(w, r, "Blog not found", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set(contentType, "application/jrd+json"+charsetUtf8Suffix)
|
w.Header().Set(contentType, "application/jrd+json"+charsetUtf8Suffix)
|
||||||
|
@ -100,7 +100,7 @@ func apHandleInbox(w http.ResponseWriter, r *http.Request) {
|
||||||
blogName := chi.URLParam(r, "blog")
|
blogName := chi.URLParam(r, "blog")
|
||||||
blog := appConfig.Blogs[blogName]
|
blog := appConfig.Blogs[blogName]
|
||||||
if blog == nil {
|
if blog == nil {
|
||||||
http.Error(w, "Inbox not found", http.StatusNotFound)
|
serveError(w, r, "Inbox not found", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
blogIri := blog.apIri()
|
blogIri := blog.apIri()
|
||||||
|
@ -108,7 +108,7 @@ func apHandleInbox(w http.ResponseWriter, r *http.Request) {
|
||||||
requestActor, requestKey, requestActorStatus, err := apVerifySignature(r)
|
requestActor, requestKey, requestActorStatus, err := apVerifySignature(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Send 401 because signature could not be verified
|
// Send 401 because signature could not be verified
|
||||||
http.Error(w, err.Error(), http.StatusUnauthorized)
|
serveError(w, r, err.Error(), http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if requestActorStatus != 0 {
|
if requestActorStatus != 0 {
|
||||||
|
@ -122,7 +122,7 @@ func apHandleInbox(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
http.Error(w, "Error when trying to get request actor", http.StatusBadRequest)
|
serveError(w, r, "Error when trying to get request actor", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Parse activity
|
// Parse activity
|
||||||
|
@ -130,17 +130,17 @@ func apHandleInbox(w http.ResponseWriter, r *http.Request) {
|
||||||
err = json.NewDecoder(r.Body).Decode(&activity)
|
err = json.NewDecoder(r.Body).Decode(&activity)
|
||||||
_ = r.Body.Close()
|
_ = r.Body.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Failed to decode body", http.StatusBadRequest)
|
serveError(w, r, "Failed to decode body", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Get and check activity actor
|
// Get and check activity actor
|
||||||
activityActor, ok := activity["actor"].(string)
|
activityActor, ok := activity["actor"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
http.Error(w, "actor in activity is no string", http.StatusBadRequest)
|
serveError(w, r, "actor in activity is no string", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if activityActor != requestActor.ID {
|
if activityActor != requestActor.ID {
|
||||||
http.Error(w, "Request actor isn't activity actor", http.StatusForbidden)
|
serveError(w, r, "Request actor isn't activity actor", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Do
|
// Do
|
||||||
|
|
|
@ -119,10 +119,10 @@ func (p *post) toASNote() *asNote {
|
||||||
return as
|
return as
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *configBlog) serveActivityStreams(blog string, w http.ResponseWriter) {
|
func (b *configBlog) serveActivityStreams(blog string, w http.ResponseWriter, r *http.Request) {
|
||||||
publicKeyDer, err := x509.MarshalPKIXPublicKey(&apPrivateKey.PublicKey)
|
publicKeyDer, err := x509.MarshalPKIXPublicKey(&apPrivateKey.PublicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Failed to marshal public key", http.StatusInternalServerError)
|
serveError(w, r, "Failed to marshal public key", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Send JSON
|
// Send JSON
|
||||||
|
|
8
api.go
8
api.go
|
@ -17,12 +17,12 @@ func apiPostCreateHugo(w http.ResponseWriter, r *http.Request) {
|
||||||
}()
|
}()
|
||||||
bodyContent, err := ioutil.ReadAll(r.Body)
|
bodyContent, err := ioutil.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p, aliases, err := parseHugoFile(string(bodyContent))
|
p, aliases, err := parseHugoFile(string(bodyContent))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.Blog = blog
|
p.Blog = blog
|
||||||
|
@ -31,7 +31,7 @@ func apiPostCreateHugo(w http.ResponseWriter, r *http.Request) {
|
||||||
p.Slug = slug
|
p.Slug = slug
|
||||||
err = p.replace()
|
err = p.replace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
aliases = append(aliases, alias)
|
aliases = append(aliases, alias)
|
||||||
|
@ -51,7 +51,7 @@ func apiPostCreateHugo(w http.ResponseWriter, r *http.Request) {
|
||||||
p.Parameters["aliases"] = aliases
|
p.Parameters["aliases"] = aliases
|
||||||
err = p.replace()
|
err = p.replace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ func checkLogin(w http.ResponseWriter, r *http.Request) bool {
|
||||||
// Set basic auth
|
// Set basic auth
|
||||||
req.SetBasicAuth(r.FormValue("username"), r.FormValue("password"))
|
req.SetBasicAuth(r.FormValue("username"), r.FormValue("password"))
|
||||||
// Send cookie
|
// Send cookie
|
||||||
sendTokenCookie(w)
|
sendTokenCookie(w, r)
|
||||||
// Serve original request
|
// Serve original request
|
||||||
d.ServeHTTP(w, req)
|
d.ServeHTTP(w, req)
|
||||||
return true
|
return true
|
||||||
|
@ -90,11 +90,11 @@ func checkLogin(w http.ResponseWriter, r *http.Request) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendTokenCookie(w http.ResponseWriter) {
|
func sendTokenCookie(w http.ResponseWriter, r *http.Request) {
|
||||||
expiration := time.Now().Add(7 * 24 * time.Hour)
|
expiration := time.Now().Add(7 * 24 * time.Hour)
|
||||||
tokenString, err := jwt.NewWithClaims(jwt.SigningMethodHS256, &jwt.StandardClaims{ExpiresAt: expiration.Unix()}).SignedString(jwtKey())
|
tokenString, err := jwt.NewWithClaims(jwt.SigningMethodHS256, &jwt.StandardClaims{ExpiresAt: expiration.Unix()}).SignedString(jwtKey())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "failed to sign JWT", http.StatusInternalServerError)
|
serveError(w, r, "Failed to sign JWT", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.SetCookie(w, &http.Cookie{
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import "net/http"
|
import "net/http"
|
||||||
|
|
||||||
func serveCustomPage(blog *configBlog, page *customPage) func(w http.ResponseWriter, r *http.Request) {
|
func serveCustomPage(blog *configBlog, page *customPage) func(w http.ResponseWriter, r *http.Request) {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, _ *http.Request) {
|
||||||
if appConfig.Cache != nil && appConfig.Cache.Enable && page.Cache {
|
if appConfig.Cache != nil && appConfig.Cache.Enable && page.Cache {
|
||||||
if page.CacheExpiration != 0 {
|
if page.CacheExpiration != 0 {
|
||||||
setInternalCacheExpirationHeader(w, page.CacheExpiration)
|
setInternalCacheExpirationHeader(w, page.CacheExpiration)
|
||||||
|
|
12
editor.go
12
editor.go
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
const editorPath = "/editor"
|
const editorPath = "/editor"
|
||||||
|
|
||||||
func serveEditor(w http.ResponseWriter, r *http.Request) {
|
func serveEditor(w http.ResponseWriter, _ *http.Request) {
|
||||||
render(w, templateEditor, &renderData{})
|
render(w, templateEditor, &renderData{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,12 +20,12 @@ func serveEditorPost(w http.ResponseWriter, r *http.Request) {
|
||||||
case "loadupdate":
|
case "loadupdate":
|
||||||
parsedURL, err := url.Parse(r.FormValue("url"))
|
parsedURL, err := url.Parse(r.FormValue("url"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
post, err := getPost(parsedURL.Path)
|
post, err := getPost(parsedURL.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mf := post.toMfItem()
|
mf := post.toMfItem()
|
||||||
|
@ -49,12 +49,12 @@ func serveEditorPost(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
jsonBytes, err := json.Marshal(mf)
|
jsonBytes, err := json.Marshal(mf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req, err := http.NewRequest(http.MethodPost, "", bytes.NewReader(jsonBytes))
|
req, err := http.NewRequest(http.MethodPost, "", bytes.NewReader(jsonBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.Header.Set(contentType, contentTypeJSON)
|
req.Header.Set(contentType, contentTypeJSON)
|
||||||
|
@ -62,7 +62,7 @@ func serveEditorPost(w http.ResponseWriter, r *http.Request) {
|
||||||
case "upload":
|
case "upload":
|
||||||
editorMicropubPost(w, r, true)
|
editorMicropubPost(w, r, true)
|
||||||
default:
|
default:
|
||||||
http.Error(w, "unknown editoraction", http.StatusBadRequest)
|
serveError(w, r, "Unknown editoraction", http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
19
errors.go
19
errors.go
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type errorData struct {
|
type errorData struct {
|
||||||
|
@ -11,11 +12,23 @@ type errorData struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func serve404(w http.ResponseWriter, r *http.Request) {
|
func serve404(w http.ResponseWriter, r *http.Request) {
|
||||||
|
serveError(w, r, fmt.Sprintf("%s was not found", r.RequestURI), http.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
func serveError(w http.ResponseWriter, r *http.Request, message string, status int) {
|
||||||
|
if !strings.Contains(strings.ToLower(r.Header.Get("Accept")), contentTypeHTML) {
|
||||||
|
http.Error(w, message, status)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
title := fmt.Sprintf("%d %s", status, http.StatusText(status))
|
||||||
|
if message == "" {
|
||||||
|
message = http.StatusText(status)
|
||||||
|
}
|
||||||
render(w, templateError, &renderData{
|
render(w, templateError, &renderData{
|
||||||
Data: &errorData{
|
Data: &errorData{
|
||||||
Title: "404 Not Found",
|
Title: title,
|
||||||
Message: fmt.Sprintf("`%s` was not found", r.RequestURI),
|
Message: message,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(status)
|
||||||
}
|
}
|
||||||
|
|
2
feeds.go
2
feeds.go
|
@ -81,7 +81,7 @@ func generateFeed(blog string, f feedType, w http.ResponseWriter, r *http.Reques
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Header().Del(contentType)
|
w.Header().Del(contentType)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
4
http.go
4
http.go
|
@ -296,6 +296,10 @@ func buildHandler() (http.Handler, error) {
|
||||||
// Check redirects, then serve 404
|
// Check redirects, then serve 404
|
||||||
r.With(checkRegexRedirects, cacheMiddleware, minifier.Middleware).NotFound(serve404)
|
r.With(checkRegexRedirects, cacheMiddleware, minifier.Middleware).NotFound(serve404)
|
||||||
|
|
||||||
|
r.With(minifier.Middleware).MethodNotAllowed(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
serveError(rw, r, "", http.StatusMethodNotAllowed)
|
||||||
|
})
|
||||||
|
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ func checkIndieAuth(next http.Handler) http.Handler {
|
||||||
}
|
}
|
||||||
tokenData, err := verifyIndieAuthToken(bearerToken)
|
tokenData, err := verifyIndieAuthToken(bearerToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusUnauthorized)
|
serveError(w, r, err.Error(), http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
next.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), "scope", strings.Join(tokenData.Scopes, " "))))
|
next.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), "scope", strings.Join(tokenData.Scopes, " "))))
|
||||||
|
|
|
@ -35,18 +35,18 @@ func indieAuthRequest(w http.ResponseWriter, r *http.Request) {
|
||||||
State: r.Form.Get("state"),
|
State: r.Form.Get("state"),
|
||||||
}
|
}
|
||||||
if rt := r.Form.Get("response_type"); rt != "code" && rt != "id" && rt != "" {
|
if rt := r.Form.Get("response_type"); rt != "code" && rt != "id" && rt != "" {
|
||||||
http.Error(w, "response_type must be code", http.StatusBadRequest)
|
serveError(w, r, "response_type must be code", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if scope := r.Form.Get("scope"); scope != "" {
|
if scope := r.Form.Get("scope"); scope != "" {
|
||||||
data.Scopes = strings.Split(scope, " ")
|
data.Scopes = strings.Split(scope, " ")
|
||||||
}
|
}
|
||||||
if !isValidProfileURL(data.ClientID) || !isValidProfileURL(data.RedirectURI) {
|
if !isValidProfileURL(data.ClientID) || !isValidProfileURL(data.RedirectURI) {
|
||||||
http.Error(w, "client_id and redirect_uri need to by valid URLs", http.StatusBadRequest)
|
serveError(w, r, "client_id and redirect_uri need to by valid URLs", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if data.State == "" {
|
if data.State == "" {
|
||||||
http.Error(w, "state must not be empty", http.StatusBadRequest)
|
serveError(w, r, "state must not be empty", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
render(w, "indieauth", &renderData{
|
render(w, "indieauth", &renderData{
|
||||||
|
@ -90,7 +90,7 @@ func indieAuthAccept(w http.ResponseWriter, r *http.Request) {
|
||||||
data.code = fmt.Sprintf("%x", sha.Sum(nil))
|
data.code = fmt.Sprintf("%x", sha.Sum(nil))
|
||||||
err := data.saveAuthorization()
|
err := data.saveAuthorization()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, data.RedirectURI+"?code="+data.code+"&state="+data.State, http.StatusFound)
|
http.Redirect(w, r, data.RedirectURI+"?code="+data.code+"&state="+data.State, http.StatusFound)
|
||||||
|
@ -114,11 +114,11 @@ func indieAuthVerification(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
valid, err := data.verifyAuthorization()
|
valid, err := data.verifyAuthorization()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !valid {
|
if !valid {
|
||||||
http.Error(w, "Authentication not valid", http.StatusForbidden)
|
serveError(w, r, "Authentication not valid", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res := &tokenResponse{
|
res := &tokenResponse{
|
||||||
|
@ -128,7 +128,7 @@ func indieAuthVerification(w http.ResponseWriter, r *http.Request) {
|
||||||
err = json.NewEncoder(w).Encode(res)
|
err = json.NewEncoder(w).Encode(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Header().Del(contentType)
|
w.Header().Del(contentType)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ func indieAuthToken(w http.ResponseWriter, r *http.Request) {
|
||||||
// Token verification
|
// Token verification
|
||||||
data, err := verifyIndieAuthToken(r.Header.Get("Authorization"))
|
data, err := verifyIndieAuthToken(r.Header.Get("Authorization"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Invalid token or token not found", http.StatusUnauthorized)
|
serveError(w, r, "Invalid token or token not found", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res := &tokenResponse{
|
res := &tokenResponse{
|
||||||
|
@ -150,7 +150,7 @@ func indieAuthToken(w http.ResponseWriter, r *http.Request) {
|
||||||
err = json.NewEncoder(w).Encode(res)
|
err = json.NewEncoder(w).Encode(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Header().Del(contentType)
|
w.Header().Del(contentType)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -171,15 +171,15 @@ func indieAuthToken(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
valid, err := data.verifyAuthorization()
|
valid, err := data.verifyAuthorization()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !valid {
|
if !valid {
|
||||||
http.Error(w, "Authentication not valid", http.StatusForbidden)
|
serveError(w, r, "Authentication not valid", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(data.Scopes) < 1 {
|
if len(data.Scopes) < 1 {
|
||||||
http.Error(w, "No scope", http.StatusBadRequest)
|
serveError(w, r, "No scope", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data.time = time.Now()
|
data.time = time.Now()
|
||||||
|
@ -188,7 +188,7 @@ func indieAuthToken(w http.ResponseWriter, r *http.Request) {
|
||||||
data.token = fmt.Sprintf("%x", sha.Sum(nil))
|
data.token = fmt.Sprintf("%x", sha.Sum(nil))
|
||||||
err = data.saveToken()
|
err = data.saveToken()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res := &tokenResponse{
|
res := &tokenResponse{
|
||||||
|
@ -201,12 +201,12 @@ func indieAuthToken(w http.ResponseWriter, r *http.Request) {
|
||||||
err = json.NewEncoder(w).Encode(res)
|
err = json.NewEncoder(w).Encode(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Header().Del(contentType)
|
w.Header().Del(contentType)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
serveError(w, r, "", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
44
micropub.go
44
micropub.go
|
@ -36,12 +36,12 @@ func serveMicropubQuery(w http.ResponseWriter, r *http.Request) {
|
||||||
if urlString := r.URL.Query().Get("url"); urlString != "" {
|
if urlString := r.URL.Query().Get("url"); urlString != "" {
|
||||||
u, err := url.Parse(r.URL.Query().Get("url"))
|
u, err := url.Parse(r.URL.Query().Get("url"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p, err := getPost(u.Path)
|
p, err := getPost(u.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mf = p.toMfItem()
|
mf = p.toMfItem()
|
||||||
|
@ -53,7 +53,7 @@ func serveMicropubQuery(w http.ResponseWriter, r *http.Request) {
|
||||||
offset: offset,
|
offset: offset,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
list := map[string][]*microformatItem{}
|
list := map[string][]*microformatItem{}
|
||||||
|
@ -70,7 +70,7 @@ func serveMicropubQuery(w http.ResponseWriter, r *http.Request) {
|
||||||
for blog := range appConfig.Blogs {
|
for blog := range appConfig.Blogs {
|
||||||
values, err := allTaxonomyValues(blog, appConfig.Micropub.CategoryParam)
|
values, err := allTaxonomyValues(blog, appConfig.Micropub.CategoryParam)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
allCategories = append(allCategories, values...)
|
allCategories = append(allCategories, values...)
|
||||||
|
@ -81,7 +81,7 @@ func serveMicropubQuery(w http.ResponseWriter, r *http.Request) {
|
||||||
"categories": allCategories,
|
"categories": allCategories,
|
||||||
})
|
})
|
||||||
default:
|
default:
|
||||||
w.WriteHeader(http.StatusNotFound)
|
serve404(w, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,38 +124,38 @@ func serveMicropubPost(w http.ResponseWriter, r *http.Request) {
|
||||||
err = r.ParseForm()
|
err = r.ParseForm()
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if action := micropubAction(r.Form.Get("action")); action != "" {
|
if action := micropubAction(r.Form.Get("action")); action != "" {
|
||||||
u, err := url.Parse(r.Form.Get("url"))
|
u, err := url.Parse(r.Form.Get("url"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if action == actionDelete {
|
if action == actionDelete {
|
||||||
micropubDelete(w, r, u)
|
micropubDelete(w, r, u)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Error(w, "Action not supported", http.StatusNotImplemented)
|
serveError(w, r, "Action not supported", http.StatusNotImplemented)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p, err = convertMPValueMapToPost(r.Form)
|
p, err = convertMPValueMapToPost(r.Form)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if strings.Contains(ct, contentTypeJSON) {
|
} else if strings.Contains(ct, contentTypeJSON) {
|
||||||
parsedMfItem := µformatItem{}
|
parsedMfItem := µformatItem{}
|
||||||
err := json.NewDecoder(r.Body).Decode(parsedMfItem)
|
err := json.NewDecoder(r.Body).Decode(parsedMfItem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if parsedMfItem.Action != "" {
|
if parsedMfItem.Action != "" {
|
||||||
u, err := url.Parse(parsedMfItem.URL)
|
u, err := url.Parse(parsedMfItem.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if parsedMfItem.Action == actionDelete {
|
if parsedMfItem.Action == actionDelete {
|
||||||
|
@ -166,25 +166,25 @@ func serveMicropubPost(w http.ResponseWriter, r *http.Request) {
|
||||||
micropubUpdate(w, r, u, parsedMfItem)
|
micropubUpdate(w, r, u, parsedMfItem)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Error(w, "Action not supported", http.StatusNotImplemented)
|
serveError(w, r, "Action not supported", http.StatusNotImplemented)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p, err = convertMPMfToPost(parsedMfItem)
|
p, err = convertMPMfToPost(parsedMfItem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "wrong content type", http.StatusBadRequest)
|
serveError(w, r, "wrong content type", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !strings.Contains(r.Context().Value("scope").(string), "create") {
|
if !strings.Contains(r.Context().Value("scope").(string), "create") {
|
||||||
http.Error(w, "create scope missing", http.StatusForbidden)
|
serveError(w, r, "create scope missing", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err := p.create()
|
err := p.create()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, p.fullURL(), http.StatusAccepted)
|
http.Redirect(w, r, p.fullURL(), http.StatusAccepted)
|
||||||
|
@ -418,11 +418,11 @@ func (p *post) computeExtraPostParameters() error {
|
||||||
|
|
||||||
func micropubDelete(w http.ResponseWriter, r *http.Request, u *url.URL) {
|
func micropubDelete(w http.ResponseWriter, r *http.Request, u *url.URL) {
|
||||||
if !strings.Contains(r.Context().Value("scope").(string), "delete") {
|
if !strings.Contains(r.Context().Value("scope").(string), "delete") {
|
||||||
http.Error(w, "delete scope missing", http.StatusForbidden)
|
serveError(w, r, "delete scope missing", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := deletePost(u.Path); err != nil {
|
if err := deletePost(u.Path); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, u.String(), http.StatusNoContent)
|
http.Redirect(w, r, u.String(), http.StatusNoContent)
|
||||||
|
@ -431,12 +431,12 @@ func micropubDelete(w http.ResponseWriter, r *http.Request, u *url.URL) {
|
||||||
|
|
||||||
func micropubUpdate(w http.ResponseWriter, r *http.Request, u *url.URL, mf *microformatItem) {
|
func micropubUpdate(w http.ResponseWriter, r *http.Request, u *url.URL, mf *microformatItem) {
|
||||||
if !strings.Contains(r.Context().Value("scope").(string), "update") {
|
if !strings.Contains(r.Context().Value("scope").(string), "update") {
|
||||||
http.Error(w, "update scope missing", http.StatusForbidden)
|
serveError(w, r, "update scope missing", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p, err := getPost(u.Path)
|
p, err := getPost(u.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if mf.Replace != nil {
|
if mf.Replace != nil {
|
||||||
|
@ -550,12 +550,12 @@ func micropubUpdate(w http.ResponseWriter, r *http.Request, u *url.URL, mf *micr
|
||||||
}
|
}
|
||||||
err = p.computeExtraPostParameters()
|
err = p.computeExtraPostParameters()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = p.replace()
|
err = p.replace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, p.fullURL(), http.StatusNoContent)
|
http.Redirect(w, r, p.fullURL(), http.StatusNoContent)
|
||||||
|
|
|
@ -22,25 +22,25 @@ const micropubMediaSubPath = "/media"
|
||||||
|
|
||||||
func serveMicropubMedia(w http.ResponseWriter, r *http.Request) {
|
func serveMicropubMedia(w http.ResponseWriter, r *http.Request) {
|
||||||
if !strings.Contains(r.Context().Value("scope").(string), "media") {
|
if !strings.Contains(r.Context().Value("scope").(string), "media") {
|
||||||
http.Error(w, "media scope missing", http.StatusForbidden)
|
serveError(w, r, "media scope missing", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if appConfig.Micropub.MediaStorage == nil {
|
if appConfig.Micropub.MediaStorage == nil {
|
||||||
http.Error(w, "Not configured", http.StatusNotImplemented)
|
serveError(w, r, "Not configured", http.StatusNotImplemented)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ct := r.Header.Get(contentType); !strings.Contains(ct, contentTypeMultipartForm) {
|
if ct := r.Header.Get(contentType); !strings.Contains(ct, contentTypeMultipartForm) {
|
||||||
http.Error(w, "wrong content-type", http.StatusBadRequest)
|
serveError(w, r, "wrong content-type", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err := r.ParseMultipartForm(0)
|
err := r.ParseMultipartForm(0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
file, header, err := r.FormFile("file")
|
file, header, err := r.FormFile("file")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer func() { _ = file.Close() }()
|
defer func() { _ = file.Close() }()
|
||||||
|
@ -48,7 +48,7 @@ func serveMicropubMedia(w http.ResponseWriter, r *http.Request) {
|
||||||
defer func() { _ = hashFile.Close() }()
|
defer func() { _ = hashFile.Close() }()
|
||||||
fileName, err := getSHA256(hashFile)
|
fileName, err := getSHA256(hashFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fileExtension := filepath.Ext(header.Filename)
|
fileExtension := filepath.Ext(header.Filename)
|
||||||
|
@ -65,13 +65,13 @@ func serveMicropubMedia(w http.ResponseWriter, r *http.Request) {
|
||||||
fileName += strings.ToLower(fileExtension)
|
fileName += strings.ToLower(fileExtension)
|
||||||
location, err := appConfig.Micropub.MediaStorage.uploadToBunny(fileName, file)
|
location, err := appConfig.Micropub.MediaStorage.uploadToBunny(fileName, file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "failed to upload original file: "+err.Error(), http.StatusInternalServerError)
|
serveError(w, r, "failed to upload original file: "+err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if appConfig.Micropub.MediaStorage.TinifyKey != "" {
|
if appConfig.Micropub.MediaStorage.TinifyKey != "" {
|
||||||
compressedLocation, err := appConfig.Micropub.MediaStorage.tinify(location)
|
compressedLocation, err := appConfig.Micropub.MediaStorage.tinify(location)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "failed to compress file: "+err.Error(), http.StatusInternalServerError)
|
serveError(w, r, "failed to compress file: "+err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
} else if compressedLocation != "" {
|
} else if compressedLocation != "" {
|
||||||
location = compressedLocation
|
location = compressedLocation
|
||||||
|
|
|
@ -22,7 +22,7 @@ func allPostAliases() ([]string, error) {
|
||||||
func servePostAlias(w http.ResponseWriter, r *http.Request) {
|
func servePostAlias(w http.ResponseWriter, r *http.Request) {
|
||||||
row, err := appDbQueryRow("select path from post_parameters where parameter = 'aliases' and value = @alias", sql.Named("alias", r.URL.Path))
|
row, err := appDbQueryRow("select path from post_parameters where parameter = 'aliases' and value = @alias", sql.Named("alias", r.URL.Path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var path string
|
var path string
|
||||||
|
@ -31,7 +31,7 @@ func servePostAlias(w http.ResponseWriter, r *http.Request) {
|
||||||
serve404(w, r)
|
serve404(w, r)
|
||||||
return
|
return
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, path, http.StatusFound)
|
http.Redirect(w, r, path, http.StatusFound)
|
||||||
|
|
6
posts.go
6
posts.go
|
@ -41,7 +41,7 @@ func servePost(w http.ResponseWriter, r *http.Request) {
|
||||||
serve404(w, r)
|
serve404(w, r)
|
||||||
return
|
return
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if as {
|
if as {
|
||||||
|
@ -95,7 +95,7 @@ func serveHome(blog string, path string) func(w http.ResponseWriter, r *http.Req
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
as := strings.HasSuffix(r.URL.Path, ".as")
|
as := strings.HasSuffix(r.URL.Path, ".as")
|
||||||
if as {
|
if as {
|
||||||
appConfig.Blogs[blog].serveActivityStreams(blog, w)
|
appConfig.Blogs[blog].serveActivityStreams(blog, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
serveIndex(&indexConfig{
|
serveIndex(&indexConfig{
|
||||||
|
@ -202,7 +202,7 @@ func serveIndex(ic *indexConfig) func(w http.ResponseWriter, r *http.Request) {
|
||||||
var posts []*post
|
var posts []*post
|
||||||
err := p.Results(&posts)
|
err := p.Results(&posts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Meta
|
// Meta
|
||||||
|
|
|
@ -13,7 +13,7 @@ func serveSearch(blog string, path string) func(w http.ResponseWriter, r *http.R
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if q := r.Form.Get("q"); q != "" {
|
if q := r.Form.Get("q"); q != "" {
|
||||||
|
|
|
@ -13,7 +13,7 @@ const sitemapPath = "/sitemap.xml"
|
||||||
func serveSitemap(w http.ResponseWriter, r *http.Request) {
|
func serveSitemap(w http.ResponseWriter, r *http.Request) {
|
||||||
posts, err := getPosts(&postsRequestConfig{})
|
posts, err := getPosts(&postsRequestConfig{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sm := sitemap.New()
|
sm := sitemap.New()
|
||||||
|
|
|
@ -6,7 +6,7 @@ func serveTaxonomy(blog string, tax *taxonomy) func(w http.ResponseWriter, r *ht
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
allValues, err := allTaxonomyValues(blog, tax.Name)
|
allValues, err := allTaxonomyValues(blog, tax.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
render(w, templateTaxonomy, &renderData{
|
render(w, templateTaxonomy, &renderData{
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
<main>
|
<main>
|
||||||
{{ with .Data.Title }}<h1>{{ . }}</h1>{{ end }}
|
{{ with .Data.Title }}<h1>{{ . }}</h1>{{ end }}
|
||||||
{{ with .Data.Message }}{{ md . }}{{ end }}
|
{{ with .Data.Message }}<p class="monospace">{{ . }}</p>{{ end }}
|
||||||
</main>
|
</main>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
|
|
@ -45,15 +45,15 @@ func initWebmention() error {
|
||||||
func handleWebmention(w http.ResponseWriter, r *http.Request) {
|
func handleWebmention(w http.ResponseWriter, r *http.Request) {
|
||||||
m, err := extractMention(r)
|
m, err := extractMention(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !isAllowedHost(httptest.NewRequest(http.MethodGet, m.Target, nil), r.URL.Host, appConfig.Server.Domain) {
|
if !isAllowedHost(httptest.NewRequest(http.MethodGet, m.Target, nil), r.URL.Host, appConfig.Server.Domain) {
|
||||||
http.Error(w, "target not allowed", http.StatusBadRequest)
|
serveError(w, r, "target not allowed", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = queueMention(m); err != nil {
|
if err = queueMention(m); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusAccepted)
|
w.WriteHeader(http.StatusAccepted)
|
||||||
|
@ -85,14 +85,14 @@ func webmentionAdmin(w http.ResponseWriter, r *http.Request) {
|
||||||
status: webmentionStatusVerified,
|
status: webmentionStatusVerified,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
approved, err := getWebmentions(&webmentionsRequestConfig{
|
approved, err := getWebmentions(&webmentionsRequestConfig{
|
||||||
status: webmentionStatusApproved,
|
status: webmentionStatusApproved,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
render(w, "webmentionadmin", &renderData{
|
render(w, "webmentionadmin", &renderData{
|
||||||
|
@ -106,12 +106,12 @@ func webmentionAdmin(w http.ResponseWriter, r *http.Request) {
|
||||||
func webmentionAdminDelete(w http.ResponseWriter, r *http.Request) {
|
func webmentionAdminDelete(w http.ResponseWriter, r *http.Request) {
|
||||||
id, err := strconv.Atoi(r.FormValue("mentionid"))
|
id, err := strconv.Atoi(r.FormValue("mentionid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = deleteWebmention(id)
|
err = deleteWebmention(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
purgeCache()
|
purgeCache()
|
||||||
|
@ -122,12 +122,12 @@ func webmentionAdminDelete(w http.ResponseWriter, r *http.Request) {
|
||||||
func webmentionAdminApprove(w http.ResponseWriter, r *http.Request) {
|
func webmentionAdminApprove(w http.ResponseWriter, r *http.Request) {
|
||||||
id, err := strconv.Atoi(r.FormValue("mentionid"))
|
id, err := strconv.Atoi(r.FormValue("mentionid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
serveError(w, r, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = approveWebmention(id)
|
err = approveWebmention(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
purgeCache()
|
purgeCache()
|
||||||
|
|
Loading…
Reference in New Issue