Skip to content

Commit

Permalink
Added support for Google reCAPTCHA
Browse files Browse the repository at this point in the history
  • Loading branch information
josephspurrier committed Sep 15, 2015
1 parent 5b86922 commit 04472e2
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 10 deletions.
18 changes: 18 additions & 0 deletions README.md
Expand Up @@ -69,6 +69,7 @@ There are a few external packages:
github.com/gorilla/context - registry for global request variables
github.com/gorilla/sessions - cookie and filesystem sessions
github.com/go-sql-driver/mysql - MySQL driver
github.com/haisum/recaptcha - Google reCAPTCHA support
github.com/jmoiron/sqlx - MySQL general purpose extensions
github.com/josephspurrier/csrfbanana - CSRF protection for gorilla sessions
github.com/julienschmidt/httprouter - high performance HTTP request router
Expand Down Expand Up @@ -261,6 +262,18 @@ if err != nil {
}
~~~

Validate a form if the Google reCAPTCHA is enabled in the config:

~~~ go
// Validate with Google reCAPTCHA
if !recaptcha.Verified(r) {
sess.AddFlash(view.Flash{"reCAPTCHA invalid!", view.FlashError})
sess.Save(r, w)
RegisterGET(w, r)
return
}
~~~

## Database

It's a good idea to abstract the database layer out so if you need to make
Expand Down Expand Up @@ -330,6 +343,11 @@ This is config.json:
"Port": 25,
"From": ""
},
"Recaptcha": {
"Enabled": false,
"Secret": "",
"SiteKey": ""
},
"Server": {
"Hostname": "",
"UseHTTP": true,
Expand Down
5 changes: 5 additions & 0 deletions config/config.json
Expand Up @@ -20,6 +20,11 @@
"Port": 25,
"From": ""
},
"Recaptcha": {
"Enabled": false,
"Secret": "",
"SiteKey": ""
},
"Server": {
"Hostname": "",
"UseHTTP": true,
Expand Down
9 changes: 9 additions & 0 deletions controller/register.go
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/josephspurrier/gowebapp/model"
"github.com/josephspurrier/gowebapp/shared/passhash"
"github.com/josephspurrier/gowebapp/shared/recaptcha"
"github.com/josephspurrier/gowebapp/shared/session"
"github.com/josephspurrier/gowebapp/shared/view"

Expand Down Expand Up @@ -45,6 +46,14 @@ func RegisterPOST(w http.ResponseWriter, r *http.Request) {
return
}

// Validate with Google reCAPTCHA
if !recaptcha.Verified(r) {
sess.AddFlash(view.Flash{"reCAPTCHA invalid!", view.FlashError})
sess.Save(r, w)
RegisterGET(w, r)
return
}

// Get form values
first_name := r.FormValue("first_name")
last_name := r.FormValue("last_name")
Expand Down
17 changes: 11 additions & 6 deletions gowebapp.go
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/josephspurrier/gowebapp/shared/database"
"github.com/josephspurrier/gowebapp/shared/email"
"github.com/josephspurrier/gowebapp/shared/jsonconfig"
"github.com/josephspurrier/gowebapp/shared/recaptcha"
"github.com/josephspurrier/gowebapp/shared/server"
"github.com/josephspurrier/gowebapp/shared/session"
"github.com/josephspurrier/gowebapp/shared/view"
Expand Down Expand Up @@ -38,6 +39,9 @@ func main() {
// Connect to database
database.Connect(config.Database)

// Configure the Google reCAPTCHA prior to loading view plugins
recaptcha.Configure(config.Recaptcha)

// Setup the views
view.Configure(config.View)
view.LoadTemplates(config.Template.Root, config.Template.Children)
Expand All @@ -56,12 +60,13 @@ var config = &configuration{}

// configuration contains the application settings
type configuration struct {
Database database.Databases `json:"Database"`
Email email.SMTPInfo `json:"Email"`
Server server.Server `json:"Server"`
Session session.Session `json:"Session"`
Template view.Template `json:"Template"`
View view.View `json:"View"`
Database database.Databases `json:"Database"`
Email email.SMTPInfo `json:"Email"`
Recaptcha recaptcha.RecaptchaInfo `json:"Recaptcha"`
Server server.Server `json:"Server"`
Session session.Session `json:"Session"`
Template view.Template `json:"Template"`
View view.View `json:"View"`
}

// ParseJSON unmarshals bytes to structs
Expand Down
40 changes: 40 additions & 0 deletions shared/recaptcha/recaptcha.go
@@ -0,0 +1,40 @@
package recaptcha

import (
"github.com/haisum/recaptcha"
"net/http"
)

var (
recap RecaptchaInfo
)

// RecaptchaInfo has the details for the Google reCAPTCHA
type RecaptchaInfo struct {
Enabled bool
Secret string
SiteKey string
}

// Configure adds the settings for Google reCAPTCHA
func Configure(c RecaptchaInfo) {
recap = c
}

// ReadConfig returns the settings for Google reCAPTCHA
func ReadConfig() RecaptchaInfo {
return recap
}

// Verified returns whether the Google reCAPTCHA was verified or not
func Verified(r *http.Request) bool {
if !recap.Enabled {
return true
}

// Check the reCaptcha
re := recaptcha.R{
Secret: recap.Secret,
}
return re.Verify(*r)
}
9 changes: 9 additions & 0 deletions shared/view/plugin/plugin.go
Expand Up @@ -4,6 +4,7 @@ import (
"html/template"
"log"

"github.com/josephspurrier/gowebapp/shared/recaptcha"
"github.com/josephspurrier/gowebapp/shared/view"
)

Expand Down Expand Up @@ -41,5 +42,13 @@ func TemplateFuncMap(v view.View) template.FuncMap {
return template.HTML(`<a href="` + v.PrependBaseURI(path) + `">` + name + `</a>`)
}

f["SITEKEY"] = func() template.HTML {
if recaptcha.ReadConfig().Enabled {
return template.HTML(recaptcha.ReadConfig().SiteKey)
}

return template.HTML("")
}

return f
}
4 changes: 1 addition & 3 deletions shared/view/view.go
Expand Up @@ -96,9 +96,6 @@ func New(req *http.Request) *View {
v.Vars = make(map[string]interface{})
v.Vars["AuthLevel"] = "anon"

//v.Vars["flashclass"] = "alert-box alert"
//v.Vars["flashmessage"] = "Cool!"

v.BaseURI = viewInfo.BaseURI
v.Extension = viewInfo.Extension
v.Folder = viewInfo.Folder
Expand All @@ -107,6 +104,7 @@ func New(req *http.Request) *View {
// Make sure BaseURI is available in the templates
v.Vars["BaseURI"] = v.BaseURI

// This is required for the view to access the request
r = req

// Get session
Expand Down
6 changes: 5 additions & 1 deletion template/register.tmpl
@@ -1,5 +1,5 @@
{{define "title"}}Create an Account{{end}}
{{define "head"}}{{end}}
{{define "head"}}{{JS "//www.google.com/recaptcha/api.js"}}{{end}}
{{define "content"}}

<div class="row">
Expand Down Expand Up @@ -30,6 +30,10 @@
<div><input type="password" id="password_verify" name="password_verify" maxlength="48" placeholder="Verify Password" value="{{.password}}" /></div>
</div>

{{if SITEKEY}}
<div class="g-recaptcha" data-sitekey="{{SITEKEY}}" style="margin-bottom: 1rem;"></div>
{{end}}

<div>
<label for="Create Account"></label>
<div><input type="submit" value="Create Account" class="button" /></div>
Expand Down

0 comments on commit 04472e2

Please sign in to comment.