From c1bd44b997e55ad98d8ea9ccddb13ec53cc3c95d Mon Sep 17 00:00:00 2001 From: Euan Torano Date: Tue, 7 Mar 2017 18:57:05 +0000 Subject: [PATCH] Adding reCAPTCHA rather than the custom captcha. Signed-off-by: Euan Torano --- captchas.nim | 37 ------------------------------------- forms.tmpl | 6 ++++-- forum.json.example | 4 ++++ forum.nim | 25 ++++++++++++++++++++----- forum.nim.cfg | 2 ++ nimforum.nimble | 2 +- public/captchas/.gitignore | 2 -- utils.nim | 4 ++++ 8 files changed, 35 insertions(+), 47 deletions(-) delete mode 100644 captchas.nim create mode 100644 forum.json.example delete mode 100644 public/captchas/.gitignore diff --git a/captchas.nim b/captchas.nim deleted file mode 100644 index f569f04..0000000 --- a/captchas.nim +++ /dev/null @@ -1,37 +0,0 @@ -# -# -# The Nim Forum -# (c) Copyright 2012 Andreas Rumpf, Dominik Picheta -# Look at license.txt for more info. -# All rights reserved. -# - -import cairo, os, strutils, jester - -proc getCaptchaFilename*(i: int): string {.inline.} = - result = "public/captchas/capture_" & $i & ".png" - -proc getCaptchaUrl*(req: Request, i: int): string = - result = req.makeUri("/captchas/capture_" & $i & ".png", absolute = false) - -proc createCaptcha*(file, text: string) = - var surface = imageSurfaceCreate(FORMAT_ARGB32, int32(10*text.len), int32(10)) - var cr = create(surface) - - selectFontFace(cr, "serif", FONT_SLANT_NORMAL, FONT_WEIGHT_BOLD) - setFontSize(cr, 12.0) - - setSourceRgb(cr, 1.0, 0.5, 0.0) - moveTo(cr, 0.0, 10.0) - showText(cr, repeat('O', text.len)) - - setSourceRgb(cr, 0.0, 0.0, 1.0) - moveTo(cr, 0.0, 10.0) - showText(cr, text) - - destroy(cr) - discard writeToPng(surface, file) - destroy(surface) - -when isMainModule: - createCaptcha("test.png", "1+33") diff --git a/forms.tmpl b/forms.tmpl index 9d62d95..9f6d2a7 100644 --- a/forms.tmpl +++ b/forms.tmpl @@ -249,10 +249,12 @@ ${fieldValid(c, "email", "E-Mail:")} ${textWidget(c, "email", reuseText, maxlength=300)} + #if useCaptcha: - ${fieldValid(c, "antibot", "What is " & antibot(c) & "?")} - ${textWidget(c, "antibot", "", maxlength=4)} + ${fieldValid(c, "g-recaptcha-response", "Captcha:")} + ${captcha.render(includeNoScript=true)} + #end if #if c.errorMsg != "":
diff --git a/forum.json.example b/forum.json.example new file mode 100644 index 0000000..8cf9e86 --- /dev/null +++ b/forum.json.example @@ -0,0 +1,4 @@ +{ + "recaptchaSecretKey": "", + "recaptchaSiteKey": "" +} \ No newline at end of file diff --git a/forum.nim b/forum.nim index 7414144..3222112 100644 --- a/forum.nim +++ b/forum.nim @@ -8,8 +8,8 @@ import os, strutils, times, md5, strtabs, cgi, math, db_sqlite, - captchas, scgi, jester, asyncdispatch, asyncnet, cache, sequtils, - parseutils, utils, random, rst, ranks + scgi, jester, asyncdispatch, asyncnet, cache, sequtils, + parseutils, utils, random, rst, ranks, recaptcha when not defined(windows): import bcrypt # TODO @@ -77,6 +77,8 @@ var db: DbConn isFTSAvailable: bool config: Config + useCaptcha: bool + captcha: ReCaptcha proc init(c: var TForumData) = c.userPass = "" @@ -314,8 +316,16 @@ proc register(c: var TForumData, name, pass, antibot, return setError(c, "new_password", "Invalid password!") # captcha validation: - if not isCaptchaCorrect(c, antibot): - return setError(c, "antibot", "Answer to captcha incorrect!") + if useCaptcha: + var captchaValid: bool = false + try: + captchaValid = waitFor captcha.verify(antibot) + except: + echo("[ERROR] Error checking captcha: " & getCurrentExceptionMsg()) + captchaValid = false + + if not captchaValid: + return setError(c, "antibot", "Answer to captcha incorrect!") # email validation if not ('@' in email and '.' in email): @@ -1123,7 +1133,7 @@ routes: post "/doregister": createTFD() - if c.register(@"name", @"new_password", @"antibot", @"email"): + if c.register(@"name", @"new_password", @"g-recaptcha-response", @"email"): resp genMain(c, "You are now registered. You must now confirm your" & " email address by clicking the link sent to " & @"email", "Registration successful - Nim Forum") @@ -1353,6 +1363,11 @@ when isMainModule: isFTSAvailable = db.getAllRows(sql("SELECT name FROM sqlite_master WHERE " & "type='table' AND name='post_fts'")).len == 1 config = loadConfig() + if len(config.recaptchaSecretKey) > 0 and len(config.recaptchaSiteKey) > 0: + useCaptcha = true + captcha = initReCaptcha(config.recaptchaSecretKey, config.recaptchaSiteKey) + else: + useCaptcha = false var http = true if paramCount() > 0: if paramStr(1) == "scgi": diff --git a/forum.nim.cfg b/forum.nim.cfg index 429dc5b..3af1ac0 100644 --- a/forum.nim.cfg +++ b/forum.nim.cfg @@ -2,3 +2,5 @@ # we need the documentation generator of the compiler: path="$lib/packages/docutils" path="$nim" + +-d:ssl \ No newline at end of file diff --git a/nimforum.nimble b/nimforum.nimble index 3591767..b0cdb09 100644 --- a/nimforum.nimble +++ b/nimforum.nimble @@ -8,4 +8,4 @@ license = "MIT" bin = "forum" [Deps] -Requires: "nim >= 0.14.0, cairo#head, jester#head, bcrypt#head" +Requires: "nim >= 0.14.0, cairo#head, jester#head, bcrypt#head, recaptcha >= 1.0.0" diff --git a/public/captchas/.gitignore b/public/captchas/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/public/captchas/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/utils.nim b/utils.nim index 002ee94..ce48804 100644 --- a/utils.nim +++ b/utils.nim @@ -22,6 +22,8 @@ type smtpUser: string smtpPassword: string mlistAddress: string + recaptchaSecretKey*: string + recaptchaSiteKey*: string var docConfig: StringTableRef @@ -38,6 +40,8 @@ proc loadConfig*(filename = getCurrentDir() / "forum.json"): Config = result.smtpUser = root{"smtpUser"}.getStr("") result.smtpPassword = root{"smtpPassword"}.getStr("") result.mlistAddress = root{"mlistAddress"}.getStr("") + result.recaptchaSecretKey = root{"recaptchaSecretKey"}.getStr("") + result.recaptchaSiteKey = root{"recaptchaSiteKey"}.getStr("") except: echo("[WARNING] Couldn't read config file: ", filename)