[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
commit eb720241da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
213 changed files with 1762 additions and 1082 deletions

View file

@ -26,7 +26,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"
"github.com/superseriousbusiness/gotosocial/internal/regexes"
)
@ -66,9 +65,12 @@ import (
// '500':
// description: internal server error
func (m *Module) ReportPOSTHandler(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.ScopeWriteReports,
)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}
@ -89,19 +91,19 @@ func (m *Module) ReportPOSTHandler(c *gin.Context) {
}
if form.AccountID == "" {
err = errors.New("account_id must be set")
err := errors.New("account_id must be set")
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
return
}
if !regexes.ULID.MatchString(form.AccountID) {
err = errors.New("account_id was not valid")
err := errors.New("account_id was not valid")
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
return
}
if length := len([]rune(form.Comment)); length > 1000 {
err = fmt.Errorf("comment length must be no more than 1000 chars, provided comment was %d chars", length)
err := fmt.Errorf("comment length must be no more than 1000 chars, provided comment was %d chars", length)
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), 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"
)
// ReportGETHandler swagger:operation GET /api/v1/reports/{id} reportGet
@ -47,7 +46,7 @@ import (
//
// security:
// - OAuth2 Bearer:
// - read:reports
// - read:accounts
//
// responses:
// '200':
@ -65,9 +64,12 @@ import (
// '500':
// description: internal server error
func (m *Module) ReportGETHandler(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.ScopeReadAccounts,
)
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"
"github.com/superseriousbusiness/gotosocial/internal/paging"
)
@ -94,7 +93,7 @@ import (
//
// security:
// - OAuth2 Bearer:
// - read:reports
// - read:accounts
//
// responses:
// '200':
@ -119,9 +118,12 @@ import (
// '500':
// description: internal server error
func (m *Module) ReportsGETHandler(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.ScopeReadAccounts,
)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}