Skip to content

Commit 6e67141

Browse files
committed
Added: help API route (#123)
1 parent 1cbbde6 commit 6e67141

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

libreforms_fastapi/app/__init__.py

+51
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
BackgroundTasks,
1414
Depends,
1515
Query,
16+
Form,
1617
)
1718
from fastapi.responses import (
1819
HTMLResponse,
@@ -109,6 +110,7 @@
109110

110111
from libreforms_fastapi.utils.pydantic_models import (
111112
CreateUserRequest,
113+
HelpRequest,
112114
get_form_config,
113115
get_form_names,
114116
)
@@ -1646,6 +1648,55 @@ async def api_auth_login(form_data: Annotated[OAuth2PasswordRequestForm, Depends
16461648

16471649

16481650

1651+
1652+
# This is a help route to submit a help request to the sysadmin
1653+
@app.post("/api/auth/help", dependencies=[Depends(api_key_auth)], response_class=JSONResponse)
1654+
async def api_auth_help(
1655+
request: Request,
1656+
background_tasks: BackgroundTasks,
1657+
help_request: HelpRequest,
1658+
session: SessionLocal = Depends(get_db),
1659+
key: str = Depends(X_API_KEY)
1660+
):
1661+
1662+
if not config.HELP_PAGE_ENABLED or not config.SMTP_ENABLED:
1663+
raise HTTPException(status_code=404)
1664+
1665+
# Get the requesting user details
1666+
user = session.query(User).filter_by(api_key=key).first()
1667+
1668+
if not user:
1669+
raise HTTPException(status_code=404)
1670+
1671+
time_str = datetime.now(config.TIMEZONE).strftime("%Y-%m-%d %H:%M:%S")
1672+
1673+
# We escape and shorten the message contents as needed
1674+
safe_subject = escape(help_request.subject)
1675+
shortened_safe_subject = safe_subject[:50]
1676+
1677+
safe_message = escape(help_request.message)
1678+
safe_category = escape(help_request.category)
1679+
1680+
full_safe_subject = f"[{config.SITE_NAME}][{user.username}][{safe_category}] {shortened_safe_subject}"
1681+
1682+
full_safe_message = f"You are receiving this message because a user has submitted a request for help at {config.DOMAIN}. " \
1683+
f"You can see the request details below.\n\n****\nUser: {user.username}\nEmail: {user.email}\nTime of Submission:" \
1684+
f"{time_str}\nCategory: {safe_category}\nSubject: {safe_subject}\nMessage: {safe_message}\n****\n\nYou may reply " \
1685+
f"directly to the user who submitted this request by replying to this email."
1686+
1687+
background_tasks.add_task(
1688+
mailer.send_mail,
1689+
subject=full_safe_subject,
1690+
content=full_safe_message,
1691+
to_address=config.HELP_EMAIL,
1692+
reply_to_addr=user.email
1693+
)
1694+
1695+
return JSONResponse(
1696+
status_code=202,
1697+
content={"status": "success"},
1698+
)
1699+
16491700
##########################
16501701
### API Routes - Admin
16511702
##########################

libreforms_fastapi/utils/pydantic_models.py

+5
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,8 @@ class Config:
292292

293293
return model
294294

295+
class HelpRequest(BaseModel):
296+
"""A quick and dirty pydantic model for help request data"""
297+
subject: str
298+
category: str
299+
message: str

libreforms_fastapi/utils/smtp.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import smtplib
33
from email.mime.text import MIMEText
44
from email.mime.multipart import MIMEMultipart
5+
from email.header import Header
56

67
class Mailer():
78
def __init__(self, mail_server=None, port=None,
@@ -38,10 +39,9 @@ def send_mail(self, subject=None, content=None, to_address=None, cc_address_list
3839
with smtplib.SMTP(self.mail_server,self.port) as server:
3940

4041
msg = MIMEMultipart()
41-
msg['Subject'] = subject
42+
msg['Subject'] = Header(subject, 'utf-8')
4243
msg['From'] = self.from_address
4344
msg['To'] = to_address
44-
# print(cc_address_list)
4545
msg['Cc'] = ", ".join(cc_address_list) if cc_conditions else None
4646
msg['Reply-To'] = reply_to_addr if reply_to_addr else self.from_address
4747

0 commit comments

Comments
 (0)