add captcha back

( thanks dixropot / pixrobot8 / sininnekissa for constant spam )

Signed-off-by: Ari Archer <ari@ari.lt>
This commit is contained in:
Arija A. 2024-06-11 19:29:02 +03:00
parent 4adaeb393a
commit b1eab076db
6 changed files with 45 additions and 1 deletions

View file

@ -9,3 +9,4 @@ MarkupSafe
bleach bleach
web-mini web-mini
flask-limiter flask-limiter
flask-ishuman

View file

@ -53,6 +53,10 @@ def create_app(name: str) -> flask.Flask:
app.config["USE_SESSION_FOR_NEXT"] = True app.config["USE_SESSION_FOR_NEXT"] = True
from .c import c
c.init_app(app)
from .models import Counter, db from .models import Counter, db
with app.app_context(): with app.app_context():

7
src/aw/c.py Normal file
View file

@ -0,0 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""captcha"""
from flask_ishuman import IsHuman
c: IsHuman = IsHuman()

View file

@ -11,6 +11,7 @@ import validators
from werkzeug.wrappers import Response from werkzeug.wrappers import Response
from . import email, models, util from . import email, models, util
from .c import c
from .limiter import limiter from .limiter import limiter
from .routing import Bp from .routing import Bp
@ -130,10 +131,13 @@ def delete(comment_id: int, token: str):
def comment(): def comment():
"""publish a comment""" """publish a comment"""
for field in "name", "email", "comment": for field in "name", "email", "comment", "code":
if field not in flask.request.form: if field not in flask.request.form:
flask.abort(400) flask.abort(400)
if not c.verify(flask.request.form["code"]): # type: ignore
flask.abort(403)
if not validators.email(flask.request.form["email"]): if not validators.email(flask.request.form["email"]):
flask.abort(400) flask.abort(400)
@ -308,6 +312,12 @@ def badge_yellow() -> Response:
return r return r
@views.get("/captcha.png")
def captcha() -> Response:
"""CAPTCHA"""
return flask.Response(c.new().rawpng(), mimetype="image/png")
@views.get("/btc") @views.get("/btc")
def btc() -> Response: def btc() -> Response:
"""Bitcoin address""" """Bitcoin address"""

View file

@ -108,6 +108,18 @@ form > button {
width: 100%; width: 100%;
} }
.captcha {
display: -ms-grid;
display: grid;
place-items: center;
margin: 0.5em;
}
.captcha > img {
display: block;
cursor: pointer;
}
@-webkit-keyframes grow { @-webkit-keyframes grow {
from { from {
-webkit-transform: scaleY(0); -webkit-transform: scaleY(0);

View file

@ -435,6 +435,16 @@
<textarea required type="text" id="comment" name="comment" placeholder="Hello! I like your website - &lt;https://ari.lt/&gt;."></textarea> <textarea required type="text" id="comment" name="comment" placeholder="Hello! I like your website - &lt;https://ari.lt/&gt;."></textarea>
</div> </div>
<div class="captcha">
<img loading="lazy" width="240px" height="90" src="{{ url_for("views.captcha") }}?new" onclick="this.src=this.src+Math.floor(1000*Math.random())" alt="An image CAPTCHA" />
<i>Click the image above to reload and get a new CAPTCHA.</i>
</div>
<div class="form-group">
<label for="captcha">CAPTCHA:</label>
<input required type="text" id="code" name="code" placeholder="Enter the CAPTCHA code above." />
</div>
<div class="form-group"> <div class="form-group">
<label for="agree">Email Policy Agreement:</label> <label for="agree">Email Policy Agreement:</label>
<input required type="checkbox" id="agree" name="agree" /> <input required type="checkbox" id="agree" name="agree" />