[feature] Implement /api/v2/instance endpoint (#1409)

* interim: start adding /api/v2/instance

* finish up
This commit is contained in:
tobi 2023-02-02 14:08:13 +01:00 committed by GitHub
commit 382512a5a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
109 changed files with 1660 additions and 944 deletions

View file

@ -36,10 +36,9 @@ func (m *Module) baseHandler(c *gin.Context) {
return
}
host := config.GetHost()
instance, err := m.processor.InstanceGet(c.Request.Context(), host)
instance, err := m.processor.InstanceGetV1(c.Request.Context())
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGetV1)
return
}

View file

@ -24,7 +24,6 @@ import (
"github.com/gin-gonic/gin"
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
@ -34,20 +33,19 @@ func (m *Module) confirmEmailGETHandler(c *gin.Context) {
// if there's no token in the query, just serve the 404 web handler
token := c.Query(tokenParam)
if token == "" {
apiutil.ErrorHandler(c, gtserror.NewErrorNotFound(errors.New(http.StatusText(http.StatusNotFound))), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorNotFound(errors.New(http.StatusText(http.StatusNotFound))), m.processor.InstanceGetV1)
return
}
user, errWithCode := m.processor.UserConfirmEmail(ctx, token)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}
host := config.GetHost()
instance, err := m.processor.InstanceGet(ctx, host)
instance, err := m.processor.InstanceGetV1(ctx)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGetV1)
return
}

View file

@ -34,12 +34,12 @@ const textCSSUTF8 = string(apiutil.TextCSS + "; charset=utf-8")
func (m *Module) customCSSGETHandler(c *gin.Context) {
if !config.GetAccountsAllowCustomCSS() {
err := errors.New("accounts-allow-custom-css is not enabled on this instance")
apiutil.ErrorHandler(c, gtserror.NewErrorNotFound(err), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorNotFound(err), m.processor.InstanceGetV1)
return
}
if _, err := apiutil.NegotiateAccept(c, apiutil.TextCSS); err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGetV1)
return
}
@ -47,13 +47,13 @@ func (m *Module) customCSSGETHandler(c *gin.Context) {
username := strings.ToLower(c.Param(usernameKey))
if username == "" {
err := errors.New("no account username specified")
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
return
}
customCSS, errWithCode := m.processor.AccountGetCustomCSSForUsername(c.Request.Context(), username)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}

View file

@ -36,26 +36,25 @@ const (
func (m *Module) domainBlockListGETHandler(c *gin.Context) {
authed, err := oauth.Authed(c, false, false, false, false)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
return
}
if !config.GetInstanceExposeSuspendedWeb() && (authed.Account == nil || authed.User == nil) {
err := fmt.Errorf("this instance does not expose the list of suspended domains publicly")
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
return
}
host := config.GetHost()
instance, err := m.processor.InstanceGet(c.Request.Context(), host)
instance, err := m.processor.InstanceGetV1(c.Request.Context())
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGetV1)
return
}
domainBlocks, errWithCode := m.processor.InstancePeersGet(c.Request.Context(), true, false, false)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}

View file

@ -57,7 +57,7 @@ type ogMeta struct {
// the base root of an instance. It also serves as a
// foundation for building account / status ogMeta on
// top of.
func ogBase(instance *apimodel.Instance) *ogMeta {
func ogBase(instance *apimodel.InstanceV1) *ogMeta {
var locale string
if len(instance.Languages) > 0 {
locale = instance.Languages[0]

View file

@ -45,25 +45,24 @@ func (m *Module) profileGETHandler(c *gin.Context) {
authed, err := oauth.Authed(c, false, false, false, false)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
return
}
username := strings.ToLower(c.Param(usernameKey))
if username == "" {
err := errors.New("no account username specified")
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
return
}
host := config.GetHost()
instance, err := m.processor.InstanceGet(ctx, host)
instance, err := m.processor.InstanceGetV1(ctx)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGetV1)
return
}
instanceGet := func(ctx context.Context, domain string) (*apimodel.Instance, gtserror.WithCode) {
instanceGet := func(ctx context.Context) (*apimodel.InstanceV1, gtserror.WithCode) {
return instance, nil
}
@ -145,14 +144,14 @@ func (m *Module) returnAPProfile(ctx context.Context, c *gin.Context, username s
user, errWithCode := m.processor.GetFediUser(ctx, username, c.Request.URL)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGet) //nolint:contextcheck
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) //nolint:contextcheck
return
}
b, mErr := json.Marshal(user)
if mErr != nil {
err := fmt.Errorf("could not marshal json: %s", mErr)
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet) //nolint:contextcheck
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGetV1) //nolint:contextcheck
return
}

