Skip to content

Commit

Permalink
Add sms sender
Browse files Browse the repository at this point in the history
  • Loading branch information
flavien-hugs committed Aug 16, 2024
1 parent adeb05e commit 3555989
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 10 deletions.
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,9 @@ JWT_SECRET_KEY=<ChangeMe>
JWT_ALGORITHM=<ChangeMe>
ACCESS_TOKEN_EXPIRE_MINUTES=<ChangeMe>
REFRESH_TOKEN_EXPIRE_MINUTES=<ChangeMe>

# Config SMS
SMS_SENDER=<ChangeMe>
SMS_USERNAME=<ChangeMe>
SMS_ENDPOINT=<ChangeMe>
SMS_TOKEN=<ChangeMe>
4 changes: 3 additions & 1 deletion src/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from .database import shutdown_db, startup_db # noqa: F401
from .email import get_email_settings # noqa: F401
from .settings import get_settings # noqa: F401
from .sms import get_sms_config # noqa: F401
from .swaggers import enable_endpoint # noqa: F401
from .token import get_token_settings # noqa: F401

settings = get_settings()
sms_config = get_sms_config()
jwt_settings = get_token_settings()
email_settings = get_email_settings()
enable_endpoint = enable_endpoint()

__all__ = ["settings", "startup_db", "shutdown_db", "email_settings", "jwt_settings", "enable_endpoint"]
__all__ = ["settings", "startup_db", "shutdown_db", "email_settings", "jwt_settings", "sms_config", "enable_endpoint"]
1 change: 1 addition & 0 deletions src/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class AuthBaseConfig(BaseSettings):
APP_ACCESS_LOG: bool = Field(default=True, alias="APP_ACCESS_LOG")
APP_DEFAULT_PORT: PositiveInt = Field(default=9077, alias="APP_DEFAULT_PORT")
PASSWORD_MIN_LENGTH: PositiveInt = Field(default=6, alias="PASSWORD_MIN_LENGTH")
ENABLE_OTP_CODE: bool = Field(default=True, alias="ENABLE_OTP_CODE")

# USER MODEL NAME
USER_MODEL_NAME: str = Field(..., alias="USER_MODEL_NAME")
Expand Down
16 changes: 16 additions & 0 deletions src/config/sms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from functools import lru_cache

from pydantic import Field
from pydantic_settings import BaseSettings


class SmsBaseConfig(BaseSettings):
SMS_ENDPOINT: str = Field(..., alias="SMS_ENDPOINT")
SMS_USERNAME: str = Field(..., alias="SMS_USERNAME")
SMS_SENDER: str = Field(..., alias="SMS_SENDER")
SMS_TOKEN: str = Field(..., alias="SMS_TOKEN")


@lru_cache
def get_sms_config() -> SmsBaseConfig:
return SmsBaseConfig()
10 changes: 5 additions & 5 deletions src/services/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
template_env = Environment(loader=template_loader, autoescape=select_autoescape(["html", "txt"]))


async def login(payload: LoginUser) -> JSONResponse:
async def login(background: BackgroundTasks, payload: LoginUser) -> JSONResponse:
if (user := await User.find_one({"email": payload.email.lower()})) is None:
raise CustomHTTException(
code_error=UserErrorCode.USER_NOT_FOUND,
Expand Down Expand Up @@ -130,7 +130,7 @@ async def request_password_reset(background: BackgroundTasks, email: EmailStr) -
)

