summaryrefslogtreecommitdiff
path: root/internal/api
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2024-06-18 18:18:00 +0200
committerLibravatar GitHub <noreply@github.com>2024-06-18 18:18:00 +0200
commitd2b3d37724a999d4cc78c46157593267e29d184e (patch)
treeac72be127d8adb80bbd756ad970ae14df7b5618f /internal/api
parent[feature] Implement types[] param for notifications (#3009) (diff)
downloadgotosocial-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')
-rw-r--r--internal/api/client/admin/accountaction.go7
-rw-r--r--internal/api/client/admin/admin.go25
-rw-r--r--internal/api/client/admin/emojidelete.go8
-rw-r--r--internal/api/client/admin/emojidelete_test.go7
-rw-r--r--internal/api/client/admin/emojiget.go8
-rw-r--r--internal/api/client/admin/emojiget_test.go7
-rw-r--r--internal/api/client/admin/emojisget.go20
-rw-r--r--internal/api/client/admin/emojiupdate.go7
-rw-r--r--internal/api/client/admin/emojiupdate_test.go23
-rw-r--r--internal/api/client/admin/reportget.go8
-rw-r--r--internal/api/client/admin/reportresolve.go8
-rw-r--r--internal/api/client/admin/reportresolve_test.go3
-rw-r--r--internal/api/client/admin/reportsget.go58
-rw-r--r--internal/api/client/admin/reportsget_test.go21
-rw-r--r--internal/api/client/admin/ruledelete.go8
-rw-r--r--internal/api/client/admin/ruleget.go8
-rw-r--r--internal/api/client/admin/ruleupdate.go8
-rw-r--r--internal/api/client/reports/reportget.go8
-rw-r--r--internal/api/client/reports/reportget_test.go2
-rw-r--r--internal/api/client/reports/reports.go12
-rw-r--r--internal/api/client/reports/reportsget.go61
-rw-r--r--internal/api/client/reports/reportsget_test.go13
-rw-r--r--internal/api/client/search/searchget.go2
-rw-r--r--internal/api/client/search/searchget_test.go2
-rw-r--r--internal/api/util/parsequery.go35
25 files changed, 169 insertions, 200 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
}
diff --git a/internal/api/client/reports/reportget.go b/internal/api/client/reports/reportget.go
index 4a9b06664..c9ca0054f 100644
--- a/internal/api/client/reports/reportget.go
+++ b/internal/api/client/reports/reportget.go
@@ -18,7 +18,6 @@
package reports
import (
- "errors"
"net/http"
"github.com/gin-gonic/gin"
@@ -77,10 +76,9 @@ func (m *Module) ReportGETHandler(c *gin.Context) {
return
}
- targetReportID := c.Param(IDKey)
- if targetReportID == "" {
- err := errors.New("no report id specified")
- apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
+ targetReportID, errWithCode := apiutil.ParseID(c.Param(apiutil.IDKey))
+ if errWithCode != nil {
+ apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}
diff --git a/internal/api/client/reports/reportget_test.go b/internal/api/client/reports/reportget_test.go
index 5b6c406f7..4f01101b2 100644
--- a/internal/api/client/reports/reportget_test.go
+++ b/internal/api/client/reports/reportget_test.go
@@ -145,7 +145,7 @@ func (suite *ReportGetTestSuite) TestGetReport2() {
}
func (suite *ReportGetTestSuite) TestGetReport3() {
- report, err := suite.getReport(http.StatusBadRequest, `{"error":"Bad Request: no report id specified"}`, "")
+ report, err := suite.getReport(http.StatusBadRequest, `{"error":"Bad Request: required key id was not set or had empty value"}`, "")
suite.NoError(err)
suite.Nil(report)
}
diff --git a/internal/api/client/reports/reports.go b/internal/api/client/reports/reports.go
index e881474fb..b10697c1f 100644
--- a/internal/api/client/reports/reports.go
+++ b/internal/api/client/reports/reports.go
@@ -21,19 +21,13 @@ import (
"net/http"
"github.com/gin-gonic/gin"
+ apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
"github.com/superseriousbusiness/gotosocial/internal/processing"
)
const (
- BasePath = "/v1/reports"
- IDKey = "id"
- ResolvedKey = "resolved"
- TargetAccountIDKey = "target_account_id"
- MaxIDKey = "max_id"
- SinceIDKey = "since_id"
- MinIDKey = "min_id"
- LimitKey = "limit"
- BasePathWithID = BasePath + "/:" + IDKey
+ BasePath = "/v1/reports"
+ BasePathWithID = BasePath + "/:" + apiutil.IDKey
)
type Module struct {
diff --git a/internal/api/client/reports/reportsget.go b/internal/api/client/reports/reportsget.go
index 5f194a589..4c3d4e33a 100644
--- a/internal/api/client/reports/reportsget.go
+++ b/internal/api/client/reports/reportsget.go
@@ -18,14 +18,13 @@
package reports
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/reports reports
@@ -67,7 +66,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
// -
@@ -76,24 +75,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 less than 1, will be clamped to 1.
-// If more than 100, will be clamped to 100.
+// description: Number of reports to return.
// default: 20
+// minimum: 1
+// maximum: 100
// in: query
//
// security:
@@ -134,36 +130,29 @@ 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 <= 0 {
- i = 1
- } else if 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.Report().GetMultiple(c.Request.Context(), authed.Account, resolved, c.Query(TargetAccountIDKey), c.Query(MaxIDKey), c.Query(SinceIDKey), c.Query(MinIDKey), limit)
+ resp, errWithCode := m.processor.Report().GetMultiple(
+ c.Request.Context(),
+ authed.Account,
+ resolved,
+ c.Query(apiutil.TargetAccountIDKey),
+ page,
+ )
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
diff --git a/internal/api/client/reports/reportsget_test.go b/internal/api/client/reports/reportsget_test.go
index c63d6c894..2413292a0 100644
--- a/internal/api/client/reports/reportsget_test.go
+++ b/internal/api/client/reports/reportsget_test.go
@@ -29,6 +29,7 @@ import (
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/api/client/reports"
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/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
@@ -61,21 +62,21 @@ func (suite *ReportsGetTestSuite) getReports(
ctx.Set(oauth.SessionAuthorizedUser, user)
// create the request URI
- requestPath := reports.BasePath + "?" + reports.LimitKey + "=" + strconv.Itoa(limit)
+ requestPath := reports.BasePath + "?" + apiutil.LimitKey + "=" + strconv.Itoa(limit)
if resolved != nil {
- requestPath = requestPath + "&" + reports.ResolvedKey + "=" + strconv.FormatBool(*resolved)
+ requestPath = requestPath + "&" + apiutil.ResolvedKey + "=" + strconv.FormatBool(*resolved)
}
if targetAccountID != "" {
- requestPath = requestPath + "&" + reports.TargetAccountIDKey + "=" + targetAccountID
+ requestPath = requestPath + "&" + apiutil.TargetAccountIDKey + "=" + targetAccountID
}
if maxID != "" {
- requestPath = requestPath + "&" + reports.MaxIDKey + "=" + maxID
+ requestPath = requestPath + "&" + apiutil.MaxIDKey + "=" + maxID
}
if sinceID != "" {
- requestPath = requestPath + "&" + reports.SinceIDKey + "=" + sinceID
+ requestPath = requestPath + "&" + apiutil.SinceIDKey + "=" + sinceID
}
if minID != "" {
- requestPath = requestPath + "&" + reports.MinIDKey + "=" + minID
+ requestPath = requestPath + "&" + apiutil.MinIDKey + "=" + minID
}
baseURI := config.GetProtocol() + "://" + config.GetHost()
requestURI := baseURI + "/api/" + requestPath
diff --git a/internal/api/client/search/searchget.go b/internal/api/client/search/searchget.go
index d7ab81388..0f9595efc 100644
--- a/internal/api/client/search/searchget.go
+++ b/internal/api/client/search/searchget.go
@@ -247,7 +247,7 @@ func (m *Module) SearchGETHandler(c *gin.Context) {
Resolve: resolve,
Following: following,
ExcludeUnreviewed: excludeUnreviewed,
- AccountID: c.Query(apiutil.SearchAccountIDKey),
+ AccountID: c.Query(apiutil.AccountIDKey),
APIv1: apiVersion == apiutil.APIv1,
}
diff --git a/internal/api/client/search/searchget_test.go b/internal/api/client/search/searchget_test.go
index a0d0cad0e..27e5f782d 100644
--- a/internal/api/client/search/searchget_test.go
+++ b/internal/api/client/search/searchget_test.go
@@ -105,7 +105,7 @@ func (suite *SearchGetTestSuite) getSearch(
}
if fromAccountID != nil {
- queryParts = append(queryParts, apiutil.SearchAccountIDKey+"="+url.QueryEscape(*fromAccountID))
+ queryParts = append(queryParts, apiutil.AccountIDKey+"="+url.QueryEscape(*fromAccountID))
}
requestURL.RawQuery = strings.Join(queryParts, "&")
diff --git a/internal/api/util/parsequery.go b/internal/api/util/parsequery.go
index 5210735a1..90cc30e6f 100644
--- a/internal/api/util/parsequery.go
+++ b/internal/api/util/parsequery.go
@@ -34,13 +34,16 @@ const (
/* Common keys */
- IDKey = "id"
- LimitKey = "limit"
- LocalKey = "local"
- MaxIDKey = "max_id"
- SinceIDKey = "since_id"
- MinIDKey = "min_id"
- UsernameKey = "username"
+ IDKey = "id"
+ LimitKey = "limit"
+ LocalKey = "local"
+ MaxIDKey = "max_id"
+ SinceIDKey = "since_id"
+ MinIDKey = "min_id"
+ UsernameKey = "username"
+ AccountIDKey = "account_id"
+ TargetAccountIDKey = "target_account_id"
+ ResolvedKey = "resolved"
/* AP endpoint keys */
@@ -55,7 +58,6 @@ const (
SearchQueryKey = "q"
SearchResolveKey = "resolve"
SearchTypeKey = "type"
- SearchAccountIDKey = "account_id"
/* Tag keys */
@@ -132,6 +134,10 @@ func ParseLocal(value string, defaultValue bool) (bool, gtserror.WithCode) {
return parseBool(value, defaultValue, LocalKey)
}
+func ParseResolved(value string, defaultValue *bool) (*bool, gtserror.WithCode) {
+ return parseBoolPtr(value, defaultValue, ResolvedKey)
+}
+
func ParseSearchExcludeUnreviewed(value string, defaultValue bool) (bool, gtserror.WithCode) {
return parseBool(value, defaultValue, SearchExcludeUnreviewedKey)
}
@@ -289,6 +295,19 @@ func parseBool(value string, defaultValue bool, key string) (bool, gtserror.With
return i, nil
}
+func parseBoolPtr(value string, defaultValue *bool, key string) (*bool, gtserror.WithCode) {
+ if value == "" {
+ return defaultValue, nil
+ }
+
+ i, err := strconv.ParseBool(value)
+ if err != nil {
+ return defaultValue, parseError(key, value, defaultValue, err)
+ }
+
+ return &i, nil
+}
+
func parseInt(value string, defaultValue int, max int, min int, key string) (int, gtserror.WithCode) {
if value == "" {
return defaultValue, nil