School subscription captcha first iteration

This commit is contained in:
Andrea Fazzi 2020-02-12 09:50:35 +01:00
parent d9911b68ce
commit 1bb38bb002
11 changed files with 77 additions and 3 deletions

View file

@ -53,4 +53,9 @@ var (
TemplateName: "error_questions_order_is_empty",
Err: errors.New(i18n.Errors["questionsOrderIsEmpty"]["it"]),
}
WrongCaptcha = &Error{
TemplateName: "error_wrong_captcha",
Err: errors.New(i18n.Errors["wrongCaptcha"]["it"]),
}
)

2
go.mod
View file

@ -8,6 +8,7 @@ require (
github.com/auth0/go-jwt-middleware v0.0.0-20190805220309-36081240882b
github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b // indirect
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee // indirect
github.com/dchest/captcha v0.0.0-20170622155422-6a29415a8364
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/dgryski/go-gk v0.0.0-20140819190930-201884a44051 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
@ -44,6 +45,7 @@ require (
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa // indirect
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/russross/blackfriday.v2 v2.0.0
gopkg.in/yaml.v2 v2.2.4

5
go.sum
View file

@ -33,6 +33,8 @@ github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee h1:BnPxIde0gjtTnc9
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/captcha v0.0.0-20170622155422-6a29415a8364 h1:U+BMqUt8LFgyrF0/NKgPZdr1sGZ3j6uBECpOGcISpFI=
github.com/dchest/captcha v0.0.0-20170622155422-6a29415a8364/go.mod h1:QGrK8vMWWHQYQ3QU9bw9Y9OPNfxccGzfb41qjvVeXtY=
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3 h1:tkum0XDgfR0jcVVXuTsYv/erY2NnEDqwRojbxR1rBYA=
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
@ -273,6 +275,7 @@ google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -286,6 +289,8 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View file

@ -22,6 +22,8 @@ import (
jwt "github.com/dgrijalva/jwt-go"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
"github.com/dchest/captcha"
)
type handlerFuncWithError func(http.ResponseWriter, *http.Request) error
@ -175,6 +177,10 @@ func NewHandlers(config *config.ConfigT, renderer map[string]renderer.Renderer,
r.Handle("/subscribe", handlers.Login(handlers.Database, handlers.CookieStore, []byte(config.Keys.JWTSigningKey)))
// Captcha
r.Handle("/captcha/{img}", captcha.Server(captcha.StdWidth, captcha.StdHeight))
// Home
r.Handle("/", handlers.JWTCookieMiddleware.Handler(handlers.Recover(handlers.Home())))

View file

@ -44,5 +44,8 @@ var (
"categoryExists": map[string]string{
"it": "Esiste già un partecipante di questa categoria.",
},
"wrongCaptcha": map[string]string{
"it": "Il numero inserito non corrisponde all'immagine.",
},
}
)

View file

@ -9,6 +9,7 @@ import (
"git.andreafazzi.eu/andrea/oef/errors"
"git.andreafazzi.eu/andrea/oef/mail"
"git.andreafazzi.eu/andrea/oef/renderer"
"github.com/dchest/captcha"
"github.com/jinzhu/gorm"
)
@ -63,6 +64,9 @@ type School struct {
SelectedRegion map[uint]string `gorm:"-"`
AllRegions []*Region `gorm:"-"`
CaptchaID string `gorm:"-",schema:"-"`
CaptchaSolution string `gorm:"-",schema:"-"`
mailSender *mail.MailSender
}
@ -175,6 +179,11 @@ func (model *School) Create(db *Database, args map[string]string, w http.Respons
return school, nil
} else {
if isSubscriber(r) {
if !captcha.VerifyString(r.FormValue("CaptchaID"), r.FormValue("CaptchaSolution")) {
return nil, errors.WrongCaptcha
}
}
school := new(School)
err := renderer.Decode(school, r)
if err != nil {

View file

@ -12,6 +12,7 @@ import (
"time"
"git.andreafazzi.eu/andrea/oef/i18n"
"github.com/dchest/captcha"
jwt "github.com/dgrijalva/jwt-go"
"github.com/jinzhu/inflection"
yml "gopkg.in/yaml.v2"
@ -26,6 +27,7 @@ const (
var (
funcMap = template.FuncMap{
"genCaptcha": genCaptcha,
"markdown": markdown,
"version": version,
"toInt": toInt,
@ -72,6 +74,10 @@ var (
}
)
func genCaptcha() string {
return captcha.New()
}
func markdown(text string) string {
unsafe := blackfriday.Run([]byte(text))
return string(bluemonday.UGCPolicy().SanitizeBytes(unsafe))

View file

@ -1,5 +1,6 @@
import './style.css'
$(function () {
setInterval(function() {
@ -11,6 +12,12 @@ $(function () {
}
$("#timeleft").html(timeleft)
}, 1000);
$("#reloadCaptcha").on("click",function(eventObject) {
image = eventObject.currentTarget;
setSrcQuery(document.getElementById('image'), "reload=" + (new Date()).getTime());
});
$("#myInput").on("keyup", function(eventObject) {

View file

@ -1,4 +1,4 @@
{{ define "content" }}
{{$options := `title: "Errore nella creazione/aggiornamento di un partecipante"`}}
{{$options := `title: "Errore durante l'iscrizione della scuola"`}}
{{template "error" dict "options" ($options|yaml) "data" .Data}}
{{end}}

View file

@ -0,0 +1,4 @@
{{ define "content" }}
{{$options := `title: "Errore durante l'iscrizione di una scuola"`}}
{{template "error" dict "options" ($options|yaml) "data" .Data}}
{{end}}

View file

@ -100,8 +100,19 @@
{{template "input" dict "options" ($options|yaml) "value" (.Data|field "ContestDirectorLastname") "update" $update}}
</div>
</div>
{{if .Claims|isSubscriber}}
{{$captcha := genCaptcha}}
<div class="form-group">
<img class="border" id="captcha_img" src="/captcha/{{$captcha}}.png" alt="Immagine CAPTCHA">
<button type="button" onclick="reload()" class="btn btn-outline-success"><i class="fa fa-redo"></i></button>
</div>
<div class="form-group">
{{$options := ` { name: "CaptchaSolution",id: "school_captcha_solution",placeholder: "Inserire i numeri visualizzati nell'immagine",type: "text",required: "true"} `}}
{{template "input" dict "options" ($options|yaml)}}
<input type="hidden" name="CaptchaID" value="{{$captcha}}">
</div>
{{$options := ` { saveTitle: "Invia iscrizione", model: "School" } `}}
{{template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update}}
{{else}}
@ -114,6 +125,22 @@
{{end}}
</form>
<script>
function setSrcQuery(e, q) {
var src = e.src;
var p = src.indexOf('?');
if (p >= 0) {
src = src.substr(0, p);
}
e.src = src + "?" + q
}
function reload() {
setSrcQuery(document.getElementById('captcha_img'), "reload=" + (new Date()).getTime());
return false;
}
</script>
</div>
{{ end }}