88 lines
3.1 KiB
Python
88 lines
3.1 KiB
Python
"""
|
|
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.store.product_category import Filters_Product_Category # circular
|
|
# 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
|
|
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.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 = StringField('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('Verification')
|
|
submit = SubmitField('Send Message')
|