captcha: add captcha to contact page (fixes #482)

This commit is contained in:
justcool393 2023-02-09 08:41:15 -08:00 committed by GitHub
parent 004adcd5fe
commit 4cecdef35a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 37 deletions

14
files/helpers/captcha.py Normal file
View file

@ -0,0 +1,14 @@
from typing import Final
import requests
HCAPTCHA_URL: Final[str] = "https://hcaptcha.com/siteverify"
def validate_captcha(secret:str, sitekey: str, token: str):
if not sitekey: return True
if not token: return False
data = {"secret": secret,
"response": token,
"sitekey": sitekey
}
req = requests.post(HCAPTCHA_URL, data=data, timeout=5)
return bool(req.json()["success"])

View file

@ -2,12 +2,11 @@ from urllib.parse import urlencode
from files.mail import * from files.mail import *
from files.__main__ import app, limiter from files.__main__ import app, limiter
from files.helpers.const import * from files.helpers.const import *
import requests from files.helpers.captcha import validate_captcha
@app.get("/login") @app.get("/login")
@auth_desired @auth_desired
def login_get(v): def login_get(v):
redir = request.values.get("redirect") redir = request.values.get("redirect")
if redir: if redir:
redir = redir.replace("/logged_out", "").strip() redir = redir.replace("/logged_out", "").strip()
@ -289,21 +288,11 @@ def sign_up_post(v):
if existing_account: if existing_account:
return signup_error("An account with that username already exists.") return signup_error("An account with that username already exists.")
if app.config.get("HCAPTCHA_SITEKEY"): if not validate_captcha(app.config.get("HCAPTCHA_SECRET", ""),
token = request.values.get("h-captcha-response") app.config.get("HCAPTCHA_SITEKEY", ""),
if not token: request.values.get("h-captcha-response", "")):
return signup_error("Unable to verify captcha [1].") return signup_error("Unable to verify CAPTCHA")
data = {"secret": app.config["HCAPTCHA_SECRET"],
"response": token,
"sitekey": app.config["HCAPTCHA_SITEKEY"]}
url = "https://hcaptcha.com/siteverify"
x = requests.post(url, data=data, timeout=5)
if not x.json()["success"]:
return signup_error("Unable to verify captcha [2].")
session.pop("signup_token") session.pop("signup_token")

View file

@ -2,6 +2,7 @@ from files.mail import *
from files.__main__ import app, limiter, mail from files.__main__ import app, limiter, mail
from files.helpers.alerts import * from files.helpers.alerts import *
from files.helpers.const import * from files.helpers.const import *
from files.helpers.captcha import validate_captcha
from files.classes.award import AWARDS from files.classes.award import AWARDS
from sqlalchemy import func from sqlalchemy import func
from os import path from os import path
@ -280,13 +281,17 @@ def api(v):
@app.get("/media") @app.get("/media")
@auth_desired @auth_desired
def contact(v): def contact(v):
return render_template("contact.html", v=v,
return render_template("contact.html", v=v) hcaptcha=app.config.get("HCAPTCHA_SITEKEY", ""))
@app.post("/send_admin") @app.post("/send_admin")
@limiter.limit("1/second;2/minute;6/hour;10/day") @limiter.limit("1/second;2/minute;6/hour;10/day")
@auth_desired @auth_desired
def submit_contact(v): def submit_contact(v: Optional[User]):
if not v and not validate_captcha(app.config.get("HCAPTCHA_SECRET", ""),
app.config.get("HCAPTCHA_SITEKEY", ""),
request.values.get("h-captcha-response", "")):
abort(403, "CAPTCHA provided was not correct. Please try it again")
body = request.values.get("message") body = request.values.get("message")
email = request.values.get("email") email = request.values.get("email")
if not body: abort(400) if not body: abort(400)

View file

@ -1,12 +1,8 @@
{% extends "default.html" %} {% extends "default.html" %}
{% block title %} {% block title %}
<title>{{SITE_TITLE}} - Contact</title> <title>{{SITE_TITLE}} - Contact</title>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{% if msg %} {% if msg %}
<div class="alert alert-success alert-dismissible fade show my-3" role="alert"> <div class="alert alert-success alert-dismissible fade show my-3" role="alert">
<i class="fas fa-check-circle my-auto" aria-hidden="true"></i> <i class="fas fa-check-circle my-auto" aria-hidden="true"></i>
@ -18,7 +14,7 @@
</button> </button>
</div> </div>
{% endif %} {% endif %}
<section id="contact">
<h1 class="article-title">Contact {{SITE_TITLE}} Admins</h1> <h1 class="article-title">Contact {{SITE_TITLE}} Admins</h1>
<p>Use this form to contact {{SITE_TITLE}} Admins.</p> <p>Use this form to contact {{SITE_TITLE}} Admins.</p>
@ -34,18 +30,16 @@
<div id="filename"><i class="far fa-image"></i></div> <div id="filename"><i class="far fa-image"></i></div>
<input autocomplete="off" id="file-upload" type="file" name="file" accept="image/*, video/*" {% if request.headers.get('cf-ipcountry')=="T1" %}disabled{% endif %} onchange="changename('filename','file-upload')" hidden> <input autocomplete="off" id="file-upload" type="file" name="file" accept="image/*, video/*" {% if request.headers.get('cf-ipcountry')=="T1" %}disabled{% endif %} onchange="changename('filename','file-upload')" hidden>
</label> </label>
{% if not v and hcaptcha %}
<div class="h-captcha" data-sitekey="{{hcaptcha}}"></div>
{% endif %}
<input type="submit" value="Submit" class="btn btn-primary mt-3"> <input type="submit" value="Submit" class="btn btn-primary mt-3">
</form> </form>
</section>
<pre> <section id="canary">
<p>If you can see this line, we haven't been contacted by any law enforcement or governmental organizations in 2022 yet.</p>
</section>
</pre> {% if hcaptcha %}
<script src="{{ 'js/hcaptcha.js' | asset }}"></script>
<p>If you can see this line, we haven't been contacted by any law enforcement or governmental organizations in 2022 yet.</p> {% endif %}
<pre>
</pre>
{% endblock %} {% endblock %}