Custom URL parser

This commit is contained in:
rxdn 2022-07-16 21:06:30 +01:00
parent 02a50719b0
commit c9c9b2eb02
10 changed files with 55 additions and 10 deletions

View File

@ -17,7 +17,7 @@ type integrationCreateBody struct {
PrivacyPolicyUrl *string `json:"privacy_policy_url" validate:"omitempty,url,max=255,startswith=https://"` PrivacyPolicyUrl *string `json:"privacy_policy_url" validate:"omitempty,url,max=255,startswith=https://"`
Method string `json:"http_method" validate:"required,oneof=GET POST"` Method string `json:"http_method" validate:"required,oneof=GET POST"`
WebhookUrl string `json:"webhook_url" validate:"required,url,max=255,startswith=http"` WebhookUrl string `json:"webhook_url" validate:"required,webhook,max=255"`
Secrets []struct { Secrets []struct {
Name string `json:"name" validate:"required,min=1,max=32,excludesall=% "` Name string `json:"name" validate:"required,min=1,max=32,excludesall=% "`
@ -34,7 +34,7 @@ type integrationCreateBody struct {
} `json:"placeholders" validate:"dive,omitempty,min=0,max=15"` } `json:"placeholders" validate:"dive,omitempty,min=0,max=15"`
} }
var validate = validator.New() var validate = newIntegrationValidator()
func CreateIntegrationHandler(ctx *gin.Context) { func CreateIntegrationHandler(ctx *gin.Context) {
userId := ctx.Keys["userid"].(uint64) userId := ctx.Keys["userid"].(uint64)

View File

@ -6,6 +6,7 @@ import (
"github.com/TicketsBot/database" "github.com/TicketsBot/database"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"strconv" "strconv"
"strings"
) )
type integrationResponse struct { type integrationResponse struct {
@ -87,7 +88,7 @@ func GetIntegrationHandler(ctx *gin.Context) {
ctx.JSON(200, integrationResponse{ ctx.JSON(200, integrationResponse{
Id: integration.Id, Id: integration.Id,
OwnerId: integration.OwnerId, OwnerId: integration.OwnerId,
WebhookHost: utils.GetUrlHost(integration.WebhookUrl), WebhookHost: utils.GetUrlHost(strings.ReplaceAll(integration.WebhookUrl, "%", "")),
Name: integration.Name, Name: integration.Name,
Description: integration.Description, Description: integration.Description,
ImageUrl: integration.ImageUrl, ImageUrl: integration.ImageUrl,

View File

@ -5,6 +5,7 @@ import (
"github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/GoPanel/utils"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"strconv" "strconv"
"strings"
) )
const pageLimit = 20 const pageLimit = 20
@ -55,7 +56,7 @@ func ListIntegrationsHandler(ctx *gin.Context) {
integrationResponse: integrationResponse{ integrationResponse: integrationResponse{
Id: integration.Id, Id: integration.Id,
OwnerId: integration.OwnerId, OwnerId: integration.OwnerId,
WebhookHost: utils.GetUrlHost(integration.WebhookUrl), WebhookHost: utils.GetUrlHost(strings.ReplaceAll(integration.WebhookUrl, "%", "")),
Name: integration.Name, Name: integration.Name,
Description: integration.Description, Description: integration.Description,
ImageUrl: integration.ImageUrl, ImageUrl: integration.ImageUrl,

View File

@ -7,6 +7,7 @@ import (
"github.com/TicketsBot/database" "github.com/TicketsBot/database"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"strings"
) )
type integrationWithCount struct { type integrationWithCount struct {
@ -56,7 +57,7 @@ func GetOwnedIntegrationsHandler(ctx *gin.Context) {
integrationResponse: integrationResponse{ integrationResponse: integrationResponse{
Id: integration.Id, Id: integration.Id,
OwnerId: integration.OwnerId, OwnerId: integration.OwnerId,
WebhookHost: utils.GetUrlHost(integration.WebhookUrl), WebhookHost: utils.GetUrlHost(strings.ReplaceAll(integration.WebhookUrl, "%", "")),
Name: integration.Name, Name: integration.Name,
Description: integration.Description, Description: integration.Description,
ImageUrl: integration.ImageUrl, ImageUrl: integration.ImageUrl,

View File

@ -18,7 +18,7 @@ type integrationUpdateBody struct {
PrivacyPolicyUrl *string `json:"privacy_policy_url" validate:"omitempty,url,max=255,startswith=https://"` PrivacyPolicyUrl *string `json:"privacy_policy_url" validate:"omitempty,url,max=255,startswith=https://"`
Method string `json:"http_method" validate:"required,oneof=GET POST"` Method string `json:"http_method" validate:"required,oneof=GET POST"`
WebhookUrl string `json:"webhook_url" validate:"required,url,max=255,startswith=http"` WebhookUrl string `json:"webhook_url" validate:"required,webhook,max=255"`
Secrets []struct { Secrets []struct {
Id int `json:"id" validate:"omitempty,min=1"` Id int `json:"id" validate:"omitempty,min=1"`

View File

@ -0,0 +1,36 @@
package api
import (
"github.com/TicketsBot/GoPanel/utils"
"github.com/go-playground/validator/v10"
"net/url"
"regexp"
)
var placeholderRegex = regexp.MustCompile(`%[\w|-]+%`)
func newIntegrationValidator() *validator.Validate {
v := validator.New()
utils.Must(v.RegisterValidation("webhook", WebhookValidator))
return v
}
func WebhookValidator(fl validator.FieldLevel) bool {
value := fl.Field().String()
stripped := placeholderRegex.ReplaceAllString(value, "")
parsed, err := url.Parse(stripped)
if err != nil {
return false
}
if parsed.Scheme != "http" && parsed.Scheme != "https" {
return false
}
if parsed.Host == "" {
return false
}
return true
}

2
go.mod
View File

@ -21,6 +21,7 @@ require (
github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/google/uuid v1.1.1 github.com/google/uuid v1.1.1
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.0
github.com/jackc/pgconn v1.6.1
github.com/jackc/pgtype v1.4.0 github.com/jackc/pgtype v1.4.0
github.com/jackc/pgx/v4 v4.7.1 github.com/jackc/pgx/v4 v4.7.1
github.com/pasztorpisti/qs v0.0.0-20171216220353-8d6c33ee906c github.com/pasztorpisti/qs v0.0.0-20171216220353-8d6c33ee906c
@ -51,7 +52,6 @@ require (
github.com/gorilla/securecookie v1.1.1 // indirect github.com/gorilla/securecookie v1.1.1 // indirect
github.com/gorilla/sessions v1.2.1 // indirect github.com/gorilla/sessions v1.2.1 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.6.1 // indirect
github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.0.2 // indirect github.com/jackc/pgproto3/v2 v2.0.2 // indirect

2
go.sum
View File

@ -5,8 +5,6 @@ github.com/TicketsBot/archiverclient v0.0.0-20220326163414-558fd52746dc h1:n15W8
github.com/TicketsBot/archiverclient v0.0.0-20220326163414-558fd52746dc/go.mod h1:2KcfHS0JnSsgcxZBs3NyWMXNQzEo67mBSGOyzHPWOCc= github.com/TicketsBot/archiverclient v0.0.0-20220326163414-558fd52746dc/go.mod h1:2KcfHS0JnSsgcxZBs3NyWMXNQzEo67mBSGOyzHPWOCc=
github.com/TicketsBot/common v0.0.0-20220703211704-f792aa9f0c42 h1:3/qnbrEfL8gqSbjJ4o7WKkdoPngmhjAGEXFwteEjpqs= github.com/TicketsBot/common v0.0.0-20220703211704-f792aa9f0c42 h1:3/qnbrEfL8gqSbjJ4o7WKkdoPngmhjAGEXFwteEjpqs=
github.com/TicketsBot/common v0.0.0-20220703211704-f792aa9f0c42/go.mod h1:WxHh6bY7KhIqdayeOp5f0Zj2NNi/7QqCQfMEqHnpdAM= github.com/TicketsBot/common v0.0.0-20220703211704-f792aa9f0c42/go.mod h1:WxHh6bY7KhIqdayeOp5f0Zj2NNi/7QqCQfMEqHnpdAM=
github.com/TicketsBot/database v0.0.0-20220710122820-0fdcde6692f0 h1:1lrgdlmyf0KFkl4Y3Cu1L6BQzKOzowoLUp/Kq/jwfvc=
github.com/TicketsBot/database v0.0.0-20220710122820-0fdcde6692f0/go.mod h1:F57cywrZsnper1cy56Bx0c/HEsxQBLHz3Pl98WXblWw=
github.com/TicketsBot/database v0.0.0-20220712212403-61804b8beb18 h1:p3rr325yK5CqWQMBML1SzkC+mXx+SSaBq4PnyxeBYXA= github.com/TicketsBot/database v0.0.0-20220712212403-61804b8beb18 h1:p3rr325yK5CqWQMBML1SzkC+mXx+SSaBq4PnyxeBYXA=
github.com/TicketsBot/database v0.0.0-20220712212403-61804b8beb18/go.mod h1:F57cywrZsnper1cy56Bx0c/HEsxQBLHz3Pl98WXblWw= github.com/TicketsBot/database v0.0.0-20220712212403-61804b8beb18/go.mod h1:F57cywrZsnper1cy56Bx0c/HEsxQBLHz3Pl98WXblWw=
github.com/TicketsBot/logarchiver v0.0.0-20220326162808-cdf0310f5e1c h1:OqGjFH6mbE6gd+NqI2ARJdtH3UUvhiAkD0r0fhGJK2s= github.com/TicketsBot/logarchiver v0.0.0-20220326162808-cdf0310f5e1c h1:OqGjFH6mbE6gd+NqI2ARJdtH3UUvhiAkD0r0fhGJK2s=

View File

@ -1,6 +1,8 @@
package utils package utils
import "net/url" import (
"net/url"
)
func GetUrlHost(rawUrl string) string { func GetUrlHost(rawUrl string) string {
parsed, err := url.Parse(rawUrl) parsed, err := url.Parse(rawUrl)

View File

@ -15,3 +15,9 @@ func ValueOrZero[T any](v *T) T {
func Slice[T any](v ...T) []T { func Slice[T any](v ...T) []T {
return v return v
} }
func Must(err error) {
if err != nil {
panic(err)
}
}