mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-20 20:52:33 +02:00
61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
package captcha
|
|
|
|
import (
|
|
"net/http"
|
|
"text/template"
|
|
|
|
"github.com/yusing/go-proxy/internal/auth"
|
|
"github.com/yusing/go-proxy/internal/logging"
|
|
"github.com/yusing/go-proxy/internal/net/gphttp"
|
|
|
|
_ "embed"
|
|
)
|
|
|
|
const cookieName = "godoxy_captcha_session"
|
|
|
|
//go:embed captcha.html
|
|
var captchaPageHTML string
|
|
var captchaPage = template.Must(template.New("captcha").Parse(captchaPageHTML))
|
|
|
|
func PreRequest(p Provider, w http.ResponseWriter, r *http.Request) (proceed bool) {
|
|
// check session
|
|
sessionID, err := r.Cookie(cookieName)
|
|
if err == nil {
|
|
session, ok := CaptchaSessions.Load(sessionID.Value)
|
|
if ok {
|
|
if session.expired() {
|
|
CaptchaSessions.Delete(sessionID.Value)
|
|
} else {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
|
|
if !gphttp.GetAccept(r.Header).AcceptHTML() {
|
|
gphttp.Forbidden(w, "Captcha is required")
|
|
return false
|
|
}
|
|
|
|
if r.Method == http.MethodPost {
|
|
err := p.Verify(r)
|
|
if err == nil {
|
|
session := newCaptchaSession(p)
|
|
CaptchaSessions.Store(session.ID, session)
|
|
auth.SetTokenCookie(w, r, cookieName, session.ID, p.SessionExpiry())
|
|
http.Redirect(w, r, r.URL.Path, http.StatusFound)
|
|
return false
|
|
}
|
|
gphttp.Unauthorized(w, err.Error())
|
|
return false
|
|
}
|
|
|
|
// captcha challenge
|
|
err = captchaPage.Execute(w, map[string]any{
|
|
"ScriptHTML": p.ScriptHTML(),
|
|
"FormHTML": p.FormHTML(),
|
|
})
|
|
if err != nil {
|
|
logging.Error().Err(err).Msg("failed to execute captcha page")
|
|
}
|
|
return false
|
|
}
|