diff options
| author | 2024-06-18 18:18:00 +0200 | |
|---|---|---|
| committer | 2024-06-18 18:18:00 +0200 | |
| commit | d2b3d37724a999d4cc78c46157593267e29d184e (patch) | |
| tree | ac72be127d8adb80bbd756ad970ae14df7b5618f /internal/api/client/admin | |
| parent | [feature] Implement types[] param for notifications (#3009) (diff) | |
| download | gotosocial-d2b3d37724a999d4cc78c46157593267e29d184e.tar.xz | |
[feature/frontend] Reports frontend v2 (#3022)
* use apiutil + paging in admin processor+handlers
* we're making it happen
* fix little whoopsie
* styling for report list
* don't youuuu forget about meee don't don't don't don't
* last bits
* sanitize content before showing in report statuses
* update report docs
Diffstat (limited to 'internal/api/client/admin')
| -rw-r--r-- | internal/api/client/admin/accountaction.go | 7 | ||||
| -rw-r--r-- | internal/api/client/admin/admin.go | 25 | ||||
| -rw-r--r-- | internal/api/client/admin/emojidelete.go | 8 | ||||
| -rw-r--r-- | internal/api/client/admin/emojidelete_test.go | 7 | ||||
| -rw-r--r-- | internal/api/client/admin/emojiget.go | 8 | ||||
| -rw-r--r-- | internal/api/client/admin/emojiget_test.go | 7 | ||||
| -rw-r--r-- | internal/api/client/admin/emojisget.go | 20 | ||||
| -rw-r--r-- | internal/api/client/admin/emojiupdate.go | 7 | ||||
| -rw-r--r-- | internal/api/client/admin/emojiupdate_test.go | 23 | ||||
| -rw-r--r-- | internal/api/client/admin/reportget.go | 8 | ||||
| -rw-r--r-- | internal/api/client/admin/reportresolve.go | 8 | ||||
| -rw-r--r-- | internal/api/client/admin/reportresolve_test.go | 3 | ||||
| -rw-r--r-- | internal/api/client/admin/reportsget.go | 58 | ||||
| -rw-r--r-- | internal/api/client/admin/reportsget_test.go | 21 | ||||
| -rw-r--r-- | internal/api/client/admin/ruledelete.go | 8 | ||||
| -rw-r--r-- | internal/api/client/admin/ruleget.go | 8 | ||||
| -rw-r--r-- | internal/api/client/admin/ruleupdate.go | 8 | 
17 files changed, 101 insertions, 133 deletions
| diff --git a/internal/api/client/admin/accountaction.go b/internal/api/client/admin/accountaction.go index 7d74e8530..64e6c39ca 100644 --- a/internal/api/client/admin/accountaction.go +++ b/internal/api/client/admin/accountaction.go @@ -116,10 +116,9 @@ func (m *Module) AccountActionPOSTHandler(c *gin.Context) {  		return  	} -	targetAcctID := c.Param(IDKey) -	if targetAcctID == "" { -		err := errors.New("no account id specified") -		apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) +	targetAcctID, errWithCode := apiutil.ParseID(c.Param(apiutil.IDKey)) +	if errWithCode != nil { +		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)  		return  	}  	form.TargetID = targetAcctID diff --git a/internal/api/client/admin/admin.go b/internal/api/client/admin/admin.go index ef54f0b50..2c55de2f0 100644 --- a/internal/api/client/admin/admin.go +++ b/internal/api/client/admin/admin.go @@ -22,6 +22,7 @@ import (  	"codeberg.org/gruf/go-debug"  	"github.com/gin-gonic/gin" +	apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"  	"github.com/superseriousbusiness/gotosocial/internal/processing"  	"github.com/superseriousbusiness/gotosocial/internal/state"  ) @@ -29,48 +30,40 @@ import (  const (  	BasePath                = "/v1/admin"  	EmojiPath               = BasePath + "/custom_emojis" -	EmojiPathWithID         = EmojiPath + "/:" + IDKey +	EmojiPathWithID         = EmojiPath + "/:" + apiutil.IDKey  	EmojiCategoriesPath     = EmojiPath + "/categories"  	DomainBlocksPath        = BasePath + "/domain_blocks" -	DomainBlocksPathWithID  = DomainBlocksPath + "/:" + IDKey +	DomainBlocksPathWithID  = DomainBlocksPath + "/:" + apiutil.IDKey  	DomainAllowsPath        = BasePath + "/domain_allows" -	DomainAllowsPathWithID  = DomainAllowsPath + "/:" + IDKey +	DomainAllowsPathWithID  = DomainAllowsPath + "/:" + apiutil.IDKey  	DomainKeysExpirePath    = BasePath + "/domain_keys_expire"  	HeaderAllowsPath        = BasePath + "/header_allows" -	HeaderAllowsPathWithID  = HeaderAllowsPath + "/:" + IDKey +	HeaderAllowsPathWithID  = HeaderAllowsPath + "/:" + apiutil.IDKey  	HeaderBlocksPath        = BasePath + "/header_blocks" -	HeaderBlocksPathWithID  = HeaderBlocksPath + "/:" + IDKey +	HeaderBlocksPathWithID  = HeaderBlocksPath + "/:" + apiutil.IDKey  	AccountsV1Path          = BasePath + "/accounts"  	AccountsV2Path          = "/v2/admin/accounts" -	AccountsPathWithID      = AccountsV1Path + "/:" + IDKey +	AccountsPathWithID      = AccountsV1Path + "/:" + apiutil.IDKey  	AccountsActionPath      = AccountsPathWithID + "/action"  	AccountsApprovePath     = AccountsPathWithID + "/approve"  	AccountsRejectPath      = AccountsPathWithID + "/reject"  	MediaCleanupPath        = BasePath + "/media_cleanup"  	MediaRefetchPath        = BasePath + "/media_refetch"  	ReportsPath             = BasePath + "/reports" -	ReportsPathWithID       = ReportsPath + "/:" + IDKey +	ReportsPathWithID       = ReportsPath + "/:" + apiutil.IDKey  	ReportsResolvePath      = ReportsPathWithID + "/resolve"  	EmailPath               = BasePath + "/email"  	EmailTestPath           = EmailPath + "/test"  	InstanceRulesPath       = BasePath + "/instance/rules" -	InstanceRulesPathWithID = InstanceRulesPath + "/:" + IDKey +	InstanceRulesPathWithID = InstanceRulesPath + "/:" + apiutil.IDKey  	DebugPath               = BasePath + "/debug"  	DebugAPUrlPath          = DebugPath + "/apurl"  	DebugClearCachesPath    = DebugPath + "/caches/clear" -	IDKey                 = "id"  	FilterQueryKey        = "filter"  	MaxShortcodeDomainKey = "max_shortcode_domain"  	MinShortcodeDomainKey = "min_shortcode_domain" -	LimitKey              = "limit"  	DomainQueryKey        = "domain" -	ResolvedKey           = "resolved" -	AccountIDKey          = "account_id" -	TargetAccountIDKey    = "target_account_id" -	MaxIDKey              = "max_id" -	SinceIDKey            = "since_id" -	MinIDKey              = "min_id"  )  type Module struct { diff --git a/internal/api/client/admin/emojidelete.go b/internal/api/client/admin/emojidelete.go index 47248a1b9..9f9f9d286 100644 --- a/internal/api/client/admin/emojidelete.go +++ b/internal/api/client/admin/emojidelete.go @@ -18,7 +18,6 @@  package admin  import ( -	"errors"  	"fmt"  	"net/http" @@ -97,10 +96,9 @@ func (m *Module) EmojiDELETEHandler(c *gin.Context) {  		return  	} -	emojiID := c.Param(IDKey) -	if emojiID == "" { -		err := errors.New("no emoji id specified") -		apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) +	emojiID, errWithCode := apiutil.ParseID(c.Param(apiutil.IDKey)) +	if errWithCode != nil { +		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)  		return  	} diff --git a/internal/api/client/admin/emojidelete_test.go b/internal/api/client/admin/emojidelete_test.go index e27592baf..10cf3fe8d 100644 --- a/internal/api/client/admin/emojidelete_test.go +++ b/internal/api/client/admin/emojidelete_test.go @@ -28,6 +28,7 @@ import (  	"github.com/stretchr/testify/suite"  	"github.com/superseriousbusiness/gotosocial/internal/api/client/admin" +	apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"  	"github.com/superseriousbusiness/gotosocial/internal/db"  ) @@ -41,7 +42,7 @@ func (suite *EmojiDeleteTestSuite) TestEmojiDelete1() {  	path := admin.EmojiPathWithID  	ctx := suite.newContext(recorder, http.MethodDelete, nil, path, "application/json") -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	suite.adminModule.EmojiDELETEHandler(ctx)  	suite.Equal(http.StatusOK, recorder.Code) @@ -78,7 +79,7 @@ func (suite *EmojiDeleteTestSuite) TestEmojiDelete2() {  	path := admin.EmojiPathWithID  	ctx := suite.newContext(recorder, http.MethodDelete, nil, path, "application/json") -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	suite.adminModule.EmojiDELETEHandler(ctx)  	suite.Equal(http.StatusBadRequest, recorder.Code) @@ -100,7 +101,7 @@ func (suite *EmojiDeleteTestSuite) TestEmojiDeleteNotFound() {  	path := admin.EmojiPathWithID  	ctx := suite.newContext(recorder, http.MethodDelete, nil, path, "application/json") -	ctx.AddParam(admin.IDKey, "01GF8VRXX1R00X7XH8973Z29R1") +	ctx.AddParam(apiutil.IDKey, "01GF8VRXX1R00X7XH8973Z29R1")  	suite.adminModule.EmojiDELETEHandler(ctx)  	suite.Equal(http.StatusNotFound, recorder.Code) diff --git a/internal/api/client/admin/emojiget.go b/internal/api/client/admin/emojiget.go index 730d92db1..7ecbcfa19 100644 --- a/internal/api/client/admin/emojiget.go +++ b/internal/api/client/admin/emojiget.go @@ -18,7 +18,6 @@  package admin  import ( -	"errors"  	"fmt"  	"net/http" @@ -82,10 +81,9 @@ func (m *Module) EmojiGETHandler(c *gin.Context) {  		return  	} -	emojiID := c.Param(IDKey) -	if emojiID == "" { -		err := errors.New("no emoji id specified") -		apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) +	emojiID, errWithCode := apiutil.ParseID(c.Param(apiutil.IDKey)) +	if errWithCode != nil { +		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)  		return  	} diff --git a/internal/api/client/admin/emojiget_test.go b/internal/api/client/admin/emojiget_test.go index 86c847b17..b8bad2536 100644 --- a/internal/api/client/admin/emojiget_test.go +++ b/internal/api/client/admin/emojiget_test.go @@ -27,6 +27,7 @@ import (  	"github.com/stretchr/testify/suite"  	"github.com/superseriousbusiness/gotosocial/internal/api/client/admin" +	apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"  )  type EmojiGetTestSuite struct { @@ -39,7 +40,7 @@ func (suite *EmojiGetTestSuite) TestEmojiGet1() {  	path := admin.EmojiPathWithID  	ctx := suite.newContext(recorder, http.MethodGet, nil, path, "application/json") -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	suite.adminModule.EmojiGETHandler(ctx)  	suite.Equal(http.StatusOK, recorder.Code) @@ -71,7 +72,7 @@ func (suite *EmojiGetTestSuite) TestEmojiGet2() {  	path := admin.EmojiPathWithID  	ctx := suite.newContext(recorder, http.MethodGet, nil, path, "application/json") -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	suite.adminModule.EmojiGETHandler(ctx)  	suite.Equal(http.StatusOK, recorder.Code) @@ -102,7 +103,7 @@ func (suite *EmojiGetTestSuite) TestEmojiGetNotFound() {  	path := admin.EmojiPathWithID  	ctx := suite.newContext(recorder, http.MethodGet, nil, path, "application/json") -	ctx.AddParam(admin.IDKey, "01GF8VRXX1R00X7XH8973Z29R1") +	ctx.AddParam(apiutil.IDKey, "01GF8VRXX1R00X7XH8973Z29R1")  	suite.adminModule.EmojiGETHandler(ctx)  	suite.Equal(http.StatusNotFound, recorder.Code) diff --git a/internal/api/client/admin/emojisget.go b/internal/api/client/admin/emojisget.go index 4013e1836..d50b553ac 100644 --- a/internal/api/client/admin/emojisget.go +++ b/internal/api/client/admin/emojisget.go @@ -20,7 +20,6 @@ package admin  import (  	"fmt"  	"net/http" -	"strconv"  	"strings"  	"github.com/gin-gonic/gin" @@ -76,6 +75,8 @@ import (  //		type: integer  //		description: Number of emojis to return. Less than 1, or not set, means unlimited (all emojis).  //		default: 50 +//		minimum: 0 +//		maximum: 200  //		in: query  //	-  //		name: max_shortcode_domain @@ -142,19 +143,10 @@ func (m *Module) EmojisGETHandler(c *gin.Context) {  	maxShortcodeDomain := c.Query(MaxShortcodeDomainKey)  	minShortcodeDomain := c.Query(MinShortcodeDomainKey) -	limit := 50 -	limitString := c.Query(LimitKey) -	if limitString != "" { -		i, err := strconv.ParseInt(limitString, 10, 32) -		if err != nil { -			err := fmt.Errorf("error parsing %s: %s", LimitKey, err) -			apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) -			return -		} -		limit = int(i) -	} -	if limit < 0 { -		limit = 0 +	limit, errWithCode := apiutil.ParseLimit(c.Query(apiutil.LimitKey), 50, 200, 0) +	if errWithCode != nil { +		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) +		return  	}  	var domain string diff --git a/internal/api/client/admin/emojiupdate.go b/internal/api/client/admin/emojiupdate.go index 1d41dd545..37f67cabd 100644 --- a/internal/api/client/admin/emojiupdate.go +++ b/internal/api/client/admin/emojiupdate.go @@ -147,10 +147,9 @@ func (m *Module) EmojiPATCHHandler(c *gin.Context) {  		return  	} -	emojiID := c.Param(IDKey) -	if emojiID == "" { -		err := errors.New("no emoji id specified") -		apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) +	emojiID, errWithCode := apiutil.ParseID(c.Param(apiutil.IDKey)) +	if errWithCode != nil { +		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)  		return  	} diff --git a/internal/api/client/admin/emojiupdate_test.go b/internal/api/client/admin/emojiupdate_test.go index eb9d9d866..676363e39 100644 --- a/internal/api/client/admin/emojiupdate_test.go +++ b/internal/api/client/admin/emojiupdate_test.go @@ -28,6 +28,7 @@ import (  	"github.com/stretchr/testify/suite"  	"github.com/superseriousbusiness/gotosocial/internal/api/client/admin"  	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" +	apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"  	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"  	"github.com/superseriousbusiness/gotosocial/testrig"  ) @@ -53,7 +54,7 @@ func (suite *EmojiUpdateTestSuite) TestEmojiUpdateNewCategory() {  	bodyBytes := requestBody.Bytes()  	recorder := httptest.NewRecorder()  	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPathWithID, w.FormDataContentType()) -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	// call the handler  	suite.adminModule.EmojiPATCHHandler(ctx) @@ -130,7 +131,7 @@ func (suite *EmojiUpdateTestSuite) TestEmojiUpdateSwitchCategory() {  	bodyBytes := requestBody.Bytes()  	recorder := httptest.NewRecorder()  	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPathWithID, w.FormDataContentType()) -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	// call the handler  	suite.adminModule.EmojiPATCHHandler(ctx) @@ -208,7 +209,7 @@ func (suite *EmojiUpdateTestSuite) TestEmojiUpdateCopyRemoteToLocal() {  	bodyBytes := requestBody.Bytes()  	recorder := httptest.NewRecorder()  	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPathWithID, w.FormDataContentType()) -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	// call the handler  	suite.adminModule.EmojiPATCHHandler(ctx) @@ -284,7 +285,7 @@ func (suite *EmojiUpdateTestSuite) TestEmojiUpdateDisableEmoji() {  	bodyBytes := requestBody.Bytes()  	recorder := httptest.NewRecorder()  	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPathWithID, w.FormDataContentType()) -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	// call the handler  	suite.adminModule.EmojiPATCHHandler(ctx) @@ -325,7 +326,7 @@ func (suite *EmojiUpdateTestSuite) TestEmojiUpdateDisableLocalEmoji() {  	bodyBytes := requestBody.Bytes()  	recorder := httptest.NewRecorder()  	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPathWithID, w.FormDataContentType()) -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	// call the handler  	suite.adminModule.EmojiPATCHHandler(ctx) @@ -358,7 +359,7 @@ func (suite *EmojiUpdateTestSuite) TestEmojiUpdateModifyRemoteEmoji() {  	bodyBytes := requestBody.Bytes()  	recorder := httptest.NewRecorder()  	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPathWithID, w.FormDataContentType()) -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	// call the handler  	suite.adminModule.EmojiPATCHHandler(ctx) @@ -391,7 +392,7 @@ func (suite *EmojiUpdateTestSuite) TestEmojiUpdateModifyNoParams() {  	bodyBytes := requestBody.Bytes()  	recorder := httptest.NewRecorder()  	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPathWithID, w.FormDataContentType()) -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	// call the handler  	suite.adminModule.EmojiPATCHHandler(ctx) @@ -425,7 +426,7 @@ func (suite *EmojiUpdateTestSuite) TestEmojiUpdateCopyLocalToLocal() {  	bodyBytes := requestBody.Bytes()  	recorder := httptest.NewRecorder()  	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPathWithID, w.FormDataContentType()) -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	// call the handler  	suite.adminModule.EmojiPATCHHandler(ctx) @@ -459,7 +460,7 @@ func (suite *EmojiUpdateTestSuite) TestEmojiUpdateCopyEmptyShortcode() {  	bodyBytes := requestBody.Bytes()  	recorder := httptest.NewRecorder()  	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPathWithID, w.FormDataContentType()) -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	// call the handler  	suite.adminModule.EmojiPATCHHandler(ctx) @@ -492,7 +493,7 @@ func (suite *EmojiUpdateTestSuite) TestEmojiUpdateCopyNoShortcode() {  	bodyBytes := requestBody.Bytes()  	recorder := httptest.NewRecorder()  	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPathWithID, w.FormDataContentType()) -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	// call the handler  	suite.adminModule.EmojiPATCHHandler(ctx) @@ -526,7 +527,7 @@ func (suite *EmojiUpdateTestSuite) TestEmojiUpdateCopyShortcodeAlreadyInUse() {  	bodyBytes := requestBody.Bytes()  	recorder := httptest.NewRecorder()  	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPathWithID, w.FormDataContentType()) -	ctx.AddParam(admin.IDKey, testEmoji.ID) +	ctx.AddParam(apiutil.IDKey, testEmoji.ID)  	// call the handler  	suite.adminModule.EmojiPATCHHandler(ctx) diff --git a/internal/api/client/admin/reportget.go b/internal/api/client/admin/reportget.go index f70ae8b54..f2acd214c 100644 --- a/internal/api/client/admin/reportget.go +++ b/internal/api/client/admin/reportget.go @@ -18,7 +18,6 @@  package admin  import ( -	"errors"  	"fmt"  	"net/http" @@ -85,10 +84,9 @@ func (m *Module) ReportGETHandler(c *gin.Context) {  		return  	} -	reportID := c.Param(IDKey) -	if reportID == "" { -		err := errors.New("no report id specified") -		apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) +	reportID, errWithCode := apiutil.ParseID(c.Param(apiutil.IDKey)) +	if errWithCode != nil { +		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)  		return  	} diff --git a/internal/api/client/admin/reportresolve.go b/internal/api/client/admin/reportresolve.go index 51c268a2d..f17ae24be 100644 --- a/internal/api/client/admin/reportresolve.go +++ b/internal/api/client/admin/reportresolve.go @@ -18,7 +18,6 @@  package admin  import ( -	"errors"  	"fmt"  	"net/http" @@ -107,10 +106,9 @@ func (m *Module) ReportResolvePOSTHandler(c *gin.Context) {  		return  	} -	reportID := c.Param(IDKey) -	if reportID == "" { -		err := errors.New("no report id specified") -		apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) +	reportID, errWithCode := apiutil.ParseID(c.Param(apiutil.IDKey)) +	if errWithCode != nil { +		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)  		return  	} diff --git a/internal/api/client/admin/reportresolve_test.go b/internal/api/client/admin/reportresolve_test.go index 087080a70..561661fe0 100644 --- a/internal/api/client/admin/reportresolve_test.go +++ b/internal/api/client/admin/reportresolve_test.go @@ -29,6 +29,7 @@ import (  	"github.com/stretchr/testify/suite"  	"github.com/superseriousbusiness/gotosocial/internal/api/client/admin"  	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" +	apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"  	"github.com/superseriousbusiness/gotosocial/internal/config"  	"github.com/superseriousbusiness/gotosocial/internal/gtserror"  	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" @@ -65,7 +66,7 @@ func (suite *ReportResolveTestSuite) resolveReport(  	// create the request  	ctx.Request = httptest.NewRequest(http.MethodPost, requestURI, nil) -	ctx.AddParam(admin.IDKey, targetReportID) +	ctx.AddParam(apiutil.IDKey, targetReportID)  	ctx.Request.Header.Set("accept", "application/json")  	if actionTakenComment != nil {  		ctx.Request.Form = url.Values{"action_taken_comment": {*actionTakenComment}} diff --git a/internal/api/client/admin/reportsget.go b/internal/api/client/admin/reportsget.go index 58501a6d7..893960e2a 100644 --- a/internal/api/client/admin/reportsget.go +++ b/internal/api/client/admin/reportsget.go @@ -20,12 +20,12 @@ package admin  import (  	"fmt"  	"net/http" -	"strconv"  	"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"  )  // ReportsGETHandler swagger:operation GET /api/v1/admin/reports adminReports @@ -72,7 +72,7 @@ import (  //		name: max_id  //		type: string  //		description: >- -//			Return only reports *OLDER* than the given max ID. +//			Return only reports *OLDER* than the given max ID (for paging downwards).  //			The report with the specified ID will not be included in the response.  //		in: query  //	- @@ -81,23 +81,21 @@ import (  //		description: >-  //			Return only reports *NEWER* than the given since ID.  //			The report with the specified ID will not be included in the response. -//			This parameter is functionally equivalent to min_id.  //		in: query  //	-  //		name: min_id  //		type: string  //		description: >- -//			Return only reports *NEWER* than the given min ID. +//			Return only reports immediately *NEWER* than the given min ID (for paging upwards).  //			The report with the specified ID will not be included in the response. -//			This parameter is functionally equivalent to since_id.  //		in: query  //	-  //		name: limit  //		type: integer -//		description: >- -//			Number of reports to return. -//			If more than 100 or less than 1, will be clamped to 100. +//		description: Number of reports to return.  //		default: 20 +//		minimum: 1 +//		maximum: 100  //		in: query  //  //	security: @@ -144,34 +142,30 @@ func (m *Module) ReportsGETHandler(c *gin.Context) {  		return  	} -	var resolved *bool -	if resolvedString := c.Query(ResolvedKey); resolvedString != "" { -		i, err := strconv.ParseBool(resolvedString) -		if err != nil { -			err := fmt.Errorf("error parsing %s: %s", ResolvedKey, err) -			apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) -			return -		} -		resolved = &i +	resolved, errWithCode := apiutil.ParseResolved(c.Query(apiutil.ResolvedKey), nil) +	if errWithCode != nil { +		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) +		return  	} -	limit := 20 -	if limitString := c.Query(LimitKey); limitString != "" { -		i, err := strconv.Atoi(limitString) -		if err != nil { -			err := fmt.Errorf("error parsing %s: %s", LimitKey, err) -			apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) -			return -		} - -		// normalize -		if i < 1 || i > 100 { -			i = 100 -		} -		limit = i +	page, errWithCode := paging.ParseIDPage(c, +		1,   // min limit +		100, // max limit +		20,  // default limit +	) +	if errWithCode != nil { +		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) +		return  	} -	resp, errWithCode := m.processor.Admin().ReportsGet(c.Request.Context(), authed.Account, resolved, c.Query(AccountIDKey), c.Query(TargetAccountIDKey), c.Query(MaxIDKey), c.Query(SinceIDKey), c.Query(MinIDKey), limit) +	resp, errWithCode := m.processor.Admin().ReportsGet( +		c.Request.Context(), +		authed.Account, +		resolved, +		c.Query(apiutil.AccountIDKey), +		c.Query(apiutil.TargetAccountIDKey), +		page, +	)  	if errWithCode != nil {  		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)  		return diff --git a/internal/api/client/admin/reportsget_test.go b/internal/api/client/admin/reportsget_test.go index b20921b36..28efabc00 100644 --- a/internal/api/client/admin/reportsget_test.go +++ b/internal/api/client/admin/reportsget_test.go @@ -28,6 +28,7 @@ import (  	"github.com/stretchr/testify/suite"  	"github.com/superseriousbusiness/gotosocial/internal/api/client/admin"  	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" +	apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"  	"github.com/superseriousbusiness/gotosocial/internal/config"  	"github.com/superseriousbusiness/gotosocial/internal/gtserror"  	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" @@ -63,24 +64,24 @@ func (suite *ReportsGetTestSuite) getReports(  	ctx.Set(oauth.SessionAuthorizedUser, user)  	// create the request URI -	requestPath := admin.ReportsPath + "?" + admin.LimitKey + "=" + strconv.Itoa(limit) +	requestPath := admin.ReportsPath + "?" + apiutil.LimitKey + "=" + strconv.Itoa(limit)  	if resolved != nil { -		requestPath = requestPath + "&" + admin.ResolvedKey + "=" + strconv.FormatBool(*resolved) +		requestPath = requestPath + "&" + apiutil.ResolvedKey + "=" + strconv.FormatBool(*resolved)  	}  	if accountID != "" { -		requestPath = requestPath + "&" + admin.AccountIDKey + "=" + accountID +		requestPath = requestPath + "&" + apiutil.AccountIDKey + "=" + accountID  	}  	if targetAccountID != "" { -		requestPath = requestPath + "&" + admin.TargetAccountIDKey + "=" + targetAccountID +		requestPath = requestPath + "&" + apiutil.TargetAccountIDKey + "=" + targetAccountID  	}  	if maxID != "" { -		requestPath = requestPath + "&" + admin.MaxIDKey + "=" + maxID +		requestPath = requestPath + "&" + apiutil.MaxIDKey + "=" + maxID  	}  	if sinceID != "" { -		requestPath = requestPath + "&" + admin.SinceIDKey + "=" + sinceID +		requestPath = requestPath + "&" + apiutil.SinceIDKey + "=" + sinceID  	}  	if minID != "" { -		requestPath = requestPath + "&" + admin.MinIDKey + "=" + minID +		requestPath = requestPath + "&" + apiutil.MinIDKey + "=" + minID  	}  	baseURI := config.GetProtocol() + "://" + config.GetHost()  	requestURI := baseURI + "/api/" + requestPath @@ -766,7 +767,7 @@ func (suite *ReportsGetTestSuite) TestReportsGetCreatedByAccount() {    }  ]`, string(b)) -	suite.Equal(`<http://localhost:8080/api/v1/admin/reports?limit=20&max_id=01GP3AWY4CRDVRNZKW0TEAMB5R&account_id=01F8MH5NBDF2MV7CTC4Q5128HF>; rel="next", <http://localhost:8080/api/v1/admin/reports?limit=20&min_id=01GP3AWY4CRDVRNZKW0TEAMB5R&account_id=01F8MH5NBDF2MV7CTC4Q5128HF>; rel="prev"`, link) +	suite.Equal(`<http://localhost:8080/api/v1/admin/reports?account_id=01F8MH5NBDF2MV7CTC4Q5128HF&limit=20&max_id=01GP3AWY4CRDVRNZKW0TEAMB5R>; rel="next", <http://localhost:8080/api/v1/admin/reports?account_id=01F8MH5NBDF2MV7CTC4Q5128HF&limit=20&min_id=01GP3AWY4CRDVRNZKW0TEAMB5R>; rel="prev"`, link)  }  func (suite *ReportsGetTestSuite) TestReportsGetTargetAccount() { @@ -1028,8 +1029,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetZeroLimit() {  	suite.NoError(err)  	suite.Len(reports, 2) -	// Limit in Link header should be set to 100 -	suite.Equal(`<http://localhost:8080/api/v1/admin/reports?limit=100&max_id=01GP3AWY4CRDVRNZKW0TEAMB5R>; rel="next", <http://localhost:8080/api/v1/admin/reports?limit=100&min_id=01GP3DFY9XQ1TJMZT5BGAZPXX7>; rel="prev"`, link) +	// Limit in Link header should be set to default (20) +	suite.Equal(`<http://localhost:8080/api/v1/admin/reports?limit=20&max_id=01GP3AWY4CRDVRNZKW0TEAMB5R>; rel="next", <http://localhost:8080/api/v1/admin/reports?limit=20&min_id=01GP3DFY9XQ1TJMZT5BGAZPXX7>; rel="prev"`, link)  }  func (suite *ReportsGetTestSuite) TestReportsGetHighLimit() { diff --git a/internal/api/client/admin/ruledelete.go b/internal/api/client/admin/ruledelete.go index ead219e34..7e8fc0037 100644 --- a/internal/api/client/admin/ruledelete.go +++ b/internal/api/client/admin/ruledelete.go @@ -18,7 +18,6 @@  package admin  import ( -	"errors"  	"fmt"  	"net/http" @@ -95,10 +94,9 @@ func (m *Module) RuleDELETEHandler(c *gin.Context) {  		return  	} -	ruleID := c.Param(IDKey) -	if ruleID == "" { -		err := errors.New("no rule id specified") -		apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) +	ruleID, errWithCode := apiutil.ParseID(c.Param(apiutil.IDKey)) +	if errWithCode != nil { +		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)  		return  	} diff --git a/internal/api/client/admin/ruleget.go b/internal/api/client/admin/ruleget.go index 8281092fb..28c0599f5 100644 --- a/internal/api/client/admin/ruleget.go +++ b/internal/api/client/admin/ruleget.go @@ -18,7 +18,6 @@  package admin  import ( -	"errors"  	"fmt"  	"net/http" @@ -85,10 +84,9 @@ func (m *Module) RuleGETHandler(c *gin.Context) {  		return  	} -	ruleID := c.Param(IDKey) -	if ruleID == "" { -		err := errors.New("no rule id specified") -		apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) +	ruleID, errWithCode := apiutil.ParseID(c.Param(apiutil.IDKey)) +	if errWithCode != nil { +		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)  		return  	} diff --git a/internal/api/client/admin/ruleupdate.go b/internal/api/client/admin/ruleupdate.go index bf838f7ae..d58c30d94 100644 --- a/internal/api/client/admin/ruleupdate.go +++ b/internal/api/client/admin/ruleupdate.go @@ -18,7 +18,6 @@  package admin  import ( -	"errors"  	"fmt"  	"net/http" @@ -87,10 +86,9 @@ func (m *Module) RulePATCHHandler(c *gin.Context) {  		return  	} -	ruleID := c.Param(IDKey) -	if ruleID == "" { -		err := errors.New("no rule id specified") -		apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) +	ruleID, errWithCode := apiutil.ParseID(c.Param(apiutil.IDKey)) +	if errWithCode != nil { +		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)  		return  	} | 
