Feat: Home and Contact pages setup with Altcha bot protection and saving to database using alterntive layout.
This commit is contained in:
0
forms/project_hub/__init__.py
Normal file
0
forms/project_hub/__init__.py
Normal file
100
forms/project_hub/contact.py
Normal file
100
forms/project_hub/contact.py
Normal file
@@ -0,0 +1,100 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: Backend
|
||||
Feature: Contact Us Form
|
||||
|
||||
Description:
|
||||
Defines Flask-WTF form for handling user input on Contact Us page.
|
||||
"""
|
||||
|
||||
# IMPORTS
|
||||
# internal
|
||||
from business_objects.base import Base
|
||||
from business_objects.project_hub.contact_form import Contact_Form
|
||||
# from models.model_view_store import Model_View_Store # circular
|
||||
from models.model_view_base import Model_View_Base
|
||||
from forms.base import Form_Base
|
||||
# external
|
||||
from flask import Flask, render_template, request, flash, redirect, url_for, current_app
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, TextAreaField, SubmitField, HiddenField, BooleanField, Field, EmailField
|
||||
from wtforms.validators import DataRequired, Email, ValidationError
|
||||
import markupsafe
|
||||
from flask_wtf.recaptcha import RecaptchaField
|
||||
from abc import ABCMeta, abstractmethod
|
||||
import json
|
||||
from altcha import verify_solution
|
||||
import base64
|
||||
|
||||
class ALTCHAValidator:
|
||||
def __init__(self, message=None):
|
||||
self.message = message or 'ALTCHA verification failed'
|
||||
|
||||
def __call__(self, form, field):
|
||||
altcha_data = field.data
|
||||
|
||||
if not altcha_data:
|
||||
raise ValidationError(self.message)
|
||||
|
||||
try:
|
||||
# The data is base64 encoded JSON
|
||||
try:
|
||||
# First try to decode it as JSON directly (if it's not base64 encoded)
|
||||
altcha_payload = json.loads(altcha_data)
|
||||
except json.JSONDecodeError:
|
||||
# If direct JSON decoding fails, try base64 decoding first
|
||||
decoded_data = base64.b64decode(altcha_data).decode('utf-8')
|
||||
altcha_payload = json.loads(decoded_data)
|
||||
|
||||
ok, err = verify_solution(altcha_payload, current_app.app_config.ALTCHA_SECRET_KEY, check_expires=True)
|
||||
|
||||
if err or not ok:
|
||||
raise ValidationError(self.message + ': ' + (err or 'Invalid solution'))
|
||||
|
||||
except Exception as e:
|
||||
raise ValidationError(f'Invalid ALTCHA data: {str(e)}')
|
||||
|
||||
class ALTCHAField(Field):
|
||||
def __init__(self, label='', validators=None, **kwargs):
|
||||
validators = validators or []
|
||||
validators.append(ALTCHAValidator())
|
||||
|
||||
super(ALTCHAField, self).__init__(label, validators, **kwargs)
|
||||
|
||||
def __call__(self, **kwargs):
|
||||
html = f"""
|
||||
<altcha-widget
|
||||
challengeurl="/get-challenge"
|
||||
auto="onload"
|
||||
id="{self.id}"
|
||||
name="{self.name}">
|
||||
</altcha-widget>
|
||||
"""
|
||||
return markupsafe.Markup(html)
|
||||
|
||||
|
||||
class Form_Contact(FlaskForm):
|
||||
email = EmailField('Email')
|
||||
contact_name = StringField('Name')
|
||||
company_name = StringField('Company')
|
||||
message = TextAreaField('Message')
|
||||
receive_marketing = BooleanField('I would like to receive marketing emails.')
|
||||
# recaptcha = RecaptchaField()
|
||||
# altcha = HiddenField('ALTCHA') # , validators=[validate_altcha]
|
||||
altcha = ALTCHAField('Verify you are human')
|
||||
submit = SubmitField('Send Message')
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
Base.FLAG_EMAIL: self.email.data
|
||||
, Contact_Form.FLAG_NAME_CONTACT: self.contact_name.data
|
||||
, Contact_Form.FLAG_NAME_COMPANY: self.company_name.data
|
||||
, Contact_Form.FLAG_MESSAGE: self.message.data
|
||||
, Contact_Form.FLAG_RECEIVE_MARKETING_COMMUNICATIONS: self.receive_marketing.data
|
||||
, Contact_Form.FLAG_ALTCHA: self.altcha.data
|
||||
, Base.FLAG_ACTIVE: True
|
||||
, Base.FLAG_CREATED_ON: None
|
||||
}
|
||||
Reference in New Issue
Block a user