mail_service.send_email_background(
background_tasks=background,
background_task=background,
receiver_email=user.email.lower(),
subject=f"{email_settings.SMTP_APP_NAME}: Reset your password",
body=rendered_html,
Expand Down Expand Up @@ -166,7 +166,7 @@ async def reset_password_completed(
rendered_html = template.render(login_link=login_link, service_name=email_settings.SMTP_APP_NAME)

mail_service.send_email_background(
background_tasks=background,
background_task=background,
receiver_email=user.email.lower(),
subject=f"{email_settings.SMTP_APP_NAME}: Password reset completed",
body=rendered_html,
Expand Down Expand Up @@ -198,7 +198,7 @@ async def request_create_account_with_send_email(background: BackgroundTasks, em
)

mail_service.send_email_background(
background_tasks=background,
background_task=background,
receiver_email=email.lower(),
subject=f"{email_settings.SMTP_APP_NAME}: Please confirm your e-mail address to activate your account",
body=rendered_html,
Expand Down Expand Up @@ -231,7 +231,7 @@ async def create_new_account_with_send_email(
rendered_html = template.render(service_name=email_settings.SMTP_APP_NAME, login_link=settings.FRONTEND_PATH_LOGIN)

mail_service.send_email_background(
background_tasks=background,
background_task=background,
receiver_email=addr_email.lower(),
subject=f"{email_settings.SMTP_APP_NAME}: You welcome",
body=rendered_html,
Expand Down
6 changes: 4 additions & 2 deletions src/shared/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from .send_email import email_sender_handler # noqa: F401
from .send_email import email_sender_handler
from .send_sms import sms_sender_handler
from .utils import TokenBlacklistHandler

mail_service = email_sender_handler()
sms_service = sms_sender_handler()
blacklist_token = TokenBlacklistHandler()

__all__ = ["mail_service", "blacklist_token"]
__all__ = ["mail_service", "sms_service", "blacklist_token"]
4 changes: 2 additions & 2 deletions src/shared/send_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ async def send_email(self, receiver_email: list[EmailStr], subject: str, body: s
raise

def send_email_background(
self, background_tasks: BackgroundTasks, receiver_email: list[EmailStr], subject: str, body: str
self, background_task: BackgroundTasks, receiver_email: list[EmailStr], subject: str, body: str
):
background_tasks.add_task(self.send_email, receiver_email, subject, body)
background_task.add_task(self.send_email, receiver_email, subject, body)
logger.info("Email scheduled to be sent in the background.")


Expand Down
50 changes: 50 additions & 0 deletions src/shared/send_sms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import httpx
import logging
from starlette.background import BackgroundTasks

from src.config import sms_config


logging.basicConfig(format="%(message)s", level=logging.INFO)
_log = logging.getLogger(__name__)


class SendSMSHandler:

def __init__(self, url: str, username: str, token: str, sender: str):
self._url = url
self._token = token
self._sender = sender
self._username = username

async def send_sms(self, recipient: str, message: str):

async with httpx.AsyncClient() as client:
payload = {
"Username": self._username,
"Token": self._token,
"Dest": recipient,
"Sms": message,
"Sender": self._sender,
}
response = await client.post(self._url, json=payload)
try:
response.raise_for_status()
except httpx.HTTPStatusError as exc:
_log.error(f"Error response {exc.response.status_code} while requesting {exc.request.url!r}.")
raise

return response.text

def send_sms_background(self, background_task: BackgroundTasks, recipient: str, message: str):
background_task.add_task(self.send_sms, recipient, message)
_log.info("Email scheduled to be sent in the background.")


def sms_sender_handler() -> SendSMSHandler:
return SendSMSHandler(
url=sms_config.SMS_ENDPOINT,
username=sms_config.SMS_USERNAME,
token=sms_config.SMS_TOKEN,
sender=sms_config.SMS_SENDER,
)
6 changes: 6 additions & 0 deletions tests/.test.env
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,9 @@ ENABLE=1
DISABLE=0
SHOW_CREATE_NEW_ACCOUNT=${DISABLE}
SHOW_REQUEST_CREATE_ACCOUNT=${DISABLE}

# CONFIG ACIM SMS
SMS_SENDER=auth
SMS_USERNAME=authApi
SMS_ENDPOINT=https://localhost:8443/api/addonesms
SMS_TOKEN=$2a$10$AFCIjajhEd

0 comments on commit 3555989

Please sign in to comment.