summaryrefslogtreecommitdiff
path: root/internal/api/s2s
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2022-06-08 20:38:03 +0200
committerLibravatar GitHub <noreply@github.com>2022-06-08 20:38:03 +0200
commit1ede54ddf6dfd2d4ba039eb7e23b74bcac65b643 (patch)
tree727436fb9bf9da25e30c5ded65c5b5ccaffe0cf0 /internal/api/s2s
parent[bugfix] #621: add weak type handing to mapstructure decode (#625) (diff)
downloadgotosocial-1ede54ddf6dfd2d4ba039eb7e23b74bcac65b643.tar.xz
[feature] More consistent API error handling (#637)
* update templates * start reworking api error handling * update template * return AP status at web endpoint if negotiated * start making api error handling much more consistent * update account endpoints to new error handling * use new api error handling in admin endpoints * go fmt ./... * use api error logic in app * use generic error handling in auth * don't export generic error handler * don't defer clearing session * user nicer error handling on oidc callback handler * tidy up the sign in handler * tidy up the token handler * use nicer error handling in blocksget * auth emojis endpoint * fix up remaining api endpoints * fix whoopsie during login flow * regenerate swagger docs * change http error logging to debug
Diffstat (limited to 'internal/api/s2s')
-rw-r--r--internal/api/s2s/nodeinfo/nodeinfoget.go23
-rw-r--r--internal/api/s2s/nodeinfo/wellknownget.go15
-rw-r--r--internal/api/s2s/user/followers.go39
-rw-r--r--internal/api/s2s/user/following.go39
-rw-r--r--internal/api/s2s/user/inboxpost.go38
-rw-r--r--internal/api/s2s/user/outboxget.go52
-rw-r--r--internal/api/s2s/user/publickeyget.go39
-rw-r--r--internal/api/s2s/user/repliesget.go62
-rw-r--r--internal/api/s2s/user/statusget.go38
-rw-r--r--internal/api/s2s/user/userget.go39
-rw-r--r--internal/api/s2s/webfinger/webfingerget.go8
11 files changed, 177 insertions, 215 deletions
diff --git a/internal/api/s2s/nodeinfo/nodeinfoget.go b/internal/api/s2s/nodeinfo/nodeinfoget.go
index 8b3b1cfba..8f111bd98 100644
--- a/internal/api/s2s/nodeinfo/nodeinfoget.go
+++ b/internal/api/s2s/nodeinfo/nodeinfoget.go
@@ -23,8 +23,8 @@ import (
"net/http"
"github.com/gin-gonic/gin"
- "github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/api"
+ "github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
// NodeInfoGETHandler swagger:operation GET /nodeinfo/2.0 nodeInfoGet
@@ -45,26 +45,21 @@ import (
// schema:
// "$ref": "#/definitions/nodeinfo"
func (m *Module) NodeInfoGETHandler(c *gin.Context) {
- l := logrus.WithFields(logrus.Fields{
- "func": "NodeInfoGETHandler",
- "user-agent": c.Request.UserAgent(),
- })
-
if _, err := api.NegotiateAccept(c, api.JSONAcceptHeaders...); err != nil {
- c.JSON(http.StatusNotAcceptable, gin.H{"error": err.Error()})
+ api.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet)
return
}
- ni, err := m.processor.GetNodeInfo(c.Request.Context(), c.Request)
- if err != nil {
- l.Debugf("error with get node info request: %s", err)
- c.JSON(err.Code(), err.Safe())
+ ni, errWithCode := m.processor.GetNodeInfo(c.Request.Context(), c.Request)
+ if errWithCode != nil {
+ api.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
return
}
- b, jsonErr := json.Marshal(ni)
- if jsonErr != nil {
- c.JSON(http.StatusInternalServerError, gin.H{"error": jsonErr.Error()})
+ b, err := json.Marshal(ni)
+ if err != nil {
+ api.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
+ return
}
c.Data(http.StatusOK, `application/json; profile="http://nodeinfo.diaspora.software/ns/schema/2.0#"`, b)
diff --git a/internal/api/s2s/nodeinfo/wellknownget.go b/internal/api/s2s/nodeinfo/wellknownget.go
index 6fa3c4623..27e18987f 100644
--- a/internal/api/s2s/nodeinfo/wellknownget.go
+++ b/internal/api/s2s/nodeinfo/wellknownget.go
@@ -22,8 +22,8 @@ import (
"net/http"
"github.com/gin-gonic/gin"
- "github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/api"
+ "github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
// NodeInfoWellKnownGETHandler swagger:operation GET /.well-known/nodeinfo nodeInfoWellKnownGet
@@ -45,19 +45,14 @@ import (
// schema:
// "$ref": "#/definitions/wellKnownResponse"
func (m *Module) NodeInfoWellKnownGETHandler(c *gin.Context) {
- l := logrus.WithFields(logrus.Fields{
- "func": "NodeInfoWellKnownGETHandler",
- })
-
if _, err := api.NegotiateAccept(c, api.JSONAcceptHeaders...); err != nil {
- c.JSON(http.StatusNotAcceptable, gin.H{"error": err.Error()})
+ api.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet)
return
}
- niRel, err := m.processor.GetNodeInfoRel(c.Request.Context(), c.Request)
- if err != nil {
- l.Debugf("error with get node info rel request: %s", err)
- c.JSON(err.Code(), err.Safe())
+ niRel, errWithCode := m.processor.GetNodeInfoRel(c.Request.Context(), c.Request)
+ if errWithCode != nil {
+ api.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
return
}
diff --git a/internal/api/s2s/user/followers.go b/internal/api/s2s/user/followers.go
index ce5a03276..77c0e1307 100644
--- a/internal/api/s2s/user/followers.go
+++ b/internal/api/s2s/user/followers.go
@@ -20,48 +20,45 @@ package user
import (
"encoding/json"
- "fmt"
+ "errors"
"net/http"
+ "strings"
"github.com/gin-gonic/gin"
- "github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/api"
+ "github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
// FollowersGETHandler returns a collection of URIs for followers of the target user, formatted so that other AP servers can understand it.
func (m *Module) FollowersGETHandler(c *gin.Context) {
- l := logrus.WithFields(logrus.Fields{
- "func": "FollowersGETHandler",
- "url": c.Request.RequestURI,
- })
-
- requestedUsername := c.Param(UsernameKey)
+ // usernames on our instance are always lowercase
+ requestedUsername := strings.ToLower(c.Param(UsernameKey))
if requestedUsername == "" {
- c.JSON(http.StatusBadRequest, gin.H{"error": "no username specified in request"})
+ err := errors.New("no username specified in request")
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
- format, err := api.NegotiateAccept(c, api.ActivityPubAcceptHeaders...)
+ format, err := api.NegotiateAccept(c, api.HTMLOrActivityPubHeaders...)
if err != nil {
- c.JSON(http.StatusNotAcceptable, gin.H{"error": err.Error()})
+ api.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet)
return
}
- l.Tracef("negotiated format: %s", format)
- ctx := transferContext(c)
+ if format == string(api.TextHTML) {
+ // redirect to the user's profile
+ c.Redirect(http.StatusSeeOther, "/@"+requestedUsername)
+ }
- followers, errWithCode := m.processor.GetFediFollowers(ctx, requestedUsername, c.Request.URL)
+ resp, errWithCode := m.processor.GetFediFollowers(transferContext(c), requestedUsername, c.Request.URL)
if errWithCode != nil {
- l.Info(errWithCode.Error())
- c.JSON(errWithCode.Code(), gin.H{"error": errWithCode.Safe()})
+ api.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
return
}
- b, mErr := json.Marshal(followers)
- if mErr != nil {
- err := fmt.Errorf("could not marshal json: %s", mErr)
- l.Error(err)
- c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
+ b, err := json.Marshal(resp)
+ if err != nil {
+ api.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
return
}
diff --git a/internal/api/s2s/user/following.go b/internal/api/s2s/user/following.go
index ca3d4bb4c..14dc9343f 100644
--- a/internal/api/s2s/user/following.go
+++ b/internal/api/s2s/user/following.go
@@ -20,48 +20,45 @@ package user
import (
"encoding/json"
- "fmt"
+ "errors"
"net/http"
+ "strings"
"github.com/gin-gonic/gin"
- "github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/api"
+ "github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
// FollowingGETHandler returns a collection of URIs for accounts that the target user follows, formatted so that other AP servers can understand it.
func (m *Module) FollowingGETHandler(c *gin.Context) {
- l := logrus.WithFields(logrus.Fields{
- "func": "FollowingGETHandler",
- "url": c.Request.RequestURI,
- })
-
- requestedUsername := c.Param(UsernameKey)
+ // usernames on our instance are always lowercase
+ requestedUsername := strings.ToLower(c.Param(UsernameKey))
if requestedUsername == "" {
- c.JSON(http.StatusBadRequest, gin.H{"error": "no username specified in request"})
+ err := errors.New("no username specified in request")
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
- format, err := api.NegotiateAccept(c, api.ActivityPubAcceptHeaders...)
+ format, err := api.NegotiateAccept(c, api.HTMLOrActivityPubHeaders...)
if err != nil {
- c.JSON(http.StatusNotAcceptable, gin.H{"error": err.Error()})
+ api.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet)
return
}
- l.Tracef("negotiated format: %s", format)
- ctx := transferContext(c)
+ if format == string(api.TextHTML) {
+ // redirect to the user's profile
+ c.Redirect(http.StatusSeeOther, "/@"+requestedUsername)
+ }
- following, errWithCode := m.processor.GetFediFollowing(ctx, requestedUsername, c.Request.URL)
+ resp, errWithCode := m.processor.GetFediFollowing(transferContext(c), requestedUsername, c.Request.URL)
if errWithCode != nil {
- l.Info(errWithCode.Error())
- c.JSON(errWithCode.Code(), gin.H{"error": errWithCode.Safe()})
+ api.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
return
}
- b, mErr := json.Marshal(following)
- if mErr != nil {
- err := fmt.Errorf("could not marshal json: %s", mErr)
- l.Error(err)
- c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
+ b, err := json.Marshal(resp)
+ if err != nil {
+ api.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
return
}
diff --git a/internal/api/s2s/user/inboxpost.go b/internal/api/s2s/user/inboxpost.go
index 6e17850fd..fa6792cd2 100644
--- a/internal/api/s2s/user/inboxpost.go
+++ b/internal/api/s2s/user/inboxpost.go
@@ -19,43 +19,33 @@
package user
import (
- "net/http"
+ "errors"
+ "strings"
"github.com/gin-gonic/gin"
- "github.com/sirupsen/logrus"
+ "github.com/superseriousbusiness/gotosocial/internal/api"
"github.com/superseriousbusiness/gotosocial/internal/gtserror" //nolint:typecheck
)
// InboxPOSTHandler deals with incoming POST requests to an actor's inbox.
// Eg., POST to https://example.org/users/whatever/inbox.
func (m *Module) InboxPOSTHandler(c *gin.Context) {
- l := logrus.WithFields(logrus.Fields{
- "func": "InboxPOSTHandler",
- "url": c.Request.RequestURI,
- })
-
- requestedUsername := c.Param(UsernameKey)
+ // usernames on our instance are always lowercase
+ requestedUsername := strings.ToLower(c.Param(UsernameKey))
if requestedUsername == "" {
- c.JSON(http.StatusBadRequest, gin.H{"error": "no username specified in request"})
+ err := errors.New("no username specified in request")
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
- ctx := transferContext(c)
-
- posted, err := m.processor.InboxPost(ctx, c.Writer, c.Request)
- if err != nil {
+ if posted, err := m.processor.InboxPost(transferContext(c), c.Writer, c.Request); err != nil {
if withCode, ok := err.(gtserror.WithCode); ok {
- l.Debugf("InboxPOSTHandler: %s", withCode.Error())
- c.JSON(withCode.Code(), withCode.Safe())
- return
+ api.ErrorHandler(c, withCode, m.processor.InstanceGet)
+ } else {
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
}
- l.Debugf("InboxPOSTHandler: error processing request: %s", err)
- c.JSON(http.StatusBadRequest, gin.H{"error": "unable to process request"})
- return
- }
-
- if !posted {
- l.Debugf("InboxPOSTHandler: request could not be handled as an AP request; headers were: %+v", c.Request.Header)
- c.JSON(http.StatusBadRequest, gin.H{"error": "unable to process request"})
+ } else if !posted {
+ err := errors.New("unable to process request")
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
}
}
diff --git a/internal/api/s2s/user/outboxget.go b/internal/api/s2s/user/outboxget.go
index b8e6126df..568e48017 100644
--- a/internal/api/s2s/user/outboxget.go
+++ b/internal/api/s2s/user/outboxget.go
@@ -20,13 +20,15 @@ package user
import (
"encoding/json"
+ "errors"
"fmt"
"net/http"
"strconv"
+ "strings"
"github.com/gin-gonic/gin"
- "github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/api"
+ "github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
// OutboxGETHandler swagger:operation GET /users/{username}/outbox s2sOutboxGet
@@ -80,23 +82,31 @@ import (
// '404':
// description: not found
func (m *Module) OutboxGETHandler(c *gin.Context) {
- l := logrus.WithFields(logrus.Fields{
- "func": "OutboxGETHandler",
- "url": c.Request.RequestURI,
- })
-
- requestedUsername := c.Param(UsernameKey)
+ // usernames on our instance are always lowercase
+ requestedUsername := strings.ToLower(c.Param(UsernameKey))
if requestedUsername == "" {
- c.JSON(http.StatusBadRequest, gin.H{"error": "no username specified in request"})
+ err := errors.New("no username specified in request")
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
+ format, err := api.NegotiateAccept(c, api.HTMLOrActivityPubHeaders...)
+ if err != nil {
+ api.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet)
+ return
+ }
+
+ if format == string(api.TextHTML) {
+ // redirect to the user's profile
+ c.Redirect(http.StatusSeeOther, "/@"+requestedUsername)
+ }
+
var page bool
if pageString := c.Query(PageKey); pageString != "" {
i, err := strconv.ParseBool(pageString)
if err != nil {
- l.Debugf("error parsing page string: %s", err)
- c.JSON(http.StatusBadRequest, gin.H{"error": "couldn't parse page query param"})
+ err := fmt.Errorf("error parsing %s: %s", PageKey, err)
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
page = i
@@ -114,27 +124,15 @@ func (m *Module) OutboxGETHandler(c *gin.Context) {
maxID = maxIDString
}
- format, err := api.NegotiateAccept(c, api.ActivityPubAcceptHeaders...)
- if err != nil {
- c.JSON(http.StatusNotAcceptable, gin.H{"error": err.Error()})
- return
- }
- l.Tracef("negotiated format: %s", format)
-
- ctx := transferContext(c)
-
- outbox, errWithCode := m.processor.GetFediOutbox(ctx, requestedUsername, page, maxID, minID, c.Request.URL)
+ resp, errWithCode := m.processor.GetFediOutbox(transferContext(c), requestedUsername, page, maxID, minID, c.Request.URL)
if errWithCode != nil {
- l.Info(errWithCode.Error())
- c.JSON(errWithCode.Code(), gin.H{"error": errWithCode.Safe()})
+ api.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
return
}
- b, mErr := json.Marshal(outbox)
- if mErr != nil {
- err := fmt.Errorf("could not marshal json: %s", mErr)
- l.Error(err)
- c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
+ b, err := json.Marshal(resp)
+ if err != nil {
+ api.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
return
}
diff --git a/internal/api/s2s/user/publickeyget.go b/internal/api/s2s/user/publickeyget.go
index 6e963e191..e929c461d 100644
--- a/internal/api/s2s/user/publickeyget.go
+++ b/internal/api/s2s/user/publickeyget.go
@@ -20,12 +20,13 @@ package user
import (
"encoding/json"
- "fmt"
+ "errors"
"net/http"
+ "strings"
"github.com/gin-gonic/gin"
- "github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/api"
+ "github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
// PublicKeyGETHandler should be served at eg https://example.org/users/:username/main-key.
@@ -34,38 +35,34 @@ import (
// in the form of a vocab.ActivityStreamsPerson. The account will only contain the id,
// public key, username, and type of the account.
func (m *Module) PublicKeyGETHandler(c *gin.Context) {
- l := logrus.WithFields(logrus.Fields{
- "func": "PublicKeyGETHandler",
- "url": c.Request.RequestURI,
- })
-
- requestedUsername := c.Param(UsernameKey)
+ // usernames on our instance are always lowercase
+ requestedUsername := strings.ToLower(c.Param(UsernameKey))
if requestedUsername == "" {
- c.JSON(http.StatusBadRequest, gin.H{"error": "no username specified in request"})
+ err := errors.New("no username specified in request")
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
- format, err := api.NegotiateAccept(c, api.ActivityPubAcceptHeaders...)
+ format, err := api.NegotiateAccept(c, api.HTMLOrActivityPubHeaders...)
if err != nil {
- c.JSON(http.StatusNotAcceptable, gin.H{"error": err.Error()})
+ api.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet)
return
}
- l.Tracef("negotiated format: %s", format)
- ctx := transferContext(c)
+ if format == string(api.TextHTML) {
+ // redirect to the user's profile
+ c.Redirect(http.StatusSeeOther, "/@"+requestedUsername)
+ }
- user, errWithCode := m.processor.GetFediUser(ctx, requestedUsername, c.Request.URL)
+ resp, errWithCode := m.processor.GetFediUser(transferContext(c), requestedUsername, c.Request.URL)
if errWithCode != nil {
- l.Info(errWithCode.Error())
- c.JSON(errWithCode.Code(), gin.H{"error": errWithCode.Safe()})
+ api.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
return
}
- b, mErr := json.Marshal(user)
- if mErr != nil {
- err := fmt.Errorf("could not marshal json: %s", mErr)
- l.Error(err)
- c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
+ b, err := json.Marshal(resp)
+ if err != nil {
+ api.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
return
}
diff --git a/internal/api/s2s/user/repliesget.go b/internal/api/s2s/user/repliesget.go
index 388f69885..6ef5a5f43 100644
--- a/internal/api/s2s/user/repliesget.go
+++ b/internal/api/s2s/user/repliesget.go
@@ -20,13 +20,15 @@ package user
import (
"encoding/json"
+ "errors"
"fmt"
"net/http"
"strconv"
+ "strings"
"github.com/gin-gonic/gin"
- "github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/api"
+ "github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
// StatusRepliesGETHandler swagger:operation GET /users/{username}/statuses/{status}/replies s2sRepliesGet
@@ -86,29 +88,39 @@ import (
// '404':
// description: not found
func (m *Module) StatusRepliesGETHandler(c *gin.Context) {
- l := logrus.WithFields(logrus.Fields{
- "func": "StatusRepliesGETHandler",
- "url": c.Request.RequestURI,
- })
-
- requestedUsername := c.Param(UsernameKey)
+ // usernames on our instance are always lowercase
+ requestedUsername := strings.ToLower(c.Param(UsernameKey))
if requestedUsername == "" {
- c.JSON(http.StatusBadRequest, gin.H{"error": "no username specified in request"})
+ err := errors.New("no username specified in request")
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
- requestedStatusID := c.Param(StatusIDKey)
+ // status IDs on our instance are always uppercase
+ requestedStatusID := strings.ToUpper(c.Param(StatusIDKey))
if requestedStatusID == "" {
- c.JSON(http.StatusBadRequest, gin.H{"error": "no status id specified in request"})
+ err := errors.New("no status id specified in request")
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
+ format, err := api.NegotiateAccept(c, api.HTMLOrActivityPubHeaders...)
+ if err != nil {
+ api.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet)
+ return
+ }
+
+ if format == string(api.TextHTML) {
+ // redirect to the status
+ c.Redirect(http.StatusSeeOther, "/@"+requestedUsername+"/statuses/"+requestedStatusID)
+ }
+
var page bool
if pageString := c.Query(PageKey); pageString != "" {
i, err := strconv.ParseBool(pageString)
if err != nil {
- l.Debugf("error parsing page string: %s", err)
- c.JSON(http.StatusBadRequest, gin.H{"error": "couldn't parse page query param"})
+ err := fmt.Errorf("error parsing %s: %s", PageKey, err)
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
page = i
@@ -119,8 +131,8 @@ func (m *Module) StatusRepliesGETHandler(c *gin.Context) {
if onlyOtherAccountsString != "" {
i, err := strconv.ParseBool(onlyOtherAccountsString)
if err != nil {
- l.Debugf("error parsing only_other_accounts string: %s", err)
- c.JSON(http.StatusBadRequest, gin.H{"error": "couldn't parse only_other_accounts query param"})
+ err := fmt.Errorf("error parsing %s: %s", OnlyOtherAccountsKey, err)
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
onlyOtherAccounts = i
@@ -132,27 +144,15 @@ func (m *Module) StatusRepliesGETHandler(c *gin.Context) {
minID = minIDString
}
- format, err := api.NegotiateAccept(c, api.ActivityPubAcceptHeaders...)
- if err != nil {
- c.JSON(http.StatusNotAcceptable, gin.H{"error": err.Error()})
- return
- }
- l.Tracef("negotiated format: %s", format)
-
- ctx := transferContext(c)
-
- replies, errWithCode := m.processor.GetFediStatusReplies(ctx, requestedUsername, requestedStatusID, page, onlyOtherAccounts, minID, c.Request.URL)
+ resp, errWithCode := m.processor.GetFediStatusReplies(transferContext(c), requestedUsername, requestedStatusID, page, onlyOtherAccounts, minID, c.Request.URL)
if errWithCode != nil {
- l.Info(errWithCode.Error())
- c.JSON(errWithCode.Code(), gin.H{"error": errWithCode.Safe()})
+ api.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
return
}
- b, mErr := json.Marshal(replies)
- if mErr != nil {
- err := fmt.Errorf("could not marshal json: %s", mErr)
- l.Error(err)
- c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
+ b, err := json.Marshal(resp)
+ if err != nil {
+ api.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
return
}
diff --git a/internal/api/s2s/user/statusget.go b/internal/api/s2s/user/statusget.go
index 3dee0c88a..b6690c4de 100644
--- a/internal/api/s2s/user/statusget.go
+++ b/internal/api/s2s/user/statusget.go
@@ -20,57 +20,53 @@ package user
import (
"encoding/json"
- "fmt"
+ "errors"
"net/http"
"strings"
"github.com/gin-gonic/gin"
- "github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/api"
+ "github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
// StatusGETHandler serves the target status as an activitystreams NOTE so that other AP servers can parse it.
func (m *Module) StatusGETHandler(c *gin.Context) {
- l := logrus.WithFields(logrus.Fields{
- "func": "StatusGETHandler",
- "url": c.Request.RequestURI,
- })
-
// usernames on our instance are always lowercase
requestedUsername := strings.ToLower(c.Param(UsernameKey))
if requestedUsername == "" {
- c.JSON(http.StatusBadRequest, gin.H{"error": "no username specified in request"})
+ err := errors.New("no username specified in request")
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
// status IDs on our instance are always uppercase
requestedStatusID := strings.ToUpper(c.Param(StatusIDKey))
if requestedStatusID == "" {
- c.JSON(http.StatusBadRequest, gin.H{"error": "no status id specified in request"})
+ err := errors.New("no status id specified in request")
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
- format, err := api.NegotiateAccept(c, api.ActivityPubAcceptHeaders...)
+ format, err := api.NegotiateAccept(c, api.HTMLOrActivityPubHeaders...)
if err != nil {
- c.JSON(http.StatusNotAcceptable, gin.H{"error": err.Error()})
+ api.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet)
return
}
- l.Tracef("negotiated format: %s", format)
- ctx := transferContext(c)
+ if format == string(api.TextHTML) {
+ // redirect to the status
+ c.Redirect(http.StatusSeeOther, "/@"+requestedUsername+"/statuses/"+requestedStatusID)
+ }
- status, errWithCode := m.processor.GetFediStatus(ctx, requestedUsername, requestedStatusID, c.Request.URL)
+ resp, errWithCode := m.processor.GetFediStatus(transferContext(c), requestedUsername, requestedStatusID, c.Request.URL)
if errWithCode != nil {
- l.Info(errWithCode.Error())
- c.JSON(errWithCode.Code(), gin.H{"error": errWithCode.Safe()})
+ api.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
return
}
- b, mErr := json.Marshal(status)
- if mErr != nil {
- err := fmt.Errorf("could not marshal json: %s", mErr)
- l.Error(err)
- c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
+ b, err := json.Marshal(resp)
+ if err != nil {
+ api.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
return
}
diff --git a/internal/api/s2s/user/userget.go b/internal/api/s2s/user/userget.go
index c034e6bfc..b5e8a84c9 100644
--- a/internal/api/s2s/user/userget.go
+++ b/internal/api/s2s/user/userget.go
@@ -20,12 +20,13 @@ package user
import (
"encoding/json"
- "fmt"
+ "errors"
"net/http"
+ "strings"
"github.com/gin-gonic/gin"
- "github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/api"
+ "github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
// UsersGETHandler should be served at https://example.org/users/:username.
@@ -38,38 +39,34 @@ import (
// And of course, the request should be refused if the account or server making the
// request is blocked.
func (m *Module) UsersGETHandler(c *gin.Context) {
- l := logrus.WithFields(logrus.Fields{
- "func": "UsersGETHandler",
- "url": c.Request.RequestURI,
- })
-
- requestedUsername := c.Param(UsernameKey)
+ // usernames on our instance are always lowercase
+ requestedUsername := strings.ToLower(c.Param(UsernameKey))
if requestedUsername == "" {
- c.JSON(http.StatusBadRequest, gin.H{"error": "no username specified in request"})
+ err := errors.New("no username specified in request")
+ api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
return
}
- format, err := api.NegotiateAccept(c, api.ActivityPubAcceptHeaders...)
+ format, err := api.NegotiateAccept(c, api.HTMLOrActivityPubHeaders...)
if err != nil {
- c.JSON(http.StatusNotAcceptable, gin.H{"error": err.Error()})
+ api.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet)
return
}
- l.Tracef("negotiated format: %s", format)
- ctx := transferContext(c)
+ if format == string(api.TextHTML) {
+ // redirect to the user's profile
+ c.Redirect(http.StatusSeeOther, "/@"+requestedUsername)
+ }
- user, errWithCode := m.processor.GetFediUser(ctx, requestedUsername, c.Request.URL) // GetFediUser handles auth as well
+ resp, errWithCode := m.processor.GetFediUser(transferContext(c), requestedUsername, c.Request.URL)
if errWithCode != nil {
- l.Info(errWithCode.Error())
- c.JSON(errWithCode.Code(), gin.H{"error": errWithCode.Safe()})
+ api.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
return
}
- b, mErr := json.Marshal(user)
- if mErr != nil {
- err := fmt.Errorf("could not marshal json: %s", mErr)
- l.Error(err)
- c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
+ b, err := json.Marshal(resp)
+ if err != nil {
+ api.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
return
}
diff --git a/internal/api/s2s/webfinger/webfingerget.go b/internal/api/s2s/webfinger/webfingerget.go
index a271c031b..7e7ca006b 100644
--- a/internal/api/s2s/webfinger/webfingerget.go
+++ b/internal/api/s2s/webfinger/webfingerget.go
@@ -27,6 +27,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/ap"
+ "github.com/superseriousbusiness/gotosocial/internal/api"
"github.com/superseriousbusiness/gotosocial/internal/config"
)
@@ -105,10 +106,9 @@ func (m *Module) WebfingerGETRequest(c *gin.Context) {
ctx = context.WithValue(ctx, ap.ContextRequestingPublicKeyVerifier, verifier)
}
- resp, err := m.processor.GetWebfingerAccount(ctx, username)
- if err != nil {
- l.Debugf("aborting request with an error: %s", err.Error())
- c.JSON(err.Code(), gin.H{"error": err.Safe()})
+ resp, errWithCode := m.processor.GetWebfingerAccount(ctx, username)
+ if errWithCode != nil {
+ api.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
return
}