View file

@ -82,7 +82,7 @@ func (m *Module) rssFeedGETHandler(c *gin.Context) {
ctx := c.Request.Context()
if _, err := apiutil.NegotiateAccept(c, apiutil.AppRSSXML); err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGetV1)
return
}
@ -90,7 +90,7 @@ func (m *Module) rssFeedGETHandler(c *gin.Context) {
username := strings.ToLower(c.Param(usernameKey))
if username == "" {
err := errors.New("no account username specified")
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
return
}
@ -99,7 +99,7 @@ func (m *Module) rssFeedGETHandler(c *gin.Context) {
getRssFeed, accountLastPostedPublic, errWithCode := m.processor.AccountGetRSSFeedForUsername(ctx, username)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}
@ -111,13 +111,13 @@ func (m *Module) rssFeedGETHandler(c *gin.Context) {
// we either have no cache entry for this, or we have an expired cache entry; generate a new one
rssFeed, errWithCode = getRssFeed()
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}
eTag, err := generateEtag(bytes.NewBufferString(rssFeed))
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGetV1)
return
}
@ -145,7 +145,7 @@ func (m *Module) rssFeedGETHandler(c *gin.Context) {
// we had a cache entry already so we didn't call to get the rss feed yet
rssFeed, errWithCode = getRssFeed()
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}
}

View file

@ -23,15 +23,13 @@ import (
"github.com/gin-gonic/gin"
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
func (m *Module) SettingsPanelHandler(c *gin.Context) {
host := config.GetHost()
instance, err := m.processor.InstanceGet(c.Request.Context(), host)
instance, err := m.processor.InstanceGetV1(c.Request.Context())
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGetV1)
return
}

View file

@ -40,7 +40,7 @@ func (m *Module) threadGETHandler(c *gin.Context) {
authed, err := oauth.Authed(c, false, false, false, false)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
return
}
@ -48,7 +48,7 @@ func (m *Module) threadGETHandler(c *gin.Context) {
username := strings.ToLower(c.Param(usernameKey))
if username == "" {
err := errors.New("no account username specified")
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
return
}
@ -56,18 +56,17 @@ func (m *Module) threadGETHandler(c *gin.Context) {
statusID := strings.ToUpper(c.Param(statusIDKey))
if statusID == "" {
err := errors.New("no status id specified")
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
return
}
host := config.GetHost()
instance, err := m.processor.InstanceGet(ctx, host)
instance, err := m.processor.InstanceGetV1(ctx)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet)
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGetV1)
return
}
instanceGet := func(ctx context.Context, domain string) (*apimodel.Instance, gtserror.WithCode) {
instanceGet := func(ctx context.Context) (*apimodel.InstanceV1, gtserror.WithCode) {
return instance, nil
}
@ -135,14 +134,14 @@ func (m *Module) returnAPStatus(ctx context.Context, c *gin.Context, username st
status, errWithCode := m.processor.GetFediStatus(ctx, username, statusID, c.Request.URL)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGet) //nolint:contextcheck
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) //nolint:contextcheck
return
}
b, mErr := json.Marshal(status)
if mErr != nil {
err := fmt.Errorf("could not marshal json: %s", mErr)
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet) //nolint:contextcheck
apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGetV1) //nolint:contextcheck
return
}