feat(api): Don't enforce JSON content type for GET and DELETE requests and enhance cross-module code sharing with a commons module
All checks were successful
/ build (push) Successful in 4m52s
All checks were successful
/ build (push) Successful in 4m52s
This commit is contained in:
parent
20588b44bf
commit
f37ea4fbbb
19 changed files with 61 additions and 56 deletions
|
@ -4,7 +4,7 @@ Changes adhere to [semantic versioning](https://semver.org).
|
|||
|
||||
## [3.0.2] - UNRELEASED
|
||||
|
||||
* ...
|
||||
* Don't enforce JSON content type for GET and DELETE requests
|
||||
|
||||
## [3.0.1] - 2024/06/10
|
||||
|
||||
|
|
|
@ -109,8 +109,7 @@ platform, uploads produced artifacts to that release and publishes docker images
|
|||
**Before** doing so, please ensure that the **commit on `master`** has the **correct version settings** and has been
|
||||
built successfully:
|
||||
|
||||
* Adapt `constants_app.go` and change `Version` to the correct version number
|
||||
* Adapt `app.go` and change `version` to the correct version number (CLI)
|
||||
* Adapt `commons/constants.go` and change `Version` to the correct version number
|
||||
* Adapt `CHANGELOG.md` to reflect changes and ensure a date is properly set in the header, also add a reference link
|
||||
in footer (link to scm git tag source)
|
||||
* Adapt `api.yaml`: `version` attribute must reflect the to be released version
|
||||
|
@ -118,8 +117,7 @@ built successfully:
|
|||
|
||||
After the release has been created, ensure to change the following settings for the _next development cycle_:
|
||||
|
||||
* Adapt `constants_app.go` and change `Version` to the _next_ version number
|
||||
* Adapt `app.go` and change `version` to the _next_ version number (CLI)
|
||||
* Adapt `commons/constants.go` and change `Version` to the _next_ version number
|
||||
* Adapt `CHANGELOG.md` and add an _UNRELEASED_ section
|
||||
* Adapt `api.yaml`: `version` attribute must reflect the _next_ version number
|
||||
* Adapt `env: VERSION_*` in `.forgejo/workflows/release.yaml` to _next_ version number
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
package api
|
||||
|
||||
const (
|
||||
HeaderAppName = "X-App-Name"
|
||||
HeaderAppVersion = "X-App-Version"
|
||||
|
||||
HeaderWebhookToken = "X-Webhook-Token"
|
||||
|
||||
HeaderContentType = "Content-Type"
|
||||
HeaderContentTypeApplicationJson = "application/json"
|
||||
)
|
||||
|
||||
// UpdateState state of an update
|
||||
type UpdateState string
|
||||
|
||||
|
|
5
commons/constants.go
Normal file
5
commons/constants.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
package commons
|
||||
|
||||
const (
|
||||
Version = "3.0.2"
|
||||
)
|
|
@ -225,6 +225,6 @@ func (h *actionHandler) delete(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
c.Header(headerContentType, headerContentTypeApplicationJson)
|
||||
c.Header(api.HeaderContentType, api.HeaderContentTypeApplicationJson)
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -97,6 +97,6 @@ func (h *actionInvocationHandler) delete(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
c.Header(headerContentType, headerContentTypeApplicationJson)
|
||||
c.Header(api.HeaderContentType, api.HeaderContentTypeApplicationJson)
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"git.myservermanager.com/varakh/upda/api"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
@ -13,6 +14,6 @@ func newAuthHandler() *authHandler {
|
|||
}
|
||||
|
||||
func (h *authHandler) login(c *gin.Context) {
|
||||
c.Header(headerContentType, headerContentTypeApplicationJson)
|
||||
c.Header(api.HeaderContentType, api.HeaderContentTypeApplicationJson)
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package server
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.myservermanager.com/varakh/upda/api"
|
||||
"git.myservermanager.com/varakh/upda/util"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-playground/validator/v10"
|
||||
|
@ -20,7 +21,7 @@ func errAbortWithValidatorPayload(c *gin.Context, err error) {
|
|||
}
|
||||
|
||||
resErr := newServiceError(illegalArgument, fmt.Errorf("validation error: %v (%w)", util.ValuesString(errorMap), err))
|
||||
c.Header(headerContentType, headerContentTypeApplicationJson)
|
||||
c.Header(api.HeaderContentType, api.HeaderContentTypeApplicationJson)
|
||||
_ = c.AbortWithError(http.StatusBadRequest, resErr)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -66,6 +66,6 @@ func (h *eventHandler) delete(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
c.Header(headerContentType, headerContentTypeApplicationJson)
|
||||
c.Header(api.HeaderContentType, api.HeaderContentTypeApplicationJson)
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package server
|
|||
|
||||
import (
|
||||
"git.myservermanager.com/varakh/upda/api"
|
||||
"git.myservermanager.com/varakh/upda/commons"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
@ -17,7 +18,7 @@ func newInfoHandler(a *appConfig) *infoHandler {
|
|||
func (h *infoHandler) show(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, api.DataResponse{Data: gin.H{
|
||||
"name": name,
|
||||
"version": version,
|
||||
"Version": commons.Version,
|
||||
"timeZone": h.appConfig.timeZone,
|
||||
}})
|
||||
}
|
||||
|
|
|
@ -92,6 +92,6 @@ func (h *secretHandler) delete(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
c.Header(headerContentType, headerContentTypeApplicationJson)
|
||||
c.Header(api.HeaderContentType, api.HeaderContentTypeApplicationJson)
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -101,6 +101,6 @@ func (h *updateHandler) delete(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
c.Header(headerContentType, headerContentTypeApplicationJson)
|
||||
c.Header(api.HeaderContentType, api.HeaderContentTypeApplicationJson)
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -125,6 +125,6 @@ func (h *webhookHandler) delete(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
c.Header(headerContentType, headerContentTypeApplicationJson)
|
||||
c.Header(api.HeaderContentType, api.HeaderContentTypeApplicationJson)
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ func newWebhookInvocationHandler(i *webhookInvocationService, w *webhookService)
|
|||
}
|
||||
|
||||
func (h *webhookInvocationHandler) execute(c *gin.Context) {
|
||||
tokenHeader := c.GetHeader(headerWebhookToken)
|
||||
tokenHeader := c.GetHeader(api.HeaderWebhookToken)
|
||||
webhookId := c.Param("id")
|
||||
|
||||
var w *Webhook
|
||||
|
@ -57,6 +57,6 @@ func (h *webhookInvocationHandler) execute(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
c.Header(headerContentType, headerContentTypeApplicationJson)
|
||||
c.Header(api.HeaderContentType, api.HeaderContentTypeApplicationJson)
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package server
|
|||
import (
|
||||
"fmt"
|
||||
"git.myservermanager.com/varakh/upda/api"
|
||||
"git.myservermanager.com/varakh/upda/commons"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
@ -10,7 +11,7 @@ import (
|
|||
|
||||
func middlewareAppName() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Header(headerAppName, name)
|
||||
c.Header(api.HeaderAppName, name)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +32,7 @@ func middlewareGlobalMethodNotAllowed() gin.HandlerFunc {
|
|||
|
||||
func middlewareEnforceJsonContentType() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if c.Request.Method != http.MethodOptions && !strings.HasPrefix(c.GetHeader(headerContentType), headerContentTypeApplicationJson) {
|
||||
if c.Request.Method != http.MethodOptions && !strings.HasPrefix(c.GetHeader(api.HeaderContentType), api.HeaderContentTypeApplicationJson) {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, api.NewErrorResponseWithStatusAndMessage(string(illegalArgument), "content-type must be application/json"))
|
||||
return
|
||||
}
|
||||
|
@ -41,14 +42,14 @@ func middlewareEnforceJsonContentType() gin.HandlerFunc {
|
|||
|
||||
func middlewareAppVersion() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Header(headerAppVersion, version)
|
||||
c.Header(api.HeaderAppVersion, commons.Version)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func middlewareAppContentType() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Header(headerContentType, headerContentTypeApplicationJson)
|
||||
c.Header(api.HeaderContentType, api.HeaderContentTypeApplicationJson)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +62,7 @@ func middlewareErrorHandler() gin.HandlerFunc {
|
|||
|
||||
if len(c.Errors) > 0 {
|
||||
// status -1 doesn't overwrite existing status code
|
||||
c.Header(headerContentType, headerContentTypeApplicationJson)
|
||||
c.Header(api.HeaderContentType, api.HeaderContentTypeApplicationJson)
|
||||
c.JSON(-1, api.NewErrorResponseWithStatusAndMessage(errCodeToStr(c.Errors.Last()), c.Errors.Last().Error()))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -100,7 +100,6 @@ func Start() {
|
|||
hh := newHealthHandler()
|
||||
authH := newAuthHandler()
|
||||
|
||||
router.Use(middlewareEnforceJsonContentType())
|
||||
router.Use(middlewareAppName())
|
||||
router.Use(middlewareAppVersion())
|
||||
router.Use(middlewareAppContentType())
|
||||
|
@ -121,7 +120,7 @@ func Start() {
|
|||
apiPublicGroup.GET("/health", hh.show)
|
||||
apiPublicGroup.GET("/info", ih.show)
|
||||
|
||||
apiPublicGroup.POST("/webhooks/:id", wih.execute)
|
||||
apiPublicGroup.POST("/webhooks/:id", middlewareEnforceJsonContentType(), wih.execute)
|
||||
|
||||
var authMethodHandler gin.HandlerFunc
|
||||
|
||||
|
@ -141,14 +140,14 @@ func Start() {
|
|||
|
||||
apiAuthGroup.GET("/updates", uh.paginate)
|
||||
apiAuthGroup.GET("/updates/:id", uh.get)
|
||||
apiAuthGroup.PATCH("/updates/:id/state", uh.updateState)
|
||||
apiAuthGroup.PATCH("/updates/:id/state", middlewareEnforceJsonContentType(), uh.updateState)
|
||||
apiAuthGroup.DELETE("/updates/:id", uh.delete)
|
||||
|
||||
apiAuthGroup.GET("/webhooks", wh.paginate)
|
||||
apiAuthGroup.POST("/webhooks", wh.create)
|
||||
apiAuthGroup.POST("/webhooks", middlewareEnforceJsonContentType(), wh.create)
|
||||
apiAuthGroup.GET("/webhooks/:id", wh.get)
|
||||
apiAuthGroup.PATCH("/webhooks/:id/label", wh.updateLabel)
|
||||
apiAuthGroup.PATCH("/webhooks/:id/ignore-host", wh.updateIgnoreHost)
|
||||
apiAuthGroup.PATCH("/webhooks/:id/label", middlewareEnforceJsonContentType(), wh.updateLabel)
|
||||
apiAuthGroup.PATCH("/webhooks/:id/ignore-host", middlewareEnforceJsonContentType(), wh.updateIgnoreHost)
|
||||
apiAuthGroup.DELETE("/webhooks/:id", wh.delete)
|
||||
|
||||
apiAuthGroup.GET("/events", eh.window)
|
||||
|
@ -157,22 +156,22 @@ func Start() {
|
|||
|
||||
apiAuthGroup.GET("/secrets", sh.getAll)
|
||||
apiAuthGroup.GET("/secrets/:id", sh.get)
|
||||
apiAuthGroup.POST("/secrets", sh.create)
|
||||
apiAuthGroup.PATCH("/secrets/:id/value", sh.updateValue)
|
||||
apiAuthGroup.POST("/secrets", middlewareEnforceJsonContentType(), sh.create)
|
||||
apiAuthGroup.PATCH("/secrets/:id/value", middlewareEnforceJsonContentType(), sh.updateValue)
|
||||
apiAuthGroup.DELETE("/secrets/:id", sh.delete)
|
||||
|
||||
apiAuthGroup.GET("/actions", ah.paginate)
|
||||
apiAuthGroup.POST("/actions", ah.create)
|
||||
apiAuthGroup.POST("/actions", middlewareEnforceJsonContentType(), ah.create)
|
||||
apiAuthGroup.GET("/actions/:id", ah.get)
|
||||
apiAuthGroup.PATCH("/actions/:id/label", ah.updateLabel)
|
||||
apiAuthGroup.PATCH("/actions/:id/match-event", ah.updateMatchEvent)
|
||||
apiAuthGroup.PATCH("/actions/:id/match-host", ah.updateMatchHost)
|
||||
apiAuthGroup.PATCH("/actions/:id/match-application", ah.updateMatchApplication)
|
||||
apiAuthGroup.PATCH("/actions/:id/match-provider", ah.updateMatchProvider)
|
||||
apiAuthGroup.PATCH("/actions/:id/payload", ah.updatePayload)
|
||||
apiAuthGroup.PATCH("/actions/:id/enabled", ah.updateEnabled)
|
||||
apiAuthGroup.PATCH("/actions/:id/label", middlewareEnforceJsonContentType(), ah.updateLabel)
|
||||
apiAuthGroup.PATCH("/actions/:id/match-event", middlewareEnforceJsonContentType(), ah.updateMatchEvent)
|
||||
apiAuthGroup.PATCH("/actions/:id/match-host", middlewareEnforceJsonContentType(), ah.updateMatchHost)
|
||||
apiAuthGroup.PATCH("/actions/:id/match-application", middlewareEnforceJsonContentType(), ah.updateMatchApplication)
|
||||
apiAuthGroup.PATCH("/actions/:id/match-provider", middlewareEnforceJsonContentType(), ah.updateMatchProvider)
|
||||
apiAuthGroup.PATCH("/actions/:id/payload", middlewareEnforceJsonContentType(), ah.updatePayload)
|
||||
apiAuthGroup.PATCH("/actions/:id/enabled", middlewareEnforceJsonContentType(), ah.updateEnabled)
|
||||
apiAuthGroup.DELETE("/actions/:id", ah.delete)
|
||||
apiAuthGroup.POST("/actions/:id/test", aih.test)
|
||||
apiAuthGroup.POST("/actions/:id/test", middlewareEnforceJsonContentType(), aih.test)
|
||||
|
||||
apiAuthGroup.GET("/action-invocations", aih.paginate)
|
||||
apiAuthGroup.GET("/action-invocations/:id", aih.get)
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
package server
|
||||
|
||||
const (
|
||||
headerAppName = "X-App-Name"
|
||||
headerAppVersion = "X-App-Version"
|
||||
|
||||
headerWebhookToken = "X-Webhook-Token"
|
||||
|
||||
headerContentType = "Content-Type"
|
||||
headerContentTypeApplicationJson = "application/json"
|
||||
)
|
|
@ -2,5 +2,4 @@ package server
|
|||
|
||||
const (
|
||||
name = "upda"
|
||||
version = "3.0.2"
|
||||
)
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"git.myservermanager.com/varakh/upda/api"
|
||||
"git.myservermanager.com/varakh/upda/commons"
|
||||
"git.myservermanager.com/varakh/upda/util"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
@ -16,7 +17,7 @@ import (
|
|||
const (
|
||||
name = "upda-cli"
|
||||
desc = "a commandline helper for upda"
|
||||
version = "3.0.2"
|
||||
version = commons.Version
|
||||
|
||||
envServerUrl = "UPDA_SERVER_URL"
|
||||
envUser = "UPDA_USER"
|
||||
|
@ -214,7 +215,7 @@ func webhookCreate(cCtx *cli.Context) error {
|
|||
client.SetDisableWarn(true)
|
||||
res, err := client.R().
|
||||
SetBasicAuth(cCtx.String(flagUser), cCtx.String(flagPass)).
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetHeader(api.HeaderContentType, api.HeaderContentTypeApplicationJson).
|
||||
SetBody(&payload).
|
||||
SetResult(&successRes).
|
||||
SetError(&errorRes).
|
||||
|
@ -262,8 +263,8 @@ func webhookSend(cCtx *cli.Context) error {
|
|||
client := resty.New()
|
||||
client.SetDisableWarn(true)
|
||||
res, err := client.R().
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetHeader("X-Webhook-Token", cCtx.String(flagWebhookToken)).
|
||||
SetHeader(api.HeaderContentType, api.HeaderContentTypeApplicationJson).
|
||||
SetHeader(api.HeaderWebhookToken, cCtx.String(flagWebhookToken)).
|
||||
SetBody(payloadArg).
|
||||
SetError(&errorRes).
|
||||
Post(url)
|
||||
|
@ -290,7 +291,7 @@ func updateShow(cCtx *cli.Context) error {
|
|||
client.SetDisableWarn(true)
|
||||
res, err := client.R().
|
||||
SetBasicAuth(cCtx.String(flagUser), cCtx.String(flagPass)).
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetHeader(api.HeaderContentType, api.HeaderContentTypeApplicationJson).
|
||||
SetResult(&successRes).
|
||||
SetError(&errorRes).
|
||||
Get(url)
|
||||
|
|
Loading…
Reference in a new issue