gold eggs backend
Some checks failed
Build and Push to Docker Hub / build-test-push (push) Failing after 1m55s
Some checks failed
Build and Push to Docker Hub / build-test-push (push) Failing after 1m55s
This commit is contained in:
4
core/services/__init__.py
Normal file
4
core/services/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from .sms import * # noqa
|
||||
from .sms_service import * # noqa
|
||||
from .base_service import * # noqa
|
||||
from .user import * # noqa
|
||||
6
core/services/base_service.py
Executable file
6
core/services/base_service.py
Executable file
@@ -0,0 +1,6 @@
|
||||
class BaseService:
|
||||
"""
|
||||
Test Service Base
|
||||
"""
|
||||
|
||||
pass
|
||||
66
core/services/sms.py
Executable file
66
core/services/sms.py
Executable file
@@ -0,0 +1,66 @@
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
from core import exceptions
|
||||
from core.http import models
|
||||
from core.http import tasks
|
||||
|
||||
|
||||
class SmsService:
|
||||
@staticmethod
|
||||
def send_confirm(phone):
|
||||
# TODO: Deploy this change when deploying -> code = random.randint(1000, 9999) # noqa
|
||||
code = 1111
|
||||
|
||||
sms_confirm, status = models.SmsConfirm.objects.get_or_create(
|
||||
phone=phone, defaults={"code": code}
|
||||
)
|
||||
|
||||
sms_confirm.sync_limits()
|
||||
|
||||
if sms_confirm.resend_unlock_time is not None:
|
||||
expired = sms_confirm.interval(sms_confirm.resend_unlock_time)
|
||||
exception = exceptions.SmsException(
|
||||
f"Resend blocked, try again in {expired}", expired=expired
|
||||
)
|
||||
raise exception
|
||||
|
||||
sms_confirm.code = code
|
||||
sms_confirm.try_count = 0
|
||||
sms_confirm.resend_count += 1
|
||||
sms_confirm.phone = phone
|
||||
sms_confirm.expired_time = datetime.now() + timedelta(
|
||||
seconds=models.SmsConfirm.SMS_EXPIRY_SECONDS
|
||||
) # noqa
|
||||
sms_confirm.resend_unlock_time = datetime.now() + timedelta(
|
||||
seconds=models.SmsConfirm.SMS_EXPIRY_SECONDS
|
||||
) # noqa
|
||||
sms_confirm.save()
|
||||
|
||||
tasks.SendConfirm.delay(phone, code)
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def check_confirm(phone, code):
|
||||
sms_confirm = models.SmsConfirm.objects.filter(phone=phone).first()
|
||||
|
||||
if sms_confirm is None:
|
||||
raise exceptions.SmsException("Invalid confirmation code")
|
||||
|
||||
sms_confirm.sync_limits()
|
||||
|
||||
if sms_confirm.is_expired():
|
||||
raise exceptions.SmsException("Time for confirmation has expired")
|
||||
|
||||
if sms_confirm.is_block():
|
||||
expired = sms_confirm.interval(sms_confirm.unlock_time)
|
||||
raise exceptions.SmsException(f"Try again in {expired}")
|
||||
|
||||
if sms_confirm.code == code:
|
||||
sms_confirm.delete()
|
||||
return True
|
||||
|
||||
sms_confirm.try_count += 1
|
||||
sms_confirm.save()
|
||||
|
||||
raise exceptions.SmsException("Invalid confirmation code")
|
||||
135
core/services/sms_service.py
Executable file
135
core/services/sms_service.py
Executable file
@@ -0,0 +1,135 @@
|
||||
import requests
|
||||
|
||||
from common.env import env
|
||||
|
||||
|
||||
class SendService:
|
||||
GET = "GET"
|
||||
POST = "POST"
|
||||
PATCH = "PATCH"
|
||||
CONTACT = "contact"
|
||||
|
||||
def __init__(
|
||||
self, api_url=None, email=None, password=None, callback_url=None
|
||||
):
|
||||
self.api_url = api_url or env("SMS_API_URL")
|
||||
self.email = email or env("SMS_LOGIN")
|
||||
self.password = password or env("SMS_PASSWORD")
|
||||
self.callback_url = callback_url
|
||||
self.headers = {}
|
||||
|
||||
self.methods = {
|
||||
"auth_user": "auth/user",
|
||||
"auth_login": "auth/login",
|
||||
"auth_refresh": "auth/refresh",
|
||||
"send_message": "message/sms/send",
|
||||
}
|
||||
|
||||
def request(self, api_path, data=None, method=None, headers=None):
|
||||
incoming_data = {"status": "error"}
|
||||
|
||||
try:
|
||||
response = requests.request(
|
||||
method,
|
||||
f"{self.api_url}/{api_path}",
|
||||
data=data,
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
if api_path == self.methods["auth_refresh"]:
|
||||
if response.status_code == 200:
|
||||
incoming_data["status"] = "success"
|
||||
else:
|
||||
incoming_data = response.json()
|
||||
except requests.RequestException as error:
|
||||
raise Exception(str(error))
|
||||
|
||||
return incoming_data
|
||||
|
||||
def auth(self):
|
||||
data = {"email": self.email, "password": self.password}
|
||||
|
||||
return self.request(
|
||||
self.methods["auth_login"], data=data, method=self.POST
|
||||
)
|
||||
|
||||
def refresh_token(self):
|
||||
token = self.auth()["data"]["token"]
|
||||
self.headers["Authorization"] = "Bearer " + token
|
||||
|
||||
context = {
|
||||
"headers": self.headers,
|
||||
"method": self.PATCH,
|
||||
"api_path": self.methods["auth_refresh"],
|
||||
}
|
||||
|
||||
return self.request(
|
||||
context["api_path"],
|
||||
method=context["method"],
|
||||
headers=context["headers"],
|
||||
)
|
||||
|
||||
def get_my_user_info(self):
|
||||
token = self.auth()["data"]["token"]
|
||||
self.headers["Authorization"] = "Bearer " + token
|
||||
|
||||
data = {
|
||||
"headers": self.headers,
|
||||
"method": self.GET,
|
||||
"api_path": self.methods["auth_user"],
|
||||
}
|
||||
|
||||
return self.request(
|
||||
data["api_path"], method=data["method"], headers=data["headers"]
|
||||
)
|
||||
|
||||
def add_sms_contact(self, first_name, phone_number, group):
|
||||
token = self.auth()["data"]["token"]
|
||||
self.headers["Authorization"] = "Bearer " + token
|
||||
|
||||
data = {
|
||||
"name": first_name,
|
||||
"email": self.email,
|
||||
"group": group,
|
||||
"mobile_phone": phone_number,
|
||||
}
|
||||
|
||||
context = {
|
||||
"headers": self.headers,
|
||||
"method": self.POST,
|
||||
"api_path": self.CONTACT,
|
||||
"data": data,
|
||||
}
|
||||
|
||||
return self.request(
|
||||
context["api_path"],
|
||||
data=context["data"],
|
||||
method=context["method"],
|
||||
headers=context["headers"],
|
||||
)
|
||||
|
||||
def send_sms(self, phone_number, message):
|
||||
token = self.auth()["data"]["token"]
|
||||
self.headers["Authorization"] = "Bearer " + token
|
||||
|
||||
data = {
|
||||
"from": 4546,
|
||||
"mobile_phone": phone_number,
|
||||
"callback_url": self.callback_url,
|
||||
"message": message,
|
||||
}
|
||||
|
||||
context = {
|
||||
"headers": self.headers,
|
||||
"method": self.POST,
|
||||
"api_path": self.methods["send_message"],
|
||||
"data": data,
|
||||
}
|
||||
|
||||
res = self.request(
|
||||
context["api_path"],
|
||||
data=context["data"],
|
||||
method=context["method"],
|
||||
headers=context["headers"],
|
||||
)
|
||||
return res
|
||||
71
core/services/user.py
Executable file
71
core/services/user.py
Executable file
@@ -0,0 +1,71 @@
|
||||
import typing
|
||||
from datetime import datetime
|
||||
|
||||
from django.contrib.auth import hashers
|
||||
from rest_framework_simplejwt import tokens
|
||||
|
||||
|
||||
from core import exceptions
|
||||
from core.http import models
|
||||
from core.utils import exception
|
||||
|
||||
from core.services import sms
|
||||
from core.services import base_service
|
||||
|
||||
|
||||
class UserService(base_service.BaseService, sms.SmsService):
|
||||
|
||||
def get_token(self, user):
|
||||
refresh = tokens.RefreshToken.for_user(user)
|
||||
|
||||
return {
|
||||
"refresh": str(refresh),
|
||||
"access": str(refresh.access_token),
|
||||
}
|
||||
|
||||
def create_user(self, phone, first_name, last_name, password):
|
||||
models.User.objects.update_or_create(
|
||||
phone=phone,
|
||||
defaults={
|
||||
"phone": phone,
|
||||
"first_name": first_name,
|
||||
"last_name": last_name,
|
||||
"password": hashers.make_password(password),
|
||||
},
|
||||
)
|
||||
|
||||
def send_confirmation(self, phone) -> bool:
|
||||
try:
|
||||
self.send_confirm(phone)
|
||||
return True
|
||||
except exceptions.SmsException as e:
|
||||
exception.ResponseException(
|
||||
e, data={"expired": e.kwargs.get("expired")}
|
||||
) # noqa
|
||||
except Exception as e:
|
||||
exception.ResponseException(e)
|
||||
|
||||
def validate_user(self, user: typing.Union[models.User]) -> dict:
|
||||
"""
|
||||
Create user if user not found
|
||||
"""
|
||||
user.validated_at = datetime.now()
|
||||
user.save()
|
||||
token = self.get_token(user)
|
||||
return token
|
||||
|
||||
def is_validated(self, user: typing.Union[models.User]) -> bool:
|
||||
"""
|
||||
User is validated check
|
||||
"""
|
||||
if user.validated_at is not None:
|
||||
return True
|
||||
return False
|
||||
|
||||
def change_password(self, phone, password):
|
||||
"""
|
||||
Change password
|
||||
"""
|
||||
user = models.User.objects.filter(phone=phone).first()
|
||||
user.set_password(password)
|
||||
user.save()
|
||||
Reference in New Issue
Block a user