Skip to content

Commit

Permalink
feat: create OTP class based on SMTP SSL
Browse files Browse the repository at this point in the history
  • Loading branch information
R1D3R175 committed Nov 13, 2023
1 parent cd6a57a commit b10600e
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 1 deletion.
3 changes: 2 additions & 1 deletion module/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
REPORT,
HELP,
HELP_CMD_TEXT,
START_CMD_TEXT
START_CMD_TEXT,
MAIL_TEMPLATE
)
8 changes: 8 additions & 0 deletions module/data/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,11 @@

REPORT = "Segnalazioni Rappresentanti 📬"
HELP = "Help ❔"

MAIL_TEMPLATE = (
"Ciao!\n\n"
"Se stai ricevendo questo messaggio vuol dire che ti stai registrando a FinderUniCT-Bot. "
"Se non sei stato tu, ignora semplicemente questo messaggio.\n"
"Il tuo codice OTP e': {otp}\n\n"
"Il team di FinderUniCT-Bot!"
)
95 changes: 95 additions & 0 deletions module/otp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
"""
OTP module.
"""
import os
import random
import smtplib
from email.mime.text import MIMEText

from module.data import MAIL_TEMPLATE

#: Define the following in settings.yaml
HOST = 'HOST'
USER = "USER"
PASSWORD = "PASSWORD"

class OTPException(Exception):
pass

class OTPConnectionFailed(OTPException):
pass

class OTPLoginFailed(OTPException):
pass

class OTPNotAuthenticated(OTPException):
pass

class OTPCodeNotSent(OTPException):
pass

class OTPSender:
"""
OTP sender class.
Attributes:
authenticated (bool): True if the user is authenticated, False otherwise.
Methods:
login() -> None:
Logs in to the SMTP server. Modifies the authenticated attribute.
send(to: str) -> str | None:
Sends a randomly generated OTP to the specified email address.
Returns the OTP sent to the specified email address.
"""
def __init__(self):
try:
self.__server = smtplib.SMTP_SSL(HOST, smtplib.SMTP_SSL_PORT)
except Exception as e:
raise OTPConnectionFailed('Connection failed.') from e

self.authenticated = False
self.login()

def login(self) -> None:
"""
Logs in to the SMTP server.
Returns:
None: check self.authenticated for login status.
"""
if self.authenticated:
return

try:
self.__server.login(USER, PASSWORD)
self.authenticated = True
except Exception as e:
raise OTPLoginFailed('Login failed.') from e

def send(self, to: str) -> str:
"""
Sends a randomly generated OTP to the specified email address.
Args:
to (str): The email address of the recipient.
Returns:
str: The OTP sent to the specified email address.
"""
if not self.authenticated:
raise OTPNotAuthenticated('Not authenticated.')

random.seed(os.urandom(64))
otp = str(random.randint(100000, 999999))

message = MIMEText(MAIL_TEMPLATE.format(otp=otp))
message['From'] = USER
message['To'] = to
message['Subject'] = "FinderUniCT-Bot - Codice OTP"

try:
self.__server.send_message(message)
return otp
except Exception as e:
raise OTPCodeNotSent('OTP code not sent.') from e

0 comments on commit b10600e

Please sign in to comment.