[feature] Enforce OAuth token scopes (#3835)

* move tokenauth to apiutil

* enforce scopes

* docs

* update test models, remove deprecated "follow"

* file header

* tests

* tweak scope matcher

* simplify...

* fix tests

* log user out of settings panel in case of oauth error
This commit is contained in:
tobi
2025-02-26 13:04:55 +01:00
committed by GitHub
parent f734a94c1c
commit eb720241da
213 changed files with 1762 additions and 1082 deletions

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/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/internal/paging"
)
@@ -117,9 +116,12 @@ import (
// '500':
// description: internal server error
func (m *Module) ListAccountsGETHandler(c *gin.Context) {
authed, err := oauth.Authed(c, true, true, true, true)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
authed, errWithCode := apiutil.TokenAuth(c,
true, true, true, true,
apiutil.ScopeReadLists,
)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}

View File

@@ -25,7 +25,6 @@ import (
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
)
// ListAccountsPOSTHandler swagger:operation POST /api/v1/lists/{id}/accounts addListAccounts
@@ -82,9 +81,12 @@ import (
// '500':
// description: internal server error
func (m *Module) ListAccountsPOSTHandler(c *gin.Context) {
authed, err := oauth.Authed(c, true, true, true, true)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
authed, errWithCode := apiutil.TokenAuth(c,
true, true, true, true,
apiutil.ScopeWriteLists,
)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}

View File

@@ -25,7 +25,6 @@ import (
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
)
// ListAccountsDELETEHandler swagger:operation DELETE /api/v1/lists/{id}/accounts removeListAccounts
@@ -82,9 +81,12 @@ import (
// '500':
// description: internal server error
func (m *Module) ListAccountsDELETEHandler(c *gin.Context) {
authed, err := oauth.Authed(c, true, true, true, true)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
authed, errWithCode := apiutil.TokenAuth(c,
true, true, true, true,
apiutil.ScopeWriteLists,
)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}
@@ -108,7 +110,7 @@ func (m *Module) ListAccountsDELETEHandler(c *gin.Context) {
// parsing in order to be compatible with Mastodon's client API conventions.
oldMethod := c.Request.Method
c.Request.Method = "POST"
err = c.ShouldBind(form)
err := c.ShouldBind(form)
c.Request.Method = oldMethod
if err != nil {

View File

@@ -26,7 +26,6 @@ import (
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/internal/validate"
)
@@ -97,9 +96,12 @@ import (
// '500':
// description: internal server error
func (m *Module) ListCreatePOSTHandler(c *gin.Context) {
authed, err := oauth.Authed(c, true, true, true, true)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
authed, errWithCode := apiutil.TokenAuth(c,
true, true, true, true,
apiutil.ScopeWriteLists,
)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, 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/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
)
// ListDELETEHandler swagger:operation DELETE /api/v1/lists/{id} listDelete
@@ -64,9 +63,12 @@ import (
// '500':
// description: internal server error
func (m *Module) ListDELETEHandler(c *gin.Context) {
authed, err := oauth.Authed(c, true, true, true, true)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
authed, errWithCode := apiutil.TokenAuth(c,
true, true, true, true,
apiutil.ScopeWriteLists,
)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, 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/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
)
// ListGETHandler swagger:operation GET /api/v1/lists/{id} list
@@ -67,9 +66,12 @@ import (
// '500':
// description: internal server error
func (m *Module) ListGETHandler(c *gin.Context) {
authed, err := oauth.Authed(c, true, true, true, true)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
authed, errWithCode := apiutil.TokenAuth(c,
true, true, true, true,
apiutil.ScopeReadLists,
)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}

View File

@@ -23,7 +23,6 @@ import (
"github.com/gin-gonic/gin"
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
)
// ListsGETHandler swagger:operation GET /api/v1/lists lists
@@ -60,9 +59,12 @@ import (
// '500':
// description: internal server error
func (m *Module) ListsGETHandler(c *gin.Context) {
authed, err := oauth.Authed(c, true, true, true, true)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
authed, errWithCode := apiutil.TokenAuth(c,
true, true, true, true,
apiutil.ScopeReadLists,
)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}

View File

@@ -27,7 +27,6 @@ import (
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/internal/validate"
)
@@ -103,9 +102,12 @@ import (
// '500':
// description: internal server error
func (m *Module) ListUpdatePUTHandler(c *gin.Context) {
authed, err := oauth.Authed(c, true, true, true, true)
if err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
authed, errWithCode := apiutil.TokenAuth(c,
true, true, true, true,
apiutil.ScopeWriteLists,
)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}
@@ -152,7 +154,7 @@ func (m *Module) ListUpdatePUTHandler(c *gin.Context) {
}
if form.Title == nil && repliesPolicy == nil && form.Exclusive == nil {
err = errors.New("neither title nor replies_policy nor exclusive was set; nothing to update")
err := errors.New("neither title nor replies_policy nor exclusive was set; nothing to update")
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
return
}