add remoteip and sitekey optional fields to hcaptcha middleware

as suggested on the kataras/hcaptcha package
This commit is contained in:
Gerasimos (Makis) Maropoulos 2022-09-19 14:39:23 +03:00
parent 80f5699d37
commit a559a2928e
No known key found for this signature in database
GPG Key ID: 403EEB7885C79503
2 changed files with 42 additions and 13 deletions

View File

@ -34,6 +34,13 @@ type Client struct {
// and without additional information. // and without additional information.
FailureHandler context.Handler FailureHandler context.Handler
// Optional checks for siteverify.
//
// The user's remote IP address.
RemoteIP string
// The sitekey form field you expect to see.
SiteKey string
secret string secret string
} }
@ -41,6 +48,22 @@ type Client struct {
// See `New` package-level function. // See `New` package-level function.
type Option func(*Client) type Option func(*Client)
// WithRemoteIP sets the remote ip field to the given value.
// It sends the remoteip form field on "SiteVerify".
func WithRemoteIP(remoteIP string) Option {
return func(c *Client) {
c.RemoteIP = remoteIP
}
}
// WithSiteKey sets the site key field to the given value.
// It sends the sitekey form field on "SiteVerify".
func WithSiteKey(siteKey string) Option {
return func(c *Client) {
c.SiteKey = siteKey
}
}
// Response is the hcaptcha JSON response. // Response is the hcaptcha JSON response.
type Response struct { type Response struct {
ChallengeTS string `json:"challenge_ts"` ChallengeTS string `json:"challenge_ts"`
@ -55,6 +78,7 @@ type Response struct {
// Instructions at: https://docs.hcaptcha.com/. // Instructions at: https://docs.hcaptcha.com/.
// //
// See its `Handler` and `SiteVerify` for details. // See its `Handler` and `SiteVerify` for details.
// See the `WithRemoteIP` and `WithSiteKey` package-level functions too.
func New(secret string, options ...Option) context.Handler { func New(secret string, options ...Option) context.Handler {
c := &Client{ c := &Client{
FailureHandler: DefaultFailureHandler, FailureHandler: DefaultFailureHandler,
@ -76,7 +100,7 @@ func New(secret string, options ...Option) context.Handler {
// The hcaptcha's `Response` (which contains any `ErrorCodes`) // The hcaptcha's `Response` (which contains any `ErrorCodes`)
// is saved on the Request's Context (see `GetResponseFromContext`). // is saved on the Request's Context (see `GetResponseFromContext`).
func (c *Client) Handler(ctx *context.Context) { func (c *Client) Handler(ctx *context.Context) {
v := SiteVerify(ctx, c.secret) v := SiteVerify(ctx, c.secret, c.RemoteIP, c.SiteKey)
ctx.Values().Set(ResponseContextKey, v) ctx.Values().Set(ResponseContextKey, v)
if v.Success { if v.Success {
ctx.Next() ctx.Next()
@ -95,7 +119,9 @@ const apiURL = "https://hcaptcha.com/siteverify"
// It returns the hcaptcha's `Response`. // It returns the hcaptcha's `Response`.
// The `response.Success` reports whether the validation passed. // The `response.Success` reports whether the validation passed.
// Any errors are passed through the `response.ErrorCodes` field. // Any errors are passed through the `response.ErrorCodes` field.
func SiteVerify(ctx *context.Context, secret string) (response Response) { //
// The remoteIP and siteKey input arguments are optional.
func SiteVerify(ctx *context.Context, secret, remoteIP, siteKey string) (response Response) {
generatedResponseID := ctx.FormValue("h-captcha-response") generatedResponseID := ctx.FormValue("h-captcha-response")
if generatedResponseID == "" { if generatedResponseID == "" {
@ -104,12 +130,18 @@ func SiteVerify(ctx *context.Context, secret string) (response Response) {
return return
} }
resp, err := http.DefaultClient.PostForm(apiURL, values := url.Values{
url.Values{ "secret": {secret},
"secret": {secret}, "response": {generatedResponseID},
"response": {generatedResponseID}, }
}, if remoteIP != "" {
) values.Add("remoteip", remoteIP)
}
if siteKey != "" {
values.Add("sitekey", siteKey)
}
resp, err := http.DefaultClient.PostForm(apiURL, values)
if err != nil { if err != nil {
response.ErrorCodes = append(response.ErrorCodes, err.Error()) response.ErrorCodes = append(response.ErrorCodes, err.Error())
return return

View File

@ -49,11 +49,8 @@ func New(secret string) context.Handler {
} }
} }
// SiteVerify accepts context and the secret key(https://www.google.com/recaptcha) // SiteVerify accepts context and the secret key(https://www.google.com/recaptcha) and
// // returns the google's recaptcha response, if `response.Success` is true then validation passed.
// and returns the google's recaptcha response, if `response.Success` is true
//
// then validation passed.
// //
// Use `New` for middleware use instead. // Use `New` for middleware use instead.
func SiteVerify(ctx *context.Context, secret string) (response Response) { func SiteVerify(ctx *context.Context, secret string) (response Response) {