Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return errors instead of logging/go modules/comments #12

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/dpapathanasiou/go-recaptcha

go 1.13

require github.com/pkg/errors v0.8.1
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
34 changes: 14 additions & 20 deletions recaptcha.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ package recaptcha

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"time"
Expand All @@ -28,44 +28,38 @@ const recaptchaServerName = "https://www.google.com/recaptcha/api/siteverify"

var recaptchaPrivateKey string

// check uses the client ip address, the challenge code from the reCaptcha form,
// and the client's response input to that challenge to determine whether or not
// the client answered the reCaptcha input question correctly.
// It returns a boolean value indicating whether or not the client answered correctly.
func check(remoteip, response string) (r RecaptchaResponse, err error) {
// check will construct the request to the verification API, send it, and return the result.
func check(remoteip, response string) (RecaptchaResponse, error) {
var r RecaptchaResponse
resp, err := http.PostForm(recaptchaServerName,
url.Values{"secret": {recaptchaPrivateKey}, "remoteip": {remoteip}, "response": {response}})
if err != nil {
log.Printf("Post error: %s\n", err)
return
return r, fmt.Errorf("post error: %w", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println("Read error: could not read body: %s", err)
return
return r, fmt.Errorf("read error: could not read body: %w", err)
}
err = json.Unmarshal(body, &r)
if err != nil {
log.Println("Read error: got invalid JSON: %s", err)
return
return r, fmt.Errorf("read error: JSON unmarshal error: %w", err)
}
return
return r, nil
}

// Confirm is the public interface function.
// It calls check, which the client ip address, the challenge code from the reCaptcha form,
// and the client's response input to that challenge to determine whether or not
// the client answered the reCaptcha input question correctly.
// It returns a boolean value indicating whether or not the client answered correctly.
// Confirm is the public interface function that validates the reCAPTCHA token.
// It accepts the client ip address and the token returned to the client after completing the challenge.
// It returns a boolean value indicating whether or not the client token is authentic, meaning the challenge
// was answered correctly.
func Confirm(remoteip, response string) (result bool, err error) {
resp, err := check(remoteip, response)
result = resp.Success
return
}

// Init allows the webserver or code evaluating the reCaptcha form input to set the
// reCaptcha private key (string) value, which will be different for every domain.
// Init allows the webserver or code evaluating the reCAPTCHA token input to set the
// reCAPTCHA private key (string) value, which will be different for every domain.
func Init(key string) {
recaptchaPrivateKey = key